Ignore:
Timestamp:
Jan 29, 2017, 12:05:00 PM (3 years ago)
Author:
nmedfort
Message:

Continuation of work to simplify Kernel writing

File:
1 edited

Legend:

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

    r5285 r5286  
    115115    mStreamSetInputBuffers.assign(inputs.begin(), inputs.end());
    116116    mStreamSetOutputBuffers.assign(outputs.begin(), outputs.end());
    117     prepareKernel();            // possibly overridden by the KernelBuilder subtype
     117    prepareKernel(); // possibly overridden by the KernelBuilder subtype
    118118    addKernelDeclarations(m);
    119     generateInitMethod();       // possibly overridden by the KernelBuilder subtype
    120     generateDoSegmentMethod();
     119    callGenerateInitMethod();
     120    callGenerateDoSegmentMethod();
    121121
    122122    // Implement the accumulator get functions
     
    133133}
    134134
    135 // Default init method, possibly overridden if special init actions required.
    136 void KernelBuilder::generateInitMethod() const {
    137     auto savePoint = iBuilder->saveIP();
     135void KernelBuilder::callGenerateDoSegmentMethod() const {
     136    Function * doSegmentFunction = getDoSegmentFunction();
     137    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), mKernelName + "_entry", doSegmentFunction, 0));
     138    auto args = doSegmentFunction->arg_begin();
     139    Value * self = &*(args++);
     140    Value * doFinal = &*(args++);
     141    std::vector<Value *> producerPos;
     142    for (unsigned i = 0; i < mStreamSetInputs.size(); i++) {
     143        producerPos.push_back(&*(args++));
     144    }
     145    assert (args == doSegmentFunction->arg_end());
     146    generateDoSegmentMethod(doSegmentFunction, self, doFinal, producerPos); // must be overridden by the KernelBuilder subtype
     147    iBuilder->CreateRetVoid();
     148}
     149
     150void KernelBuilder::callGenerateInitMethod() const {
    138151    Module * const m = iBuilder->getModule();
    139152    Function * initFunction = m->getFunction(mKernelName + init_suffix);
    140     iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "Init_entry", initFunction, 0));   
     153    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "Init_entry", initFunction, 0));
    141154    Function::arg_iterator args = initFunction->arg_begin();
    142155    Value * self = &*(args++);
     
    147160        iBuilder->CreateStore(param, ptr);
    148161    }
     162    generateInitMethod(initFunction, self);
    149163    iBuilder->CreateRetVoid();
    150     iBuilder->restoreIP(savePoint);
    151 }
     164}
     165
     166// Default init method, possibly overridden if special init actions required.
     167void KernelBuilder::generateInitMethod(Function * /* initFunction */, Value * /* self */) const { }
     168
    152169
    153170ConstantInt * KernelBuilder::getScalarIndex(const std::string & name) const {
     
    321338//  The default doSegment method dispatches to the doBlock routine for
    322339//  each block of the given number of blocksToDo, and then updates counts.
    323 void BlockOrientedKernel::generateDoSegmentMethod() const {
     340void BlockOrientedKernel::generateDoSegmentMethod(Function * doSegmentFunction, Value * self, Value * doFinal, const std::vector<Value *> &producerPos) const {
     341
    324342    auto savePoint = iBuilder->saveIP();
    325 
    326343    callGenerateDoBlockMethod();
    327 
    328344    callGenerateDoFinalBlockMethod();
    329 
    330     Module * m = iBuilder->getModule();
    331     Function * doSegmentFunction = m->getFunction(mKernelName + doSegment_suffix);
    332     iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), mKernelName + "_entry", doSegmentFunction, 0));
     345    iBuilder->restoreIP(savePoint);
     346
    333347    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
    334348    BasicBlock * strideLoopCond = BasicBlock::Create(iBuilder->getContext(), mKernelName + "_strideLoopCond", doSegmentFunction, 0);
     
    342356    ConstantInt * strideBlocks = iBuilder->getSize(iBuilder->getStride() / iBuilder->getBitBlockWidth());
    343357
    344     Function::arg_iterator args = doSegmentFunction->arg_begin();
    345     Value * self = &*(args++);
    346     Value * doFinal = &*(args++);
    347 
    348     std::vector<Value *> producerPos;
    349     producerPos.push_back(&*(args++));
    350358    Value * availablePos = producerPos[0];
    351359    for (unsigned i = 1; i < mStreamSetInputs.size(); i++) {
    352         Value * p = &*(args++);
    353         producerPos.push_back(p);
     360        Value * p = producerPos[i];
    354361        availablePos = iBuilder->CreateSelect(iBuilder->CreateICmpULT(availablePos, p), availablePos, p);
    355362    }
     
    362369    PHINode * stridesRemaining = iBuilder->CreatePHI(size_ty, 2, "stridesRemaining");
    363370    stridesRemaining->addIncoming(stridesToDo, entryBlock);
    364     Value * notDone = iBuilder->CreateICmpUGT(stridesRemaining, ConstantInt::get(size_ty, 0));
     371    Value * notDone = iBuilder->CreateICmpUGT(stridesRemaining, iBuilder->getSize(0));
    365372    iBuilder->CreateCondBr(notDone, strideLoopBody, stridesDone);
    366373
     
    371378
    372379    setBlockNo(self, iBuilder->CreateAdd(blockNo, strideBlocks));
    373     stridesRemaining->addIncoming(iBuilder->CreateSub(stridesRemaining, ConstantInt::get(size_ty, 1)), strideLoopBody);
     380    stridesRemaining->addIncoming(iBuilder->CreateSub(stridesRemaining, iBuilder->getSize(1)), strideLoopBody);
    374381    iBuilder->CreateBr(strideLoopCond);
    375382
     
    412419    iBuilder->SetInsertPoint(segmentDone);
    413420
    414     iBuilder->CreateRetVoid();
    415     iBuilder->restoreIP(savePoint);
    416421}
    417422
    418423void BlockOrientedKernel::callGenerateDoBlockMethod() const {
    419424    Function * f = getDoBlockFunction();
    420     Value * const self = getParameter(f, "self"); assert (self);
     425    auto args = f->arg_begin();
     426    Value * const self = &(*args);
    421427    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", f));
    422428    generateDoBlockMethod(f, self, getBlockNo(self)); // must be implemented by the KernelBuilder subtype
    423429    iBuilder->CreateRetVoid();
    424 //    #ifndef NDEBUG
    425 //    llvm::verifyFunction(*f, &errs());
    426 //    #endif
    427430}
    428431
    429432void BlockOrientedKernel::callGenerateDoFinalBlockMethod() const {
    430433    Function * f = getDoFinalBlockFunction();
    431     Value * const self = getParameter(f, "self"); assert (self);
    432     Value * remainingBytes = getParameter(f, "remainingBytes"); assert (remainingBytes);
     434    auto args = f->arg_begin();
     435    Value * const self = &(*args++);
     436    Value * const remainingBytes = &(*args);
    433437    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", f));
    434438    generateFinalBlockMethod(f, self, remainingBytes, getBlockNo(self)); // possibly overridden by the KernelBuilder subtype
    435439    iBuilder->CreateRetVoid();
    436 //    #ifndef NDEBUG
    437 //    llvm::verifyFunction(*f, &errs());
    438 //    #endif
    439440}
    440441
Note: See TracChangeset for help on using the changeset viewer.