Ignore:
Timestamp:
May 10, 2017, 4:26:11 PM (2 years ago)
Author:
nmedfort
Message:

Large refactoring step. Removed IR generation code from Kernel (formally KernelBuilder?) and moved it into the new KernelBuilder? class.

File:
1 edited

Legend:

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

    r5439 r5440  
    2525
    2626class Kernel : public KernelInterface {
     27    friend class KernelBuilder;
    2728protected:
    2829    using KernelMap = boost::container::flat_map<std::string, unsigned>;
     
    3233    using StreamSetBuffers = std::vector<parabix::StreamSetBuffer *>;
    3334    using Kernels = std::vector<Kernel *>;
    34 
    35     friend class KernelBuilder;
    36     friend void ::generateSegmentParallelPipeline(const std::unique_ptr<kernel::KernelBuilder> &, const Kernels &);
    37     friend void ::generatePipelineLoop(const std::unique_ptr<kernel::KernelBuilder> &, const Kernels &);
    38     friend void ::generateParallelPipeline(const std::unique_ptr<kernel::KernelBuilder> &, const Kernels &);
    3935
    4036    static const std::string DO_BLOCK_SUFFIX;
     
    7975    bool isCachable() const override { return false; }
    8076
    81     std::string makeSignature() override;
     77    std::string makeSignature(const std::unique_ptr<KernelBuilder> & idb) override;
    8278
    8379    // Can the module ID itself serve as the unique signature?
     
    8783    //
    8884
    89     void createKernelStub(const StreamSetBuffers & inputs, const StreamSetBuffers & outputs);
    90 
    91     void createKernelStub(const StreamSetBuffers & inputs, const StreamSetBuffers & outputs, llvm::Module * const kernelModule);
     85    void createKernelStub(const std::unique_ptr<KernelBuilder> & idb, const StreamSetBuffers & inputs, const StreamSetBuffers & outputs);
     86
     87    void createKernelStub(const std::unique_ptr<KernelBuilder> & idb, const StreamSetBuffers & inputs, const StreamSetBuffers & outputs, llvm::Module * const kernelModule);
    9288
    9389    llvm::Module * getModule() const {
     
    9591    }
    9692
    97     // Generate the Kernel to the current module (iBuilder->getModule()).
    98     void generateKernel();
     93    void generateKernel(const std::unique_ptr<kernel::KernelBuilder> & idb);
    9994   
    100     llvm::Value * createInstance() final;
    101 
    102     void initializeInstance() final;
    103 
    104     void finalizeInstance() final;
    105 
    106     llvm::Value * getProducedItemCount(const std::string & name, llvm::Value * doFinal = nullptr) const final;
    107 
    108     void setProducedItemCount(const std::string & name, llvm::Value * value) const final;
    109 
    110     llvm::Value * getProcessedItemCount(const std::string & name) const final;
    111 
    112     void setProcessedItemCount(const std::string & name, llvm::Value * value) const final;
    113 
    114     llvm::Value * getConsumedItemCount(const std::string & name) const final;
    115 
    116     void setConsumedItemCount(const std::string & name, llvm::Value * value) const final;
    117 
    118     llvm::Value * getTerminationSignal() const final;
    119 
    120     void setTerminationSignal() const final;
    121 
    122     // Get the value of a scalar field for the current instance.
    123     llvm::Value * getScalarFieldPtr(llvm::Value * index) const;
    124 
    125     llvm::Value * getScalarFieldPtr(const std::string & fieldName) const;
    126 
    127     llvm::Value * getScalarField(const std::string & fieldName) const;
    128 
    129     // Set the value of a scalar field for the current instance.
    130     void setScalarField(const std::string & fieldName, llvm::Value * value) const;
    131 
    132     // Synchronization actions for executing a kernel for a particular logical segment.
    133     //
    134     // Before the segment is processed, acquireLogicalSegmentNo must be used to load
    135     // the segment number of the kernel state to ensure that the previous segment is
    136     // complete (by checking that the acquired segment number is equal to the desired segment
    137     // number).
    138     // After all segment processing actions for the kernel are complete, and any necessary
    139     // data has been extracted from the kernel for further pipeline processing, the
    140     // segment number must be incremented and stored using releaseLogicalSegmentNo.
    141     llvm::LoadInst * acquireLogicalSegmentNo() const;
    142 
    143     void releaseLogicalSegmentNo(llvm::Value * nextSegNo) const;
     95    llvm::Value * createInstance(const std::unique_ptr<kernel::KernelBuilder> & idb) final;
     96
     97    void initializeInstance(const std::unique_ptr<KernelBuilder> & idb) final;
     98
     99    void finalizeInstance(const std::unique_ptr<kernel::KernelBuilder> & idb) final;
    144100
    145101    bool hasNoTerminateAttribute() const {
     
    162118        return mStreamSetOutputBuffers[i];
    163119    }
    164 
    165     llvm::CallInst * createDoSegmentCall(const std::vector<llvm::Value *> & args) const;
    166 
    167     llvm::Value * getAccumulator(const std::string & accumName) const;
    168120
    169121    virtual ~Kernel() = 0;
     
    194146    }
    195147
     148    unsigned getScalarIndex(const std::string & name) const;
     149
    196150    void prepareStreamSetNameMap();
    197151
    198     void linkExternalMethods() override { }
    199 
    200     virtual void prepareKernel();
    201 
    202     virtual void generateInitializeMethod() { }
     152    void linkExternalMethods(const std::unique_ptr<kernel::KernelBuilder> &) override { }
     153
     154    virtual void prepareKernel(const std::unique_ptr<KernelBuilder> & idb);
     155
     156    virtual void generateInitializeMethod(const std::unique_ptr<kernel::KernelBuilder> & iBuilder) { }
    203157   
    204     virtual void generateDoSegmentMethod() = 0;
    205 
    206     virtual void generateFinalizeMethod() { }
     158    virtual void generateDoSegmentMethod(const std::unique_ptr<KernelBuilder> & iBuilder) = 0;
     159
     160    virtual void generateFinalizeMethod(const std::unique_ptr<KernelBuilder> & iBuilder) { }
    207161
    208162    // Add an additional scalar field to the KernelState struct.
     
    212166    unsigned addUnnamedScalar(llvm::Type * type);
    213167
    214     // Run-time access of Kernel State and parameters of methods for
    215     // use in implementing kernels.
    216    
    217     // Get the index of a named scalar field within the kernel state struct.
    218     unsigned getScalarIndex(const std::string & name) const;
    219 
    220     llvm::Value * getInputStreamBlockPtr(const std::string & name, llvm::Value * streamIndex) const;
    221 
    222     llvm::Value * loadInputStreamBlock(const std::string & name, llvm::Value * streamIndex) const;
    223    
    224     llvm::Value * getInputStreamPackPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex) const;
    225    
    226     llvm::Value * loadInputStreamPack(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex) const;
    227    
    228     llvm::Value * getInputStreamSetCount(const std::string & name) const;
    229 
    230     llvm::Value * getOutputStreamBlockPtr(const std::string & name, llvm::Value * streamIndex) const;
    231    
    232     void storeOutputStreamBlock(const std::string & name, llvm::Value * streamIndex, llvm::Value * toStore) const;
    233    
    234     llvm::Value * getOutputStreamPackPtr(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex) const;
    235    
    236     void storeOutputStreamPack(const std::string & name, llvm::Value * streamIndex, llvm::Value * packIndex, llvm::Value * toStore) const;
    237 
    238     llvm::Value * getOutputStreamSetCount(const std::string & name) const;
    239 
    240     llvm::Value * getAdjustedInputStreamBlockPtr(llvm::Value * blockAdjustment, const std::string & name, llvm::Value * streamIndex) const;
    241 
    242     llvm::Value * getRawInputPointer(const std::string & name, llvm::Value * streamIndex, llvm::Value * absolutePosition) const;
    243 
    244     llvm::Value * getRawOutputPointer(const std::string & name, llvm::Value * streamIndex, llvm::Value * absolutePosition) const;
    245 
    246     llvm::Value * getBaseAddress(const std::string & name) const;
    247 
    248     void setBaseAddress(const std::string & name, llvm::Value * addr) const;
    249 
    250     llvm::Value * getBufferedSize(const std::string & name) const;
    251 
    252     void setBufferedSize(const std::string & name, llvm::Value * size) const;
    253 
    254     void reserveBytes(const std::string & name, llvm::Value * requested) const;
    255 
    256     llvm::Value * getAvailableItemCount(const std::string & name) const;
    257 
    258     llvm::Value * getLinearlyAccessibleItems(const std::string & name, llvm::Value * fromPosition) const;
    259 
    260     llvm::BasicBlock * CreateWaitForConsumers() const;
    261 
    262     llvm::BasicBlock * CreateBasicBlock(std::string && name) const;
    263 
    264     llvm::Value * getStreamSetBufferPtr(const std::string & name) const;
    265 
    266168    llvm::Value * getIsFinal() const {
    267169        return mIsFinal;
    268170    }
    269171
    270     void callGenerateInitializeMethod();
    271 
    272     void callGenerateDoSegmentMethod();
    273 
    274     void callGenerateFinalizeMethod();
     172    void callGenerateInitializeMethod(const std::unique_ptr<KernelBuilder> & idb);
     173
     174    void callGenerateDoSegmentMethod(const std::unique_ptr<KernelBuilder> & idb);
     175
     176    void callGenerateFinalizeMethod(const std::unique_ptr<KernelBuilder> & idb);
    275177
    276178    StreamPort getStreamPort(const std::string & name) const;
     
    304206private:
    305207
    306     llvm::Value * getConsumerLock(const std::string & name) const;
    307 
    308     void setConsumerLock(const std::string & name, llvm::Value * value) const;
    309 
    310     llvm::Value * computeBlockIndex(const std::vector<Binding> & binding, const std::string & name, llvm::Value * itemCount) const;
     208    llvm::Value * getAvailableItemCount(const unsigned i) const {
     209        return mAvailableItemCount[i];
     210    }
    311211
    312212protected:
     
    344244protected:
    345245
    346     void CreateDoBlockMethodCall();
     246    void CreateDoBlockMethodCall(const std::unique_ptr<KernelBuilder> & idb);
    347247
    348248    // Each kernel builder subtype must provide its own logic for generating
    349249    // doBlock calls.
    350     virtual void generateDoBlockMethod() = 0;
     250    virtual void generateDoBlockMethod(const std::unique_ptr<KernelBuilder> & idb) = 0;
    351251
    352252    // Each kernel builder subtypre must also specify the logic for processing the
     
    357257    // not be overridden.
    358258
    359     virtual void generateFinalBlockMethod(llvm::Value * remainingItems);
    360 
    361     void generateDoSegmentMethod() override final;
     259    virtual void generateFinalBlockMethod(const std::unique_ptr<KernelBuilder> & idb, llvm::Value * remainingItems);
     260
     261    void generateDoSegmentMethod(const std::unique_ptr<KernelBuilder> & idb) final;
    362262
    363263    BlockOrientedKernel(std::string && kernelName,
     
    370270private:
    371271
    372     virtual bool useIndirectBr() const;
    373 
    374     void writeDoBlockMethod();
    375 
    376     void writeFinalBlockMethod(llvm::Value * remainingItems);
     272    void writeDoBlockMethod(const std::unique_ptr<KernelBuilder> & idb);
     273
     274    void writeFinalBlockMethod(const std::unique_ptr<KernelBuilder> & idb, llvm::Value * remainingItems);
    377275
    378276private:
     
    384282};
    385283
    386 /*   
     284/*
    387285The Multi-Block Kernel Builder
    388286------------------------------
     
    391289efficient kernels with possibly variable and/or nonaligned output, subject to
    392290exact or MaxRatio processing constraints.   The following restrictions apply.
    393    
     291
    394292#.  The input consists of one or more stream sets, the first of which is
    395     known as the principal input stream set. 
    396    
     293    known as the principal input stream set.
     294
    397295#.  If there is more than one input stream set, the additional stream sets must
    398296    have a processing rate defined with respect to the input stream set of one
     
    400298    declared without a processing rate attribute have the FixedRate(1) attribute
    401299    by default and therefore satisfy this constraint.
    402    
     300
    403301#.  All output stream sets must be declared with processing rate attributes
    404302    of one of the following types:
    405303    *  FixedRate, Add1, Roundup, or MaxRatio with respect to the principal input stream set.
    406304    *  FixedRate with respect to some other output stream set.
    407    
     305
    408306    When using the Multi-Block Kernel Builder to program a new type of kernel,
    409307    the programmer must implement the generateDoMultiBlockMethod for normal
    410308    multi-block processing according to the requirements below, as well as
    411309    providing for special final block processing, if necessary.
    412            
     310
    413311#.  The doMultiBlockMethod will be called with the following parameters:
    414312    * the number of items of the principal input stream to process (itemsToDo),
     
    438336    * for any input pointer p, a GEP instruction with a single int32 index i
    439337      will produce a pointer to the buffer position corresponding to the ith block of the
    440       principal input stream set. 
     338      principal input stream set.
    441339    * for any output stream set declared with a Fixed or Add1 processing rate with respect
    442340      to the principal input stream set, a GEP instruction with a single int32 index i
    443341      will produce a pointer to the buffer position corresponding to the ith block of the
    444342      principal input stream set.
    445                    
     343
    446344#.  Upon completion of multi-block processing, the Multi-Block Kernel Builder will arrange that
    447345    processed and produced item counts are updated for all stream sets that have exact
    448346    processing rate attributes.   Programmers are responsible for updating the producedItemCount
    449347    of any stream set declared with a variable attribute (MaxRatio).
    450                            
     348
    451349#.  An important caveat is that buffer areas may change arbitrarily between
    452350    calls to the doMultiBlockMethod.   In no case should a kernel store a
     
    467365
    468366    // Each multi-block kernel subtype must provide its own logic for handling
    469     // doMultiBlock calls, subject to the requirements laid out above. 
     367    // doMultiBlock calls, subject to the requirements laid out above.
    470368    // The generateMultiBlockLogic must be written to generate this logic, given
    471369    // a created but empty function.  Upon entry to generateMultiBlockLogic,
    472370    // the builder insertion point will be set to the entry block; upone
    473371    // exit the RetVoid instruction will be added to complete the method.
    474     //
    475     virtual void generateMultiBlockLogic () = 0;
     372    //
     373    virtual void generateMultiBlockLogic() = 0;
     374
     375private:
    476376
    477377    // Given a kernel subtype with an appropriate interface, the generateDoSegment
    478378    // method of the multi-block kernel builder makes all the necessary arrangements
    479379    // to translate doSegment calls into a minimal sequence of doMultiBlock calls.
    480     void generateDoSegmentMethod() override final;
     380    void generateDoSegmentMethod(const std::unique_ptr<KernelBuilder> & idb) final;
     381
    481382};
    482    
    483    
     383
     384
    484385}
    485386#endif
Note: See TracChangeset for help on using the changeset viewer.