Ignore:
Timestamp:
Jan 5, 2017, 3:54:40 PM (2 years ago)
Author:
nmedfort
Message:

Code clean up to enforce proper calling order of KernelBuilder? methods

File:
1 edited

Legend:

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

    r5242 r5246  
    1616
    1717KernelBuilder::KernelBuilder(IDISA::IDISA_Builder * builder,
    18                                  std::string kernelName,
    19                                  std::vector<Binding> stream_inputs,
    20                                  std::vector<Binding> stream_outputs,
    21                                  std::vector<Binding> scalar_parameters,
    22                                  std::vector<Binding> scalar_outputs,
    23                                  std::vector<Binding> internal_scalars)
     18                             std::string kernelName,
     19                             std::vector<Binding> stream_inputs,
     20                             std::vector<Binding> stream_outputs,
     21                             std::vector<Binding> scalar_parameters,
     22                             std::vector<Binding> scalar_outputs,
     23                             std::vector<Binding> internal_scalars)
    2424: KernelInterface(builder, kernelName, stream_inputs, stream_outputs, scalar_parameters, scalar_outputs, internal_scalars) {
    2525
    2626}
    2727
    28 unsigned KernelBuilder::addScalar(Type * type, std::string name) {
     28unsigned KernelBuilder::addScalar(Type * type, const std::string & name) {
    2929    if (LLVM_UNLIKELY(mKernelStateType != nullptr)) {
    3030        llvm::report_fatal_error("Cannot add kernel field " + name + " after kernel state finalized");
     
    3737
    3838void KernelBuilder::prepareKernel() {
     39    if (LLVM_UNLIKELY(mKernelStateType != nullptr)) {
     40        llvm::report_fatal_error("Cannot prepare kernel after kernel state finalized");
     41    }
    3942    unsigned blockSize = iBuilder->getBitBlockWidth();
    4043    if (mStreamSetInputs.size() != mStreamSetInputBuffers.size()) {
     
    8386}
    8487
    85 std::unique_ptr<Module> KernelBuilder::createKernelModule(std::vector<StreamSetBuffer *> input_buffers, std::vector<StreamSetBuffer *> output_buffers) {
    86     Module * saveModule = iBuilder->getModule();
     88std::unique_ptr<Module> KernelBuilder::createKernelModule(const std::vector<StreamSetBuffer *> & inputs, const std::vector<StreamSetBuffer *> & outputs) {
     89    auto saveModule = iBuilder->getModule();
    8790    auto savePoint = iBuilder->saveIP();
    88     auto theModule = make_unique<Module>(mKernelName + "_" + iBuilder->getBitBlockTypeName(), iBuilder->getContext());
    89     Module * m = theModule.get();
    90     iBuilder->setModule(m);
    91     generateKernel(input_buffers, output_buffers);
     91    auto module = make_unique<Module>(mKernelName + "_" + iBuilder->getBitBlockTypeName(), iBuilder->getContext());
     92    iBuilder->setModule(module.get());
     93    generateKernel(inputs, outputs);
    9294    iBuilder->setModule(saveModule);
    9395    iBuilder->restoreIP(savePoint);
    94     return theModule;
    95 }
    96 
    97 void KernelBuilder::generateKernel(std::vector<StreamSetBuffer *> input_buffers, std::vector<StreamSetBuffer*> output_buffers) {
     96    return module;
     97}
     98
     99void KernelBuilder::generateKernel(const std::vector<StreamSetBuffer *> & inputs, const std::vector<StreamSetBuffer *> & outputs) {
    98100    auto savePoint = iBuilder->saveIP();
    99101    Module * const m = iBuilder->getModule();
    100     mStreamSetInputBuffers = input_buffers;
    101     mStreamSetOutputBuffers = output_buffers;
    102     prepareKernel();  // possibly overriden by the KernelBuilder subtype
     102    mStreamSetInputBuffers.assign(inputs.begin(), inputs.end());
     103    mStreamSetOutputBuffers.assign(outputs.begin(), outputs.end());
     104    prepareKernel();            // possibly overridden by the KernelBuilder subtype
    103105    addKernelDeclarations(m);
    104     generateDoBlockMethod();     // must be implemented by the KernelBuilder subtype
    105     generateFinalBlockMethod();  // possibly overriden by the KernelBuilder subtype
     106    generateDoBlockMethod();    // must be implemented by the KernelBuilder subtype
     107    generateFinalBlockMethod(); // possibly overridden by the KernelBuilder subtype
    106108    generateDoSegmentMethod();
    107109
     
    116118        iBuilder->CreateRet(retVal);
    117119    }
     120
    118121    // Implement the initializer function
    119122    Function * initFunction = m->getFunction(mKernelName + init_suffix);
    120     iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "Init_entry", initFunction, 0));
    121    
     123    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "Init_entry", initFunction, 0));   
    122124    Function::arg_iterator args = initFunction->arg_begin();
    123125    Value * self = &*(args++);
    124     initializeKernelState(self);
     126    initializeKernelState(self);    // possibly overridden by the KernelBuilder subtype
    125127    for (auto binding : mScalarInputs) {
    126         Value * parm = &*(args++);
     128        Value * param = &*(args++);
    127129        Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(binding.name)});
    128         iBuilder->CreateStore(parm, ptr);
     130        iBuilder->CreateStore(param, ptr);
    129131    }
    130132    iBuilder->CreateRetVoid();
     
    132134}
    133135
    134 void KernelBuilder::initializeKernelState(Value * self) {
    135     iBuilder->CreateStore(Constant::getNullValue(mKernelStateType), self);
     136void KernelBuilder::initializeKernelState(Value * self) const {
     137    iBuilder->CreateStore(ConstantAggregateZero::get(mKernelStateType), self);
    136138}
    137139
    138140//  The default finalBlock method simply dispatches to the doBlock routine.
    139 void KernelBuilder::generateFinalBlockMethod() {
     141void KernelBuilder::generateFinalBlockMethod() const {
    140142    auto savePoint = iBuilder->saveIP();
    141143    Module * m = iBuilder->getModule();
     
    158160// Note: this may be overridden to incorporate doBlock logic directly into
    159161// the doSegment function.
    160 void KernelBuilder::generateDoBlockLogic(Value * self, Value * blockNo) {
     162void KernelBuilder::generateDoBlockLogic(Value * self, Value * /* blockNo */) const {
    161163    Function * doBlockFunction = iBuilder->getModule()->getFunction(mKernelName + doBlock_suffix);
    162     iBuilder->CreateCall(doBlockFunction, {self});
     164    iBuilder->CreateCall(doBlockFunction, self);
    163165}
    164166
    165167//  The default doSegment method dispatches to the doBlock routine for
    166168//  each block of the given number of blocksToDo, and then updates counts.
    167 void KernelBuilder::generateDoSegmentMethod() {
     169void KernelBuilder::generateDoSegmentMethod() const {
    168170    auto savePoint = iBuilder->saveIP();
    169171    Module * m = iBuilder->getModule();
     
    190192    std::vector<Value *> endSignalPtrs;
    191193    for (unsigned i = 0; i < mStreamSetInputs.size(); i++) {
    192         Value * ssStructPtr = getStreamSetStructPtr(self, mStreamSetInputs[i].name);
    193         inbufProducerPtrs.push_back(mStreamSetInputBuffers[i]->getProducerPosPtr(ssStructPtr));
    194         endSignalPtrs.push_back(mStreamSetInputBuffers[i]->getEndOfInputPtr(ssStructPtr));
     194        Value * param = getStreamSetStructPtr(self, mStreamSetInputs[i].name);
     195        inbufProducerPtrs.push_back(mStreamSetInputBuffers[i]->getProducerPosPtr(param));
     196        endSignalPtrs.push_back(mStreamSetInputBuffers[i]->getEndOfInputPtr(param));
    195197    }
    196198   
     
    292294    const auto f = mKernelMap.find(name);
    293295    if (LLVM_UNLIKELY(f == mKernelMap.end())) {
    294         throw std::runtime_error("Kernel does not contain internal state: " + name);
     296        llvm::report_fatal_error("Kernel does not contain scalar: " + name);
    295297    }
    296298    return iBuilder->getInt32(f->second);
     
    301303}
    302304
    303 Value * KernelBuilder::getScalarFieldPtr(Value * self, const std::string & fieldName) {
     305Value * KernelBuilder::getScalarFieldPtr(Value * self, const std::string & fieldName) const {
    304306    return iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(fieldName)});
    305307}
    306308
    307 Value * KernelBuilder::getScalarField(Value * self, std::string fieldName) {
     309Value * KernelBuilder::getScalarField(Value * self, const std::string & fieldName) const {
    308310    return iBuilder->CreateLoad(getScalarFieldPtr(self, fieldName));
    309311}
    310312
    311 void KernelBuilder::setScalarField(Value * self, std::string fieldName, Value * newFieldVal) {
     313void KernelBuilder::setScalarField(Value * self, const std::string & fieldName, Value * newFieldVal) const {
    312314    iBuilder->CreateStore(newFieldVal, getScalarFieldPtr(self, fieldName));
    313315}
    314316
    315 Value * KernelBuilder::acquireLogicalSegmentNo(Value * self) {
     317LoadInst * KernelBuilder::acquireLogicalSegmentNo(Value * self) const {
    316318    Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(logicalSegmentNoScalar)});
    317     LoadInst * segNo = iBuilder->CreateAtomicLoadAcquire(ptr);
    318     return segNo;
    319 }
    320 
    321 Value * KernelBuilder::getProcessedItemCount(Value * self) {
     319    return iBuilder->CreateAtomicLoadAcquire(ptr);
     320}
     321
     322Value * KernelBuilder::getProcessedItemCount(Value * self) const {
    322323    return getScalarField(self, processedItemCount);
    323324}
    324325
    325 Value * KernelBuilder::getProducedItemCount(Value * self) {
     326Value * KernelBuilder::getProducedItemCount(Value * self) const {
    326327    return getScalarField(self, producedItemCount);
    327328}
    328329
    329 Value * KernelBuilder::getTerminationSignal(Value * self) {
     330Value * KernelBuilder::getTerminationSignal(Value * self) const {
    330331    return getScalarField(self, terminationSignal);
    331332}
    332333
    333 void KernelBuilder::releaseLogicalSegmentNo(Value * self, Value * newCount) {
     334void KernelBuilder::releaseLogicalSegmentNo(Value * self, Value * newCount) const {
    334335    Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(logicalSegmentNoScalar)});
    335336    iBuilder->CreateAtomicStoreRelease(newCount, ptr);
    336337}
    337338
    338 void KernelBuilder::setProcessedItemCount(Value * self, Value * newCount) {
     339void KernelBuilder::setProcessedItemCount(Value * self, Value * newCount) const {
    339340    Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(processedItemCount)});
    340341    iBuilder->CreateStore(newCount, ptr);
    341342}
    342343
    343 void KernelBuilder::setProducedItemCount(Value * self, Value * newCount) {
     344void KernelBuilder::setProducedItemCount(Value * self, Value * newCount) const {
    344345    Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(producedItemCount)});
    345346    iBuilder->CreateStore(newCount, ptr);
    346347}
    347348
    348 void KernelBuilder::setTerminationSignal(Value * self) {
     349void KernelBuilder::setTerminationSignal(Value * self) const {
    349350    Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(terminationSignal)});
    350351    iBuilder->CreateStore(ConstantInt::get(iBuilder->getInt1Ty(), 1), ptr);
    351352}
    352                                      
    353 
    354 
    355 Value * KernelBuilder::getBlockNo(Value * self) {
     353
     354Value * KernelBuilder::getBlockNo(Value * self) const {
    356355    Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(blockNoScalar)});
    357     LoadInst * blockNo = iBuilder->CreateLoad(ptr);
    358     return blockNo;
    359 }
    360 
    361 void KernelBuilder::setBlockNo(Value * self, Value * newFieldVal) {
     356    return iBuilder->CreateLoad(ptr);
     357}
     358
     359void KernelBuilder::setBlockNo(Value * self, Value * newFieldVal) const {
    362360    Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(blockNoScalar)});
    363361    iBuilder->CreateStore(newFieldVal, ptr);
     
    365363
    366364
    367 Value * KernelBuilder::getParameter(Function * f, std::string paramName) {
     365Value * KernelBuilder::getParameter(Function * f, const std::string & paramName) const {
    368366    for (Function::arg_iterator argIter = f->arg_begin(), end = f->arg_end(); argIter != end; argIter++) {
    369367        Value * arg = &*argIter;
     
    373371}
    374372
    375 unsigned KernelBuilder::getStreamSetIndex(std::string name) {
     373unsigned KernelBuilder::getStreamSetIndex(const std::string & name) const {
    376374    const auto f = mStreamSetNameMap.find(name);
    377375    if (LLVM_UNLIKELY(f == mStreamSetNameMap.end())) {
     
    381379}
    382380
    383 size_t KernelBuilder::getStreamSetBufferSize(Value * self, std::string name) {
     381size_t KernelBuilder::getStreamSetBufferSize(Value * /* self */, const std::string & name) const {
    384382    const unsigned index = getStreamSetIndex(name);
    385383    StreamSetBuffer * buf = nullptr;
     
    392390}
    393391
    394 Value * KernelBuilder::getStreamSetStructPtr(Value * self, std::string name) {
     392Value * KernelBuilder::getStreamSetStructPtr(Value * self, const std::string & name) const {
    395393    return getScalarField(self, name + structPtrSuffix);
    396394}
    397395
    398 Value * KernelBuilder::getStreamSetBlockPtr(Value * self, std::string name, Value * blockNo) {
     396Value * KernelBuilder::getStreamSetBlockPtr(Value * self, const std::string &name, Value * blockNo) const {
    399397    Value * const structPtr = getStreamSetStructPtr(self, name);
    400398    const unsigned index = getStreamSetIndex(name);
     
    408406}
    409407
     408Value * KernelBuilder::getStream(Value * self, const std::string & name, Value * blockNo, Value * index) {
     409    return iBuilder->CreateGEP(getStreamSetBlockPtr(self, name, blockNo), {iBuilder->getInt32(0), index});
     410}
     411
    410412void KernelBuilder::createInstance() {
     413    if (LLVM_UNLIKELY(mKernelStateType == nullptr)) {
     414        llvm::report_fatal_error("Cannot create kernel instance before calling prepareKernel()");
     415    }
    411416    mKernelInstance = iBuilder->CreateCacheAlignedAlloca(mKernelStateType);
    412417    Module * m = iBuilder->getModule();
     
    429434}
    430435
    431 Function * KernelBuilder::generateThreadFunction(std::string name){
     436Function * KernelBuilder::generateThreadFunction(const std::string & name) const {
     437    if (LLVM_UNLIKELY(mKernelStateType == nullptr)) {
     438        llvm::report_fatal_error("Cannot generate thread function before calling prepareKernel()");
     439    }
    432440    Module * m = iBuilder->getModule();
    433441    Type * const voidTy = iBuilder->getVoidTy();
     
    591599
    592600}
     601
     602KernelBuilder::~KernelBuilder() {
     603}
Note: See TracChangeset for help on using the changeset viewer.