Ignore:
Timestamp:
Jul 15, 2016, 10:04:55 PM (3 years ago)
Author:
cameron
Message:

Initial doSegment support; pipeline generation

File:
1 edited

Legend:

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

    r5076 r5086  
    3737void KernelBuilder::prepareKernel() {
    3838    if (!mDoBlockReturnType) mDoBlockReturnType = iBuilder->getVoidTy();
     39    addScalar(iBuilder->getInt64Ty(), blockNoScalar);
     40    for (auto sSet : mStreamSetInputs) {
     41        mScalarInputs.push_back(ScalarBinding{PointerType::get(sSet.ssType.getStreamSetBlockType(iBuilder), 0), sSet.ssName + basePtrSuffix});
     42        mScalarInputs.push_back(ScalarBinding{iBuilder->getInt64Ty(), sSet.ssName + blkMaskSuffix});
     43        //Or possibly add as internal state, with code in init function:  addScalar(iBuilder->getInt64Ty(), sSet.ssName + blkMaskSuffix);
     44    }
     45    for (auto sSet : mStreamSetOutputs) {
     46        mScalarInputs.push_back(ScalarBinding{PointerType::get(sSet.ssType.getStreamSetBlockType(iBuilder), 0), sSet.ssName + basePtrSuffix});
     47        mScalarInputs.push_back(ScalarBinding{iBuilder->getInt64Ty(), sSet.ssName + blkMaskSuffix});
     48        //Or possibly add as internal state, with code in init function:  addScalar(iBuilder->getInt64Ty(), sSet.ssName + blkMaskSuffix);
     49    }
    3950    for (auto binding : mScalarInputs) {
    4051        addScalar(binding.scalarType, binding.scalarName);
     
    6980    generateDoBlockMethod();     // must be implemented by the KernelBuilder subtype
    7081    generateFinalBlockMethod();  // possibly overriden by the KernelBuilder subtype
     82    generateDoSegmentMethod();
    7183
    7284    // Implement the accumulator get functions
     
    121133}
    122134
     135//  The default doSegment method simply dispatches to the doBlock routine.
     136void KernelBuilder::generateDoSegmentMethod() {
     137    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
     138    Module * m = iBuilder->getModule();
     139    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
     140    Function * doSegmentFunction = m->getFunction(mKernelName + doSegment_suffix);
     141    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doSegmentFunction, 0));
     142    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
     143    BasicBlock * blockLoop = BasicBlock::Create(iBuilder->getContext(), "blockLoop", doSegmentFunction, 0);
     144    BasicBlock * blocksDone = BasicBlock::Create(iBuilder->getContext(), "blocksDone", doSegmentFunction, 0);
     145
     146   
     147    Function::arg_iterator args = doSegmentFunction->arg_begin();
     148    Value * self = &*(args++);
     149    Value * blocksToDo = &*(args);
     150   
     151    std::vector<Value *> basePtrs;
     152    std::vector<Value *> blockMasks;
     153    for (auto sSet : mStreamSetInputs) {
     154        basePtrs.push_back(getScalarField(self, sSet.ssName + basePtrSuffix));
     155        blockMasks.push_back(getScalarField(self, sSet.ssName + blkMaskSuffix));
     156    }
     157    for (auto sSet : mStreamSetOutputs) {
     158        basePtrs.push_back(getScalarField(self, sSet.ssName + basePtrSuffix));
     159        blockMasks.push_back(getScalarField(self, sSet.ssName + blkMaskSuffix));
     160    }
     161   
     162    iBuilder->CreateBr(blockLoop);
     163   
     164    iBuilder->SetInsertPoint(blockLoop);
     165    PHINode * blocksRemaining = iBuilder->CreatePHI(iBuilder->getInt64Ty(), 2, "blocksRemaining");
     166    blocksRemaining->addIncoming(blocksToDo, entryBlock);
     167   
     168    Value * blockNo = getScalarField(self, blockNoScalar);
     169    std::vector<Value *> doBlockArgs = {self};
     170
     171    for (unsigned i = 0; i < basePtrs.size(); i++) {
     172        doBlockArgs.push_back(iBuilder->CreateGEP(basePtrs[i], iBuilder->CreateAnd(blockNo, blockMasks[i])));
     173    }
     174    Value * rslt = iBuilder->CreateCall(doBlockFunction, doBlockArgs);
     175    setScalarField(self, blockNoScalar, iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)));
     176    blocksToDo = iBuilder->CreateSub(blocksRemaining, iBuilder->getInt64(1));
     177    blocksRemaining->addIncoming(blocksToDo, blockLoop);
     178    Value * notDone = iBuilder->CreateICmpUGT(blocksToDo, iBuilder->getInt64(0));
     179    iBuilder->CreateCondBr(notDone, blockLoop, blocksDone);
     180   
     181    iBuilder->SetInsertPoint(blocksDone);
     182    if (mDoBlockReturnType->isVoidTy()) {
     183        iBuilder->CreateRetVoid();
     184    }
     185    else {
     186        iBuilder->CreateRet(rslt);
     187    }
     188    iBuilder->restoreIP(savePoint);
     189}
     190
     191
     192
    123193Value * KernelBuilder::getScalarIndex(std::string fieldName) {
    124194    const auto f = mInternalStateNameMap.find(fieldName);
Note: See TracChangeset for help on using the changeset viewer.