Changeset 5287


Ignore:
Timestamp:
Jan 29, 2017, 4:40:32 PM (10 months ago)
Author:
nmedfort
Message:

More changes towards simplifying the KernelBuilder?

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

Legend:

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

    r5285 r5287  
    1414namespace llvm { class Type; }
    1515
     16static const auto INIT_SUFFIX = "_Init";
     17
     18static const auto DO_SEGMENT_SUFFIX = "_DoSegment";
     19
     20static const auto ACCUMULATOR_INFIX = "_get_";
     21
    1622using namespace llvm;
    1723
     
    2834    for (auto binding : mScalarOutputs) {
    2935        FunctionType * accumFnType = FunctionType::get(binding.type, {selfType}, false);
    30         std::string fnName = mKernelName + accumulator_infix + binding.name;
     36        std::string fnName = mKernelName + ACCUMULATOR_INFIX + binding.name;
    3137        Function * accumFn = Function::Create(accumFnType, GlobalValue::ExternalLinkage, fnName, client);
    3238        accumFn->setCallingConv(CallingConv::C);
     
    4248    }
    4349    FunctionType * initFunctionType = FunctionType::get(iBuilder->getVoidTy(), initParameters, false);
    44     std::string initFnName = mKernelName + init_suffix;
     50    std::string initFnName = mKernelName + INIT_SUFFIX;
    4551    Function * initFn = Function::Create(initFunctionType, GlobalValue::ExternalLinkage, initFnName, client);
    4652    initFn->setCallingConv(CallingConv::C);
     
    5460    }
    5561
    56     // Create the doBlock and finalBlock function prototypes
    57    
    58     std::vector<Type *> doBlockParameters = {selfType};
    59     std::vector<Type *> finalBlockParameters = {selfType, iBuilder->getSizeTy()};
    60     FunctionType * doBlockFunctionType = FunctionType::get(iBuilder->getVoidTy(), doBlockParameters, false);
    61     std::string doBlockName = mKernelName + doBlock_suffix;
    62     Function * doBlockFn = Function::Create(doBlockFunctionType, GlobalValue::ExternalLinkage, doBlockName, client);
    63     doBlockFn->setCallingConv(CallingConv::C);
    64     doBlockFn->setDoesNotThrow();
    65     doBlockFn->setDoesNotCapture(1);
    66    
    67     FunctionType * finalBlockType = FunctionType::get(iBuilder->getVoidTy(), finalBlockParameters, false);
    68     std::string finalBlockName = mKernelName + finalBlock_suffix;
    69     Function * finalBlockFn = Function::Create(finalBlockType, GlobalValue::ExternalLinkage, finalBlockName, client);
    70     finalBlockFn->setCallingConv(CallingConv::C);
    71     finalBlockFn->setDoesNotThrow();
    72     finalBlockFn->setDoesNotCapture(1);
    73    
    74     Function::arg_iterator doBlockArgs = doBlockFn->arg_begin();
    75     Function::arg_iterator finalBlockArgs = finalBlockFn->arg_begin();
    76     Value * doBlockArg = &*(doBlockArgs++);
    77     doBlockArg->setName("self");
    78     Value * finalBlockArg = &*(finalBlockArgs++);
    79     finalBlockArg->setName("self");
    80     finalBlockArg = &*(finalBlockArgs++);
    81     finalBlockArg->setName("remainingBytes");
    82 
    8362    // Create the doSegment function prototype.
    8463    std::vector<Type *> doSegmentParameters = {selfType, iBuilder->getInt1Ty()};
     
    8766    }
    8867    FunctionType * doSegmentFunctionType = FunctionType::get(iBuilder->getVoidTy(), doSegmentParameters, false);
    89     std::string doSegmentName = mKernelName + doSegment_suffix;
     68    std::string doSegmentName = mKernelName + DO_SEGMENT_SUFFIX;
    9069    Function * doSegmentFn = Function::Create(doSegmentFunctionType, GlobalValue::ExternalLinkage, doSegmentName, client);
    9170    doSegmentFn->setCallingConv(CallingConv::C);
     
    10180    }
    10281    doSegmentFn->setDoesNotCapture(1); // for self parameter only.
     82
     83    // Add any additional kernel declarations
     84    addAdditionalKernelDeclarations(client, selfType);
     85
    10386    iBuilder->setModule(saveModule);
    10487    iBuilder->restoreIP(savePoint);
     88}
     89
     90void KernelInterface::addAdditionalKernelDeclarations(llvm::Module * module, llvm::PointerType * selfType) const {
     91
    10592}
    10693
     
    10996}
    11097
    111 Value * KernelInterface::createDoSegmentCall(std::vector<Value *> args) const {
    112     Module * m = iBuilder->getModule();
    113     std::string fnName = mKernelName + doSegment_suffix;
    114     Function * method = m->getFunction(fnName);
    115     if (!method) {
    116         throw std::runtime_error("Cannot find " + fnName);
     98llvm::Function * KernelInterface::getAccumulatorFunction(const std::string & accumName) const {
     99    const auto name = mKernelName + ACCUMULATOR_INFIX + accumName;
     100    Function * f = iBuilder->getModule()->getFunction(name);
     101    if (LLVM_UNLIKELY(f == nullptr)) {
     102        llvm::report_fatal_error("Cannot find " + name);
    117103    }
    118     return iBuilder->CreateCall(method, args);
     104    return f;
    119105}
    120106
    121 Value * KernelInterface::createGetAccumulatorCall(Value * self, std::string accumName) const {
    122     Module * m = iBuilder->getModule();
    123     std::string fnName = mKernelName + accumulator_infix + accumName;
    124     Function * accumMethod = m->getFunction(fnName);
    125     if (!accumMethod) {
    126         throw std::runtime_error("Cannot find " + fnName);
     107Function * KernelInterface::getInitFunction() const {
     108    const auto name = mKernelName + INIT_SUFFIX;
     109    Function * f = iBuilder->getModule()->getFunction(name);
     110    if (LLVM_UNLIKELY(f == nullptr)) {
     111        llvm::report_fatal_error("Cannot find " + name);
    127112    }
    128     return iBuilder->CreateCall(accumMethod, {self});
     113    return f;
    129114}
    130115
    131116Function * KernelInterface::getDoSegmentFunction() const {
    132     return iBuilder->getModule()->getFunction(mKernelName + doSegment_suffix);
     117    const auto name = mKernelName + DO_SEGMENT_SUFFIX;
     118    Function * f = iBuilder->getModule()->getFunction(name);
     119    if (LLVM_UNLIKELY(f == nullptr)) {
     120        llvm::report_fatal_error("Cannot find " + name);
     121    }
     122    return f;
    133123}
  • icGREP/icgrep-devel/icgrep/kernels/interface.h

    r5285 r5287  
    1212namespace llvm { class Function; }
    1313namespace llvm { class Module; }
     14namespace llvm { class PointerType; }
    1415namespace llvm { class StructType; }
    1516namespace llvm { class Type; }
     
    2223    Binding(llvm::Type * type, std::string && name) : type(type), name(name) {}
    2324};
    24 
    25 static const std::string init_suffix = "_Init";
    26 static const std::string doBlock_suffix = "_DoBlock";
    27 static const std::string doSegment_suffix = "_DoSegment";
    28 static const std::string finalBlock_suffix = "_FinalBlock";
    29 static const std::string accumulator_infix = "_get_";
    3025
    3126class KernelInterface {
     
    6156    llvm::Value * getInstance() const { return mKernelInstance; }
    6257
    63     llvm::Value * createDoSegmentCall(std::vector<llvm::Value *> args) const;
    64 
    65     llvm::Value * createGetAccumulatorCall(llvm::Value * self, std::string accumName) const;
    66    
    6758    unsigned getLookAhead() const {
    6859        return mLookAheadPositions;
     
    8374    }
    8475
     76    llvm::Function * getInitFunction() const;
     77
    8578    llvm::Function * getDoSegmentFunction() const;
     79
     80    llvm::Function * getAccumulatorFunction(const std::string & accumName) const;
    8681
    8782protected:
     
    107102    }
    108103   
     104    virtual void addAdditionalKernelDeclarations(llvm::Module * module, llvm::PointerType * selfType) const;
     105
    109106protected:
    110107   
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r5286 r5287  
    2121namespace llvm { class Type; }
    2222
    23 const std::string blockNoScalar = "blockNo";
     23static const auto BLOCK_NO_SCALAR = "blockNo";
     24
     25static const auto DO_BLOCK_SUFFIX = "_DoBlock";
     26
     27static const auto FINAL_BLOCK_SUFFIX = "_FinalBlock";
    2428
    2529using namespace llvm;
     
    9397        addScalar(binding.type, binding.name);
    9498    }
    95     addScalar(iBuilder->getSizeTy(), blockNoScalar);
     99    addScalar(iBuilder->getSizeTy(), BLOCK_NO_SCALAR);
    96100    addScalar(iBuilder->getSizeTy(), logicalSegmentNoScalar);
    97101    addScalar(iBuilder->getInt1Ty(), terminationSignal);
     
    119123    callGenerateInitMethod();
    120124    callGenerateDoSegmentMethod();
    121 
    122125    // Implement the accumulator get functions
    123126    for (auto binding : mScalarOutputs) {
    124         auto fnName = mKernelName + accumulator_infix + binding.name;
    125         Function * accumFn = m->getFunction(fnName);
    126         iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "get_" + binding.name, accumFn, 0));
    127         Value * self = &*(accumFn->arg_begin());
     127        Function * f = getAccumulatorFunction(binding.name);
     128        iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "get_" + binding.name, f));
     129        Value * self = &*(f->arg_begin());
    128130        Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(binding.name)});
    129131        Value * retVal = iBuilder->CreateLoad(ptr);
     
    149151
    150152void KernelBuilder::callGenerateInitMethod() const {
    151     Module * const m = iBuilder->getModule();
    152     Function * initFunction = m->getFunction(mKernelName + init_suffix);
     153    Function * initFunction = getInitFunction();
    153154    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "Init_entry", initFunction, 0));
    154155    Function::arg_iterator args = initFunction->arg_begin();
     
    242243
    243244Value * KernelBuilder::getBlockNo(Value * self) const {
    244     Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(blockNoScalar)});
     245    Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(BLOCK_NO_SCALAR)});
    245246    return iBuilder->CreateLoad(ptr);
    246247}
    247248
    248249void KernelBuilder::setBlockNo(Value * self, Value * value) const {
    249     Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(blockNoScalar)});
     250    Value * ptr = iBuilder->CreateGEP(self, {iBuilder->getInt32(0), getScalarIndex(BLOCK_NO_SCALAR)});
    250251    iBuilder->CreateStore(value, ptr);
    251252}
    252 
    253253
    254254Argument * KernelBuilder::getParameter(Function * const f, const std::string & name) const {
     
    260260    llvm::report_fatal_error(f->getName() + " does not have parameter " + name);
    261261}
     262
     263Value * KernelBuilder::createDoSegmentCall(const std::vector<llvm::Value *> & args) const {
     264    return iBuilder->CreateCall(getDoSegmentFunction(), args);
     265}
     266
     267Value * KernelBuilder::createGetAccumulatorCall(Value * self, const std::string & accumName) const {
     268    return iBuilder->CreateCall(getAccumulatorFunction(accumName), {self});
     269}
     270
    262271
    263272unsigned KernelBuilder::getStreamSetIndex(const std::string & name) const {
     
    308317    }
    309318    mKernelInstance = iBuilder->CreateCacheAlignedAlloca(mKernelStateType);
    310     Module * m = iBuilder->getModule();
    311319    std::vector<Value *> init_args = {mKernelInstance};
    312320    for (auto a : mInitialArguments) {
     
    319327        init_args.push_back(b->getStreamSetBasePtr());
    320328    }
    321     std::string initFnName = mKernelName + init_suffix;
    322     Function * initMethod = m->getFunction(initFnName);
    323     if (initMethod == nullptr) {
    324         llvm::report_fatal_error("Cannot find " + initFnName);
    325     }
     329    Function * initMethod = getInitFunction();
    326330    iBuilder->CreateCall(initMethod, init_args);
    327331}
     
    441445
    442446Function * BlockOrientedKernel::getDoBlockFunction() const {
    443     return iBuilder->getModule()->getFunction(mKernelName + doBlock_suffix);
     447    return iBuilder->getModule()->getFunction(mKernelName + DO_BLOCK_SUFFIX);
    444448}
    445449
    446450Function * BlockOrientedKernel::getDoFinalBlockFunction() const {
    447     return iBuilder->getModule()->getFunction(mKernelName + finalBlock_suffix);
     451    return iBuilder->getModule()->getFunction(mKernelName + FINAL_BLOCK_SUFFIX);
     452}
     453
     454void BlockOrientedKernel::addAdditionalKernelDeclarations(Module * m, PointerType * selfType) const {
     455    // Create the doBlock and finalBlock function prototypes
     456    FunctionType * doBlockFunctionType = FunctionType::get(iBuilder->getVoidTy(), {selfType}, false);
     457    Function * doBlockFn = Function::Create(doBlockFunctionType, GlobalValue::ExternalLinkage, mKernelName + DO_BLOCK_SUFFIX, m);
     458    doBlockFn->setCallingConv(CallingConv::C);
     459    doBlockFn->setDoesNotThrow();
     460    doBlockFn->setDoesNotCapture(1);
     461    auto doBlockArgs = doBlockFn->arg_begin();
     462    Value * doBlockArg = &*(doBlockArgs++);
     463    doBlockArg->setName("self");
     464
     465    FunctionType * finalBlockType = FunctionType::get(iBuilder->getVoidTy(), {selfType, iBuilder->getSizeTy()}, false);
     466    Function * finalBlockFn = Function::Create(finalBlockType, GlobalValue::ExternalLinkage, mKernelName + FINAL_BLOCK_SUFFIX, m);
     467    finalBlockFn->setCallingConv(CallingConv::C);
     468    finalBlockFn->setDoesNotThrow();
     469    finalBlockFn->setDoesNotCapture(1);
     470    auto finalBlockArgs = finalBlockFn->arg_begin();
     471    Value * finalBlockArg = &*(finalBlockArgs++);
     472    finalBlockArg->setName("self");
     473    finalBlockArg = &*(finalBlockArgs++);
     474    finalBlockArg->setName("remainingBytes");
     475
    448476}
    449477
     
    476504}
    477505
     506
     507
     508
    478509// CONSTRUCTOR
    479510SegmentOrientedKernel::SegmentOrientedKernel(IDISA::IDISA_Builder * builder,
  • icGREP/icgrep-devel/icgrep/kernels/kernel.h

    r5286 r5287  
    8686    void setTerminationSignal(llvm::Value * self) const;
    8787
     88    llvm::Value * createDoSegmentCall(const std::vector<llvm::Value *> & args) const;
     89
     90    llvm::Value * createGetAccumulatorCall(llvm::Value * self, const std::string & accumName) const;
     91
    8892protected:
    8993
     
    196200};
    197201
     202class SegmentOrientedKernel : public KernelBuilder {
     203protected:
     204
     205    SegmentOrientedKernel(IDISA::IDISA_Builder * builder,
     206                          std::string && kernelName,
     207                          std::vector<Binding> && stream_inputs,
     208                          std::vector<Binding> && stream_outputs,
     209                          std::vector<Binding> && scalar_parameters,
     210                          std::vector<Binding> && scalar_outputs,
     211                          std::vector<Binding> && internal_scalars);
     212
     213    virtual ~SegmentOrientedKernel() { }
     214
     215};
     216
    198217class BlockOrientedKernel : public KernelBuilder {
    199218protected:
     
    202221    // doBlock calls.
    203222    virtual void generateDoBlockMethod(llvm::Function * function, llvm::Value * self, llvm::Value * blockNo) const = 0;
     223
     224    virtual void addAdditionalKernelDeclarations(llvm::Module * module, llvm::PointerType * selfType) const;
    204225
    205226    // Each kernel builder subtypre must also specify the logic for processing the
     
    234255};
    235256
    236 class SegmentOrientedKernel : public KernelBuilder {
    237 protected:
    238 
    239     SegmentOrientedKernel(IDISA::IDISA_Builder * builder,
    240                           std::string && kernelName,
    241                           std::vector<Binding> && stream_inputs,
    242                           std::vector<Binding> && stream_outputs,
    243                           std::vector<Binding> && scalar_parameters,
    244                           std::vector<Binding> && scalar_outputs,
    245                           std::vector<Binding> && internal_scalars);
    246 
    247     virtual ~SegmentOrientedKernel() { }
    248 };
    249 
    250 
    251257
    252258}
Note: See TracChangeset for help on using the changeset viewer.