Ignore:
Timestamp:
Oct 15, 2016, 11:22:19 PM (3 years ago)
Author:
cameron
Message:

Restructuring pipeline control to use termination signals

File:
1 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r5193 r5194  
    164164    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doSegmentFunction, 0));
    165165    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
    166     BasicBlock * blockLoopCond = BasicBlock::Create(iBuilder->getContext(), "blockLoopCond", doSegmentFunction, 0);
    167     BasicBlock * blockLoopBody = BasicBlock::Create(iBuilder->getContext(), "blockLoopBody", doSegmentFunction, 0);
    168     BasicBlock * blocksDone = BasicBlock::Create(iBuilder->getContext(), "blocksDone", doSegmentFunction, 0);
    169     BasicBlock * checkFinalBlock = BasicBlock::Create(iBuilder->getContext(), "checkFinalBlock", doSegmentFunction, 0);
     166    BasicBlock * strideLoopCond = BasicBlock::Create(iBuilder->getContext(), "strideLoopCond", doSegmentFunction, 0);
     167    BasicBlock * strideLoopBody = BasicBlock::Create(iBuilder->getContext(), "strideLoopBody", doSegmentFunction, 0);
     168    BasicBlock * stridesDone = BasicBlock::Create(iBuilder->getContext(), "stridesDone", doSegmentFunction, 0);
     169    BasicBlock * checkFinalStride = BasicBlock::Create(iBuilder->getContext(), "checkFinalStride", doSegmentFunction, 0);
     170    BasicBlock * checkEndSignals = BasicBlock::Create(iBuilder->getContext(), "checkEndSignals", doSegmentFunction, 0);
    170171    BasicBlock * callFinalBlock = BasicBlock::Create(iBuilder->getContext(), "callFinalBlock", doSegmentFunction, 0);
    171172    BasicBlock * segmentDone = BasicBlock::Create(iBuilder->getContext(), "segmentDone", doSegmentFunction, 0);
     173    BasicBlock * finalExit = BasicBlock::Create(iBuilder->getContext(), "finalExit", doSegmentFunction, 0);
    172174    Type * const size_ty = iBuilder->getSizeTy();
    173175    Constant * stride = ConstantInt::get(size_ty, iBuilder->getStride());
     
    193195    Value * availablePos = producerPos[0];
    194196    for (unsigned i = 1; i < inbufProducerPtrs.size(); i++) {
    195        
    196197        LoadInst * p = iBuilder->CreateAtomicLoadAcquire(inbufProducerPtrs[i]);
    197198        producerPos.push_back(p);
     
    204205    iBuilder->CallPrintInt(mKernelName + "_itemsAvail", itemsAvail);
    205206#endif
    206     Value * blocksAvail = iBuilder->CreateUDiv(itemsAvail, stride);
     207    Value * stridesToDo = iBuilder->CreateUDiv(blocksToDo, strideBlocks);
     208    Value * stridesAvail = iBuilder->CreateUDiv(itemsAvail, stride);
    207209    /* Adjust the number of full blocks to do, based on the available data, if necessary. */
    208     Value * lessThanFullSegment = iBuilder->CreateICmpULT(blocksAvail, blocksToDo);
    209     blocksToDo = iBuilder->CreateSelect(lessThanFullSegment, blocksAvail, blocksToDo);
    210     //iBuilder->CallPrintInt(mKernelName + "_blocksAvail", blocksAvail);
    211     iBuilder->CreateBr(blockLoopCond);
    212 
    213     iBuilder->SetInsertPoint(blockLoopCond);
    214     PHINode * blocksRemaining = iBuilder->CreatePHI(size_ty, 2, "blocksRemaining");
    215     blocksRemaining->addIncoming(blocksToDo, entryBlock);
    216     Value * notDone = iBuilder->CreateICmpUGT(blocksRemaining, ConstantInt::get(size_ty, 0));
    217     iBuilder->CreateCondBr(notDone, blockLoopBody, blocksDone);
    218 
    219     iBuilder->SetInsertPoint(blockLoopBody);
     210    Value * lessThanFullSegment = iBuilder->CreateICmpULT(stridesAvail, stridesToDo);
     211    stridesToDo = iBuilder->CreateSelect(lessThanFullSegment, stridesAvail, stridesToDo);
     212    //iBuilder->CallPrintInt(mKernelName + "_stridesAvail", stridesAvail);
     213    iBuilder->CreateBr(strideLoopCond);
     214
     215    iBuilder->SetInsertPoint(strideLoopCond);
     216    PHINode * stridesRemaining = iBuilder->CreatePHI(size_ty, 2, "stridesRemaining");
     217    stridesRemaining->addIncoming(stridesToDo, entryBlock);
     218    Value * notDone = iBuilder->CreateICmpUGT(stridesRemaining, ConstantInt::get(size_ty, 0));
     219    iBuilder->CreateCondBr(notDone, strideLoopBody, stridesDone);
     220
     221    iBuilder->SetInsertPoint(strideLoopBody);
    220222    Value * blockNo = getScalarField(self, blockNoScalar);   
    221223
    222224    generateDoBlockLogic(self, blockNo);
    223225    setBlockNo(self, iBuilder->CreateAdd(blockNo, strideBlocks));
    224     blocksRemaining->addIncoming(iBuilder->CreateSub(blocksRemaining, ConstantInt::get(size_ty, 1)), blockLoopBody);
    225     iBuilder->CreateBr(blockLoopCond);
    226    
    227     iBuilder->SetInsertPoint(blocksDone);
    228     processed = iBuilder->CreateAdd(processed, iBuilder->CreateMul(blocksToDo, stride));
     226    stridesRemaining->addIncoming(iBuilder->CreateSub(stridesRemaining, ConstantInt::get(size_ty, 1)), strideLoopBody);
     227    iBuilder->CreateBr(strideLoopCond);
     228   
     229    iBuilder->SetInsertPoint(stridesDone);
     230    processed = iBuilder->CreateAdd(processed, iBuilder->CreateMul(stridesToDo, stride));
    229231    setProcessedItemCount(self, processed);
    230     iBuilder->CreateCondBr(lessThanFullSegment, checkFinalBlock, segmentDone);
    231    
    232     iBuilder->SetInsertPoint(checkFinalBlock);
     232    iBuilder->CreateCondBr(lessThanFullSegment, checkFinalStride, segmentDone);
     233   
     234    iBuilder->SetInsertPoint(checkFinalStride);
    233235   
    234236    /* We had less than a full segment of data; we may have reached the end of input
    235237       on one of the stream sets.  */
    236238   
     239    Value * alreadyDone = getTerminationSignal(self);
     240    iBuilder->CreateCondBr(alreadyDone, finalExit, checkEndSignals);
     241   
     242    iBuilder->SetInsertPoint(checkEndSignals);
    237243    Value * endOfInput = iBuilder->CreateLoad(endSignalPtrs[0]);
    238244    if (endSignalPtrs.size() > 1) {
     
    249255    iBuilder->SetInsertPoint(callFinalBlock);
    250256   
    251     Value * remainingItems = iBuilder->CreateURem(availablePos, stride);
     257    Value * remainingItems = iBuilder->CreateSub(availablePos, processed);
    252258    createFinalBlockCall(self, remainingItems);
    253259    setProcessedItemCount(self, availablePos);
     
    257263        mStreamSetOutputBuffers[i]->setEndOfInput(ssStructPtr);
    258264    }
    259    
     265    setTerminationSignal(self);
    260266    iBuilder->CreateBr(segmentDone);
    261267   
     
    273279    // Must be the last action, for synchronization.
    274280    setLogicalSegmentNo(self, iBuilder->CreateAdd(segmentNo, ConstantInt::get(size_ty, 1)));
     281    iBuilder->CreateBr(finalExit);
     282   
     283    iBuilder->SetInsertPoint(finalExit);
    275284
    276285    iBuilder->CreateRetVoid();
     
    312321}
    313322
    314 //  By default, kernels do not terminate early. 
    315323Value * KernelBuilder::getTerminationSignal(Value * self) {
    316     return ConstantInt::getNullValue(iBuilder->getInt1Ty());
     324    return getScalarField(self, terminationSignal);
    317325}
    318326
     
    333341}
    334342
    335 void KernelBuilder::setTerminationSignal(Value * self, Value * newFieldVal) {
    336     llvm::report_fatal_error("This kernel type does not support setTerminationSignal.");
    337 }
     343void KernelBuilder::setTerminationSignal(Value * self) {
     344    Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(terminationSignal)});
     345    iBuilder->CreateStore(ConstantInt::get(iBuilder->getInt1Ty(), 1), ptr);
     346}
     347                                     
    338348
    339349
Note: See TracChangeset for help on using the changeset viewer.