Ignore:
Timestamp:
Jul 18, 2016, 11:11:02 AM (3 years ago)
Author:
cameron
Message:

Pipeline generation for kernels with non-void DoBlock? return

Location:
icGREP/icgrep-devel/icgrep/kernels
Files:
3 edited

Legend:

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

    r5098 r5099  
    152152   
    153153    iBuilder->SetInsertPoint(blockLoop);
    154     PHINode * blocksRemaining = iBuilder->CreatePHI(iBuilder->getInt64Ty(), 2, "blocksRemaining");
    155     blocksRemaining->addIncoming(blocksToDo, entryBlock);
    156    
    157     Value * blockNo = getScalarField(self, blockNoScalar);
    158     std::vector<Value *> doBlockArgs = {self};
    159 
    160     Value * rslt = iBuilder->CreateCall(doBlockFunction, doBlockArgs);
    161     setScalarField(self, blockNoScalar, iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)));
    162     blocksToDo = iBuilder->CreateSub(blocksRemaining, iBuilder->getInt64(1));
    163     blocksRemaining->addIncoming(blocksToDo, blockLoop);
    164     Value * notDone = iBuilder->CreateICmpUGT(blocksToDo, iBuilder->getInt64(0));
    165     iBuilder->CreateCondBr(notDone, blockLoop, blocksDone);
    166    
    167     iBuilder->SetInsertPoint(blocksDone);
    168154    if (mDoBlockReturnType->isVoidTy()) {
     155        PHINode * blocksRemaining = iBuilder->CreatePHI(iBuilder->getInt64Ty(), 2, "blocksRemaining");
     156        blocksRemaining->addIncoming(blocksToDo, entryBlock);
     157       
     158        Value * blockNo = getScalarField(self, blockNoScalar);
     159       
     160        iBuilder->CreateCall(doBlockFunction, {self});
     161        setScalarField(self, blockNoScalar, iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)));
     162        blocksToDo = iBuilder->CreateSub(blocksRemaining, iBuilder->getInt64(1));
     163        blocksRemaining->addIncoming(blocksToDo, blockLoop);
     164        Value * notDone = iBuilder->CreateICmpUGT(blocksToDo, iBuilder->getInt64(0));
     165        iBuilder->CreateCondBr(notDone, blockLoop, blocksDone);
     166       
     167        iBuilder->SetInsertPoint(blocksDone);
    169168        iBuilder->CreateRetVoid();
    170169    }
    171170    else {
     171        PHINode * blocksRemaining = iBuilder->CreatePHI(iBuilder->getInt64Ty(), 2, "blocksRemaining");
     172        blocksRemaining->addIncoming(blocksToDo, entryBlock);
     173        PHINode * total = iBuilder->CreatePHI(mDoBlockReturnType, 2, "resultTotal");
     174        total->addIncoming(ConstantInt::getNullValue(mDoBlockReturnType), entryBlock);
     175
     176        Value * blockNo = getScalarField(self, blockNoScalar);
     177        std::vector<Value *> doBlockArgs = {self};
     178       
     179        Value * rslt = iBuilder->CreateCall(doBlockFunction, {self});
     180        setScalarField(self, blockNoScalar, iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)));
     181        blocksToDo = iBuilder->CreateSub(blocksRemaining, iBuilder->getInt64(1));
     182        blocksRemaining->addIncoming(blocksToDo, blockLoop);
     183        Value * notDone = iBuilder->CreateICmpUGT(blocksToDo, iBuilder->getInt64(0));
     184        Value * totalSoFar = iBuilder->CreateAdd(total, rslt);
     185        total->addIncoming(totalSoFar, blockLoop);
     186        iBuilder->CreateCondBr(notDone, blockLoop, blocksDone);
     187       
     188        iBuilder->SetInsertPoint(blocksDone);
    172189        iBuilder->CreateRet(rslt);
    173190    }
    174191    iBuilder->restoreIP(savePoint);
     192    doSegmentFunction->dump();
    175193}
    176194
  • icGREP/icgrep-devel/icgrep/kernels/kernel.h

    r5097 r5099  
    6868    virtual void generateFinalBlockMethod();
    6969   
    70     void generateDoSegmentMethod();
     70    virtual void generateDoSegmentMethod();
    7171   
    7272    // Add an additional scalar field to the KernelState struct.
  • icGREP/icgrep-devel/icgrep/kernels/pipeline.cpp

    r5096 r5099  
    4242    Value * initialBlockNo = nullptr;
    4343    BasicBlock * initialBlock = nullptr;
     44    Value * rslt = nullptr;
    4445   
    4546    if (segmentSize > 1) {
     
    5758        iBuilder->SetInsertPoint(segmentBodyBlock);
    5859        Value * segBlocks = ConstantInt::get(int64ty, segmentSize);
    59         for (unsigned i = 0; i < kernels.size(); i++) {
    60             kernels[i]->createDoSegmentCall(instances[i], segBlocks);
     60        Value * rslt = kernels[0]->createDoSegmentCall(instances[0], segBlocks);
     61        for (unsigned i = 1; i < kernels.size(); i++) {
     62            rslt = kernels[i]->createDoSegmentCall(instances[i], rslt->getType()->isVoidTy() ? segBlocks : rslt);
    6163        }
    6264        remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), segmentBodyBlock);
     
    8688    // Full Block Pipeline loop
    8789    iBuilder->SetInsertPoint(fullBodyBlock);
    88    
    89     for (unsigned i = 0; i < kernels.size(); i++) {
    90         kernels[i]->createDoSegmentCall(instances[i], ConstantInt::get(int64ty, 1));
     90    rslt = kernels[0]->createDoSegmentCall(instances[0], ConstantInt::get(int64ty, 1));
     91    for (unsigned i = 1; i < kernels.size(); i++) {
     92        rslt = kernels[i]->createDoSegmentCall(instances[i], rslt->getType()->isVoidTy() ? ConstantInt::get(int64ty, 1) : rslt);
    9193    }
    9294   
     
    9698   
    9799    iBuilder->SetInsertPoint(finalBlock);
    98    
    99     for (unsigned i = 0; i < kernels.size(); i++) {
    100         kernels[i]->createFinalBlockCall(instances[i], remainingBytes);
     100    rslt = kernels[0]-> createFinalBlockCall(instances[0], remainingBytes);
     101    for (unsigned i = 1; i < kernels.size(); i++) {
     102        kernels[i]->createFinalBlockCall(instances[i], rslt->getType()->isVoidTy() ? remainingBytes : rslt);
    101103    }
    102104}
Note: See TracChangeset for help on using the changeset viewer.