Ignore:
Timestamp:
Mar 15, 2016, 10:20:07 PM (3 years ago)
Author:
nmedfort
Message:

Added the kernel instance class; removed original mmap file access in favour of the boost mmap system. corrected PrintRegister? routine.

Location:
icGREP/icgrep-devel/icgrep/kernels
Files:
1 added
10 edited

Legend:

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

    r4970 r4974  
    88#include <IDISA/idisa_builder.h>
    99#include <llvm/Support/CommandLine.h>
     10#include <kernels/instance.h>
    1011
    1112using namespace llvm;
     
    1718    return (x != 0) && (x & (x - 1)) == 0;
    1819}
     20
     21namespace kernel {
    1922
    2023// sets name & sets internal state to the kernel superclass state
     
    3336}
    3437
     38SlabAllocator<Instance> Instance::mAllocator; // static allocator declaration; should probably be in a "instance.cpp"
     39
    3540/** ------------------------------------------------------------------------------------------------------------- *
    3641 * @brief addInternalState
     
    3843unsigned KernelBuilder::addInternalState(Type * const type) {
    3944    assert (type);
    40     const unsigned index = mStates.size();
    41     mStates.push_back(type);
     45    const unsigned index = mInternalState.size();
     46    mInternalState.push_back(type);
    4247    return index;
    4348}
    4449
    45 unsigned KernelBuilder::addInternalState(llvm::Type * const type, std::string name) {
    46     if (LLVM_UNLIKELY(mStateNameMap.count(name) != 0)) {
     50unsigned KernelBuilder::addInternalState(llvm::Type * const type, std::string && name) {
     51    if (LLVM_UNLIKELY(mInternalStateNameMap.count(name) != 0)) {
    4752        throw std::runtime_error("Kernel already contains internal state " + name);
    4853    }
    4954    const unsigned index = addInternalState(type);
    50     mStateNameMap.emplace(name, index);
     55    mInternalStateNameMap.emplace(name, index);
    5156    return index;
    5257}
    5358
    54 /** ------------------------------------------------------------------------------------------------------------- *
    55  * @brief addOutputStream
    56  ** ------------------------------------------------------------------------------------------------------------- */
    57 void KernelBuilder::addOutputStream(const unsigned fields) {
    58     assert (fields > 0);
    59     mOutputStreams.push_back((fields == 1) ? mBitBlockType : ArrayType::get(mBitBlockType, fields));
    60 }
    61 
    62 /** ------------------------------------------------------------------------------------------------------------- *
    63  * @brief addOutputScalar
    64  ** ------------------------------------------------------------------------------------------------------------- */
    65 void KernelBuilder::addOutputScalar(Type * const type) {
    66     assert (type);
    67     mOutputScalar.push_back(type);
    68 }
    69 
    70 /** ------------------------------------------------------------------------------------------------------------- *
    71  * @brief addInputStream
    72  ** ------------------------------------------------------------------------------------------------------------- */
    73 void KernelBuilder::addInputStream(const unsigned fields, std::string name) {
    74     assert (fields > 0 && !name.empty());
    75     mInputStreamNames.push_back(name);
    76     if (fields == 1){
    77         mInputStreams.push_back(mBitBlockType);
    78     } else {
    79         mInputStreams.push_back(ArrayType::get(mBitBlockType, fields));
    80     }
    81 }
    82 
    83 void KernelBuilder::addInputStream(const unsigned fields) {
    84     addInputStream(fields, std::move(mKernelName + "_inputstream_" + std::to_string(mInputStreams.size())));
    85 }
    86 
    87 
    88 /** ------------------------------------------------------------------------------------------------------------- *
    89  * @brief getInputStream
    90  ** ------------------------------------------------------------------------------------------------------------- */
    91 Value * KernelBuilder::getInputStream(const unsigned index, const unsigned streamOffset) {
    92     Value * const indices[] = {getOffset(streamOffset), iBuilder->getInt32(index)};
    93     return iBuilder->CreateGEP(mInputParam, indices);
    94 }
    95 
    96 /** ------------------------------------------------------------------------------------------------------------- *
    97  * @brief getInputScalar
    98  ** ------------------------------------------------------------------------------------------------------------- */
    99 Value * KernelBuilder::getInputScalar(const unsigned) {
    100     throw std::runtime_error("currently not supported!");
    101 }
    102 
    103 /** ------------------------------------------------------------------------------------------------------------- *
    104  * @brief getOutputStream
    105  ** ------------------------------------------------------------------------------------------------------------- */
    106 Value * KernelBuilder::getOutputStream(const unsigned index, const unsigned streamOffset) {
    107     Value * const indices[] = {iBuilder->getInt32(0), iBuilder->getInt32(1), getOffset(streamOffset), iBuilder->getInt32(index)};
    108     return iBuilder->CreateGEP(mKernelParam, indices);
    109 }
    110 
    111 /** ------------------------------------------------------------------------------------------------------------- *
    112  * @brief getOutputScalar
    113  ** ------------------------------------------------------------------------------------------------------------- */
    114 Value * KernelBuilder::getOutputScalar(const unsigned) {
    115     throw std::runtime_error("currently not supported!");
    116 }
    11759
    11860/** ------------------------------------------------------------------------------------------------------------- *
    11961 * @brief getInternalState
    12062 ** ------------------------------------------------------------------------------------------------------------- */
    121 Value * KernelBuilder::getInternalState(const unsigned index, Value * const inputStruct) {
     63Value * KernelBuilder::getInternalState(Value * const instance, const unsigned index) {
    12264    Value* indices[] = {iBuilder->getInt64(0), iBuilder->getInt32(0), iBuilder->getInt32(index)};
    123     return iBuilder->CreateGEP(inputStruct ? inputStruct : mKernelParam, indices);
    124 }
    125 
    126 Value * KernelBuilder::getInternalState(const std::string & name, Value * const inputStruct) {
    127     const auto f = mStateNameMap.find(name);
    128     if (LLVM_UNLIKELY(f == mStateNameMap.end())) {
     65    return iBuilder->CreateGEP(instance ? instance : mKernelParam, indices);
     66}
     67
     68Value * KernelBuilder::getInternalState(Value * const instance, const std::string & name) {
     69    const auto f = mInternalStateNameMap.find(name);
     70    if (LLVM_UNLIKELY(f == mInternalStateNameMap.end())) {
    12971        throw std::runtime_error("Kernel does not contain internal state " + name);
    13072    }
    131     return getInternalState(f->second, inputStruct);
     73    return getInternalState(instance, f->second);
    13274}
    13375
     
    13577 * @brief setInternalState
    13678 ** ------------------------------------------------------------------------------------------------------------- */
    137 void KernelBuilder::setInternalState(const unsigned index, Value * const value) {
    138     Value * ptr = getInternalState(index);
     79void KernelBuilder::setInternalState(Value * const instance, const std::string & name, Value * const value) {
     80    Value * ptr = getInternalState(instance, name);
    13981    assert (ptr->getType()->getPointerElementType() == value->getType());
    14082    if (value->getType() == iBuilder->getBitBlockType()) {
     
    14587}
    14688
     89void KernelBuilder::setInternalState(Value * const instance, const unsigned index, Value * const value) {
     90    Value * ptr = getInternalState(instance, index);
     91    assert (ptr->getType()->getPointerElementType() == value->getType());
     92    if (value->getType() == iBuilder->getBitBlockType()) {
     93        iBuilder->CreateBlockAlignedStore(value, ptr);
     94    } else {
     95        iBuilder->CreateStore(value, ptr);
     96    }
     97}
     98
     99/** ------------------------------------------------------------------------------------------------------------- *
     100 * @brief addInputStream
     101 ** ------------------------------------------------------------------------------------------------------------- */
     102void KernelBuilder::addInputStream(const unsigned fields, std::string && name) {
     103    assert (fields > 0 && !name.empty());
     104    mInputStreamName.push_back(name);
     105    if (fields == 1){
     106        mInputStream.push_back(mBitBlockType);
     107    } else {
     108        mInputStream.push_back(ArrayType::get(mBitBlockType, fields));
     109    }
     110}
     111
     112void KernelBuilder::addInputStream(const unsigned fields) {
     113    addInputStream(fields, std::move(mKernelName + "_inputstream_" + std::to_string(mInputStream.size())));
     114}
     115
     116/** ------------------------------------------------------------------------------------------------------------- *
     117 * @brief getInputStream
     118 ** ------------------------------------------------------------------------------------------------------------- */
     119Value * KernelBuilder::getInputStream(llvm::Value * const instance, const unsigned index, const unsigned streamOffset) {
     120    assert (instance);
     121    Value * const indices[] = {getOffset(instance, streamOffset), iBuilder->getInt32(index)};
     122    return iBuilder->CreateGEP(instance, indices);
     123}
     124
    147125/** ------------------------------------------------------------------------------------------------------------- *
    148126 * @brief addInputScalar
    149127 ** ------------------------------------------------------------------------------------------------------------- */
    150 void KernelBuilder::addInputScalar(Type * const type, std::string name) {
     128void KernelBuilder::addInputScalar(Type * const type, std::string && name) {
    151129    assert (type && !name.empty());
    152     mInputScalarNames.push_back(name);
    153     mInputScalars.push_back(type);
     130    mInputScalarName.push_back(name);
     131    mInputScalar.push_back(type);
    154132}
    155133
    156134void KernelBuilder::addInputScalar(Type * const type) {
    157     addInputScalar(type, std::move(mKernelName + "_inputscalar_" + std::to_string(mInputScalars.size())));
     135    addInputScalar(type, std::move(mKernelName + "_inputscalar_" + std::to_string(mInputScalar.size())));
     136}
     137
     138/** ------------------------------------------------------------------------------------------------------------- *
     139 * @brief getInputScalar
     140 ** ------------------------------------------------------------------------------------------------------------- */
     141Value * KernelBuilder::getInputScalar(Value * const instance, const unsigned) {
     142    throw std::runtime_error("currently not supported!");
     143}
     144
     145/** ------------------------------------------------------------------------------------------------------------- *
     146 * @brief addOutputStream
     147 ** ------------------------------------------------------------------------------------------------------------- */
     148unsigned KernelBuilder::addOutputStream(const unsigned fields) {
     149    assert (fields > 0);
     150    const unsigned index = mOutputStream.size();
     151    mOutputStream.push_back((fields == 1) ? mBitBlockType : ArrayType::get(mBitBlockType, fields));
     152    return index;
     153}
     154
     155/** ------------------------------------------------------------------------------------------------------------- *
     156 * @brief addOutputScalar
     157 ** ------------------------------------------------------------------------------------------------------------- */
     158unsigned KernelBuilder::addOutputScalar(Type * const type) {
     159    assert (type);
     160    const unsigned index = mOutputScalar.size();
     161    mOutputScalar.push_back(type);
     162    return index;
     163}
     164
     165/** ------------------------------------------------------------------------------------------------------------- *
     166 * @brief getOutputStream
     167 ** ------------------------------------------------------------------------------------------------------------- */
     168Value * KernelBuilder::getOutputStream(Value * const instance, const unsigned index, const unsigned streamOffset) {
     169    assert (instance);
     170    Value * const indices[] = {getOffset(instance, streamOffset), iBuilder->getInt32(1), iBuilder->getInt32(0), iBuilder->getInt32(index)};
     171    return iBuilder->CreateGEP(instance, indices);
     172}
     173
     174/** ------------------------------------------------------------------------------------------------------------- *
     175 * @brief getOutputStreams
     176 ** ------------------------------------------------------------------------------------------------------------- */
     177Value * KernelBuilder::getOutputStreamSet(Value * const instance, const unsigned streamOffset) {
     178    assert (instance);
     179    Value * const indices[] = {getOffset(instance, streamOffset), iBuilder->getInt32(1)};
     180    return iBuilder->CreateGEP(instance, indices);
     181}
     182
     183/** ------------------------------------------------------------------------------------------------------------- *
     184 * @brief getOutputScalar
     185 ** ------------------------------------------------------------------------------------------------------------- */
     186Value * KernelBuilder::getOutputScalar(Value * const instance, const unsigned) {
     187    throw std::runtime_error("currently not supported!");
    158188}
    159189
     
    167197    const unsigned capacity = mBlocksPerSegment + mCircularBufferModulo - 1;
    168198
    169     mInputStreamType = PointerType::get(StructType::get(mMod->getContext(), mInputStreams), 0);
    170     mInputScalarType = PointerType::get(StructType::get(mMod->getContext(), mInputScalars), 0);
    171     Type * outputStreamType = ArrayType::get(StructType::get(mMod->getContext(), mOutputStreams), capacity);
     199    mInputStreamType = PointerType::get(StructType::get(mMod->getContext(), mInputStream), 0);
     200    mInputScalarType = PointerType::get(StructType::get(mMod->getContext(), mInputScalar), 0);
     201    Type * outputStreamType = ArrayType::get(StructType::get(mMod->getContext(), mOutputStream), capacity);
    172202    Type * outputAccumType = StructType::get(mMod->getContext(), mOutputScalar);
    173     Type * internalStateType = StructType::create(mMod->getContext(), mStates, mKernelName);
     203    Type * internalStateType = StructType::create(mMod->getContext(), mInternalState, mKernelName);
    174204    mKernelStructType = StructType::create(mMod->getContext(),std::vector<Type *>({internalStateType, outputStreamType, outputAccumType}), "KernelStruct_"+ mKernelName);
    175205
     
    205235    iBuilder->CreateRetVoid();
    206236
     237    Type * const int64Ty = iBuilder->getInt64Ty(); // TODO: should call getIntPtrTy() instead but we don't have the data layout here.
     238
    207239    // Generate the zero initializer
    208     Function * initializer = cast<Function>(mMod->getOrInsertFunction(mKernelName + "_Init", Type::getVoidTy(mMod->getContext()), PointerType::get(mKernelStructType, 0), nullptr));
    209     initializer->setCallingConv(CallingConv::C);
    210     Function::arg_iterator args = initializer->arg_begin();
     240    mConstructor = cast<Function>(mMod->getOrInsertFunction(mKernelName + "_Constructor", Type::getVoidTy(mMod->getContext()), PointerType::get(mKernelStructType, 0), nullptr));
     241    mConstructor->setCallingConv(CallingConv::C);
     242    auto args = mConstructor->arg_begin();
    211243    mKernelParam = args++;
    212244    mKernelParam->setName("this");
    213 
    214     iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", initializer, 0));
    215 
    216     Type * const int64Ty = iBuilder->getInt64Ty(); // TODO: should call getIntPtrTy() instead but we don't have the data layout here.
    217     for (unsigned i = 0; i < mStates.size(); ++i) {
     245    iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", mConstructor, 0));
     246    for (unsigned i = 0; i < mInternalState.size(); ++i) {
    218247        Value * const gep = getInternalState(i);
    219248        Type * const type = gep->getType();
    220249        if (type->isIntegerTy() || type->isArrayTy() || type->isVectorTy()) {
    221250            setInternalState(i, Constant::getNullValue(type));
    222         } else {           
     251        } else {
    223252            Value * gep_next = iBuilder->CreateGEP(gep, iBuilder->getInt32(1));
    224253            Value * get_int = iBuilder->CreatePtrToInt(gep, int64Ty);
     
    228257        }
    229258    }
    230 
    231259    iBuilder->CreateRetVoid();
    232260
    233     // and then the constructor
    234     mConstructor = cast<Function>(mMod->getOrInsertFunction(mKernelName+"_Create_Default", Type::getVoidTy(mMod->getContext()), PointerType::get(mKernelStructType, 0), int64Ty, int64Ty, nullptr));
    235     mConstructor->setCallingConv(CallingConv::C);
    236     args = mConstructor->arg_begin();
    237 
    238     mKernelParam = args++;
    239     mKernelParam->setName("this");
    240 
    241     iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", mConstructor, 0));
    242     iBuilder->CreateCall(initializer, mKernelParam);
    243     iBuilder->CreateRetVoid();
    244 }
    245 
    246 /** ------------------------------------------------------------------------------------------------------------- *
    247  * @brief generateKernelInstance
    248  ** ------------------------------------------------------------------------------------------------------------- */
    249 Value * KernelBuilder::generateKernelInstance() {
    250     mKernelStruct = iBuilder->CreateAlloca(mKernelStructType);
    251     iBuilder->CreateCall3(mConstructor, mKernelStruct,
    252         ConstantInt::get(iBuilder->getIntNTy(64), mBlockSize),
    253         ConstantInt::get(iBuilder->getIntNTy(64), (mBlocksPerSegment + mCircularBufferModulo - 1) * mBlockSize));
    254     return mKernelStruct;
    255 }
    256 
    257 /** ------------------------------------------------------------------------------------------------------------- *
    258  * @brief generateDoBlockCall
    259  ** ------------------------------------------------------------------------------------------------------------- */
    260 void KernelBuilder::generateInitCall() {
    261     assert (mInitFunction && mKernelStruct);
    262     iBuilder->CreateCall(mInitFunction, mKernelStruct);
    263 }
    264 
    265 /** ------------------------------------------------------------------------------------------------------------- *
    266  * @brief generateDoBlockCall
    267  ** ------------------------------------------------------------------------------------------------------------- */
    268 void KernelBuilder::generateDoBlockCall(Value * inputStreams) {
    269     assert (mFunction && mKernelStruct);
    270     iBuilder->CreateCall2(mFunction, mKernelStruct, iBuilder->CreatePointerCast(inputStreams, mInputStreamType));
     261    iBuilder->ClearInsertionPoint();
     262
     263    mSegmentIndex = 0;
     264}
     265
     266/** ------------------------------------------------------------------------------------------------------------- *
     267 * @brief instantiate
     268 *
     269 * Generate a new instance of this kernel and call the default constructor to initialize it
     270 ** ------------------------------------------------------------------------------------------------------------- */
     271Instance * KernelBuilder::instantiate() {
     272    AllocaInst * const memory = iBuilder->CreateAlloca(mKernelStructType);
     273    iBuilder->CreateCall(mConstructor, memory);
     274    return new Instance(this, memory);
     275}
     276
     277/** ------------------------------------------------------------------------------------------------------------- *
     278 * @brief call
     279 ** ------------------------------------------------------------------------------------------------------------- */
     280void KernelBuilder::call(llvm::Value * const instance, Value * inputStreams) {
     281    assert (mFunction && instance && inputStreams);
     282    iBuilder->CreateCall2(mFunction, instance, iBuilder->CreatePointerCast(inputStreams, mInputStreamType));
    271283}
    272284
     
    276288 * Compute the stream index of the given offset value.
    277289 ** ------------------------------------------------------------------------------------------------------------- */
    278 Value * KernelBuilder::getOffset(const unsigned value) {
     290Value * KernelBuilder::getOffset(Value * const instance, const unsigned value) {
    279291    const unsigned adjustedOffset = (mSegmentIndex + value);
    280     Value * offset = iBuilder->getInt32(adjustedOffset);
    281292    if (mBlockIndex) {
    282         Value * index = iBuilder->CreateBlockAlignedLoad(getInternalState(mBlockIndex));
     293        Value * offset = iBuilder->CreateBlockAlignedLoad(getBlockNo(instance));
    283294        if (adjustedOffset) {
    284             index = iBuilder->CreateAdd(index, offset);
     295            offset = iBuilder->CreateAdd(offset, ConstantInt::get(offset->getType(), adjustedOffset));
    285296        }
    286297        const unsigned bufferSize = (mBlocksPerSegment + mCircularBufferModulo - 1); assert (bufferSize > 1);
    287298        if (isPowerOfTwo(bufferSize)) {
    288             index = iBuilder->CreateAnd(index, ConstantInt::get(index->getType(), bufferSize - 1));
     299            offset = iBuilder->CreateAnd(offset, ConstantInt::get(offset->getType(), bufferSize - 1));
    289300        } else {
    290             index = iBuilder->CreateURem(index, ConstantInt::get(index->getType(), bufferSize));
     301            offset = iBuilder->CreateURem(offset, ConstantInt::get(offset->getType(), bufferSize));
    291302        }
    292303        // TODO: generate branch / phi node when it's sufficiently unlikely that we'll wrap around.
    293         offset = index;
    294     }
    295     return offset;
     304        return offset;
     305    } else {
     306        return iBuilder->getInt32(adjustedOffset);
     307    }
    296308}
    297309
     
    304316    mCircularBufferModulo = (lookaheadBlocks + 1);
    305317}
     318
     319} // end of namespace kernel
  • icGREP/icgrep-devel/icgrep/kernels/kernel.h

    r4970 r4974  
    3232}
    3333
     34namespace kernel {
     35
     36class Instance;
     37
    3438class KernelBuilder {
     39    friend class Instance;
     40    friend llvm::Function * generateScanWordRoutine(llvm::Module *, IDISA::IDISA_Builder *, unsigned, KernelBuilder *, bool);
    3541    using NameMap = boost::container::flat_map<std::string, unsigned>;
    3642public:
     
    3945
    4046    unsigned addInternalState(llvm::Type * const type);
    41     unsigned addInternalState(llvm::Type * const type, std::string name);
     47    unsigned addInternalState(llvm::Type * const type, std::string && name);
    4248
    4349    void addInputStream(const unsigned fields);
    44     void addInputStream(const unsigned fields, std::string name);
     50    void addInputStream(const unsigned fields, std::string && name);
    4551
    4652    void addInputScalar(llvm::Type * const type);
    47     void addInputScalar(llvm::Type * const type, std::string name);
    48 
    49 
    50     void addOutputStream(const unsigned fields);
    51     void addOutputScalar(llvm::Type * const type);
     53    void addInputScalar(llvm::Type * const type, std::string && name);
     54
     55    unsigned addOutputStream(const unsigned fields);
     56    unsigned addOutputScalar(llvm::Type * const type);
    5257
    5358    llvm::Function * prepareFunction();
     
    5560    void increment();
    5661
    57     llvm::Value * getInputStream(const unsigned index, const unsigned streamOffset = 0);
    58 
    59     llvm::Value * getInputScalar(const unsigned index);
    60 
    61     llvm::Value * getInternalState(const std::string & name, llvm::Value * const inputStruct = nullptr);
    62 
    63     llvm::Value * getInternalState(const unsigned index, llvm::Value * const inputStruct = nullptr);
    64 
    65     llvm::Value * getOutputStream(const unsigned index, const unsigned streamOffset = 0);
    66 
    67     llvm::Value * getOutputScalar(const unsigned index);
     62    inline llvm::Value * getInputStream(const unsigned index, const unsigned streamOffset = 0) {
     63        return getInputStream(mInputParam, index, streamOffset);
     64    }
     65
     66    inline llvm::Value * getInputScalar(const unsigned index) {
     67        return getInputScalar(mInputParam, index);
     68    }
     69
     70    llvm::Value * getInternalState(const std::string & name) {
     71        return getInternalState(mKernelParam, name);
     72    }
     73
     74    void setInternalState(const std::string & name, llvm::Value * value) {
     75        setInternalState(mKernelParam, name, value);
     76    }
     77
     78    llvm::Value * getInternalState(const unsigned index) {
     79        return getInternalState(mKernelParam, index);
     80    }
     81
     82    void setInternalState(const unsigned index, llvm::Value * value) {
     83        setInternalState(mKernelParam, index, value);
     84    }
     85
     86    llvm::Value * getOutputStream(const unsigned index, const unsigned streamOffset = 0) {
     87        return getOutputStream(mKernelParam, index, streamOffset);
     88    }
     89    llvm::Value * getOutputStreamSet(const unsigned streamOffset = 0) {
     90        return getOutputStreamSet(mKernelParam, streamOffset);
     91    }
     92
     93    llvm::Value * getOutputScalar(const unsigned index) {
     94        return getOutputScalar(mKernelParam, index);
     95    }
     96
     97    llvm::Value * getBlockNo() {
     98        return getBlockNo(mKernelParam);
     99    }
     100
     101    llvm::Type * getInputStreamType() const;
    68102
    69103    void finalize();
    70104
    71     llvm::Value * generateKernelInstance();
    72         void generateInitCall();
    73     void generateDoBlockCall(llvm::Value * inputStreams);
     105    kernel::Instance * instantiate();
    74106
    75107    unsigned getSegmentBlocks() const;
     108
     109    llvm::Type * getKernelStateType() const;
     110
     111    llvm::Value * getKernelState() const;
     112
    76113    llvm::Function * getDoBlockFunction() const;
    77     llvm::Type * getKernelStructType() const;
    78     llvm::Value * getKernelStructParam() const;
    79114
    80115    void setLongestLookaheadAmount(const unsigned bits);
     116
    81117    void setBlocksPerSegment(const unsigned blocks);
    82118
    83     void setInternalState(const unsigned index, llvm::Value * const value);
    84 
    85     llvm::Value * getBlockIndexScalar();
    86 
    87119protected:
    88120
    89     llvm::Value * getOffset(const unsigned value);
     121    llvm::Value * getInputStream(llvm::Value * const instance, const unsigned index, const unsigned streamOffset);
     122
     123    llvm::Value * getInputScalar(llvm::Value * const instance, const unsigned index);
     124
     125    llvm::Value * getInternalState(llvm::Value * const instance, const std::string & name);
     126
     127    void setInternalState(llvm::Value * const instance, const std::string & name, llvm::Value * const value);
     128
     129    llvm::Value * getInternalState(llvm::Value * const instance, const unsigned index);
     130
     131    void setInternalState(llvm::Value * const instance, const unsigned index, llvm::Value * const value);
     132
     133    llvm::Value * getOutputStream(llvm::Value * const instance, const unsigned index, const unsigned streamOffset);
     134
     135    llvm::Value * getOutputStreamSet(llvm::Value * const instance, const unsigned streamOffset);
     136
     137    llvm::Value * getOutputScalar(llvm::Value * const instance, const unsigned index);
     138
     139    llvm::Value * getOffset(llvm::Value * const instance, const unsigned value);
     140
     141    llvm::Value * getBlockNo(llvm::Value * const instance);
     142
     143    void call(llvm::Value * const instance, llvm::Value * inputStreams);
    90144
    91145private:
     
    94148    std::string                                                 mKernelName;
    95149    llvm::Type *                        mBitBlockType;
    96     std::vector<llvm::Type *>                   mStates;
    97     std::vector<llvm::Type *>           mInputStreams;
    98     std::vector<llvm::Type *>           mOutputStreams;
    99     std::vector<llvm::Type *>           mInputScalars;
    100     std::vector<llvm::Type *>           mOutputScalar;
    101     std::vector<std::string>            mInputStreamNames;
    102     std::vector<std::string>            mInputScalarNames;
    103150    llvm::Function*                                     mConstructor;
    104     llvm::Function*                                             mInitFunction;
    105151    llvm::Function*                                             mFunction;
    106152    unsigned                            mBlockSize;
     
    111157    llvm::Type *                        mInputScalarType;
    112158    llvm::Value *                       mInputParam;
    113     llvm::Value *                       mKernelStruct;
    114159    llvm::Value *                       mKernelParam;
    115160    unsigned                            mSegmentIndex;
    116161    unsigned                            mBlockIndex;
    117 
    118 
    119     NameMap                             mStateNameMap;
    120 
     162    std::vector<llvm::Type *>           mInputStream;
     163    std::vector<std::string>            mInputStreamName;
     164    std::vector<llvm::Type *>           mInputScalar;
     165    std::vector<std::string>            mInputScalarName;
     166    std::vector<llvm::Type *>           mOutputStream;
     167    std::vector<llvm::Type *>           mOutputScalar;
     168    std::vector<llvm::Type *>                   mInternalState;
     169    NameMap                             mInternalStateNameMap;
    121170};
    122171
     
    129178}
    130179
    131 inline llvm::Type * KernelBuilder::getKernelStructType() const{
     180inline llvm::Type * KernelBuilder::getKernelStateType() const{
    132181    return mKernelStructType;
    133182}
    134183
    135 inline llvm::Value * KernelBuilder::getKernelStructParam() const {
     184inline llvm::Value * KernelBuilder::getKernelState() const {
    136185    return mKernelParam;
    137186}
     
    141190}
    142191
     192inline llvm::Type * KernelBuilder::getInputStreamType() const {
     193    return mInputStreamType;
     194}
     195
    143196inline void KernelBuilder::increment() {
    144197    ++mSegmentIndex;
    145198}
    146199
    147 inline llvm::Value * KernelBuilder::getBlockIndexScalar() {
    148     return getInternalState(mBlockIndex);
    149 }
     200inline llvm::Value * KernelBuilder::getBlockNo(llvm::Value * const instance) {
     201    return getInternalState(instance, mBlockIndex);
     202}
     203
     204} // end of namespace kernel
    150205
    151206#endif // KERNEL_H
  • icGREP/icgrep-devel/icgrep/kernels/pipeline.cpp

    r4970 r4974  
    1010#include <kernels/scanmatchgen.h>
    1111#include <kernels/s2p_kernel.h>
     12#include <kernels/instance.h>
    1213
    1314#include <pablo/function.h>
    1415#include <pablo/pablo_compiler.h>
    1516
     17
    1618using namespace pablo;
     19using namespace kernel;
    1720
    1821PipelineBuilder::PipelineBuilder(Module * m, IDISA::IDISA_Builder * b)
     
    6366    Function::arg_iterator args = main->arg_begin();
    6467
    65     Value* input_param = args++;
    66     input_param->setName("input");
     68    Value * const inputStream = args++;
     69    inputStream->setName("input");
    6770    Value* buffersize_param = args++;
    6871    buffersize_param->setName("buffersize");   
     
    8487    BasicBlock * pipeline_return_block = BasicBlock::Create(mMod->getContext(), "pipeline_return_block", main, 0);
    8588
    86     Value * s2pKernelStruct = mS2PKernel->generateKernelInstance();
    87     Value * icGrepKernelStruct = mICgrepKernel->generateKernelInstance();
    88     Value * scanMatchKernelStruct = mScanMatchKernel->generateKernelInstance();
     89    Instance * s2pInstance = mS2PKernel->instantiate();
     90    Instance * icGrepInstance = mICgrepKernel->instantiate();
     91    Instance * scanMatchInstance = mScanMatchKernel->instantiate();
    8992
    9093
    91     Value * gep = mScanMatchKernel->getInternalState("FileBuf", scanMatchKernelStruct);
    92     Value * filebuf = iBuilder->CreateBitCast(input_param, S);
     94    Value * gep = scanMatchInstance->getInternalState("FileBuf");
     95    Value * filebuf = iBuilder->CreateBitCast(inputStream, S);
    9396    iBuilder->CreateStore(filebuf, gep);
    9497
    95 
    96     gep = mScanMatchKernel->getInternalState("FileSize", scanMatchKernelStruct);
     98    gep = scanMatchInstance->getInternalState("FileSize");
    9799    iBuilder->CreateStore(buffersize_param, gep);
    98100
    99 
    100     gep = mScanMatchKernel->getInternalState("FileName", scanMatchKernelStruct);
     101    gep = scanMatchInstance->getInternalState("FileName");
    101102    iBuilder->CreateStore(filename_param, gep);
    102103
    103     Value * basis_bits = iBuilder->CreateGEP(s2pKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    104     Value * results = iBuilder->CreateGEP(icGrepKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    105  
     104    Value * basis_bits = s2pInstance->getOutputStreamSet();
     105
     106    Value * results = icGrepInstance->getOutputStreamSet();
     107
    106108    iBuilder->CreateBr(pipeline_test_block);
    107109
    108110    iBuilder->SetInsertPoint(pipeline_test_block);
    109     PHINode * remaining_phi = iBuilder->CreatePHI(T, 2, "remaining");   
    110     PHINode * blkNo_phi = iBuilder->CreatePHI(T, 2, "blkNo");
    111     remaining_phi->addIncoming(buffersize_param, entry_block);
    112     blkNo_phi->addIncoming(iBuilder->getInt64(0), entry_block);
     111    PHINode * blockNo = iBuilder->CreatePHI(T, 2, "blockNo");
     112    blockNo->addIncoming(iBuilder->getInt64(0), entry_block);
     113    PHINode * remainingBytes = iBuilder->CreatePHI(T, 2, "remainingBytes");
     114    remainingBytes->addIncoming(buffersize_param, entry_block);
    113115
    114116    Constant * step = ConstantInt::get(T, mBlockSize * mS2PKernel->getSegmentBlocks());
    115117
    116     Value * final_block_cond = iBuilder->CreateICmpSLT(remaining_phi, step);
     118    Value * final_block_cond = iBuilder->CreateICmpSLT(remainingBytes, step);
    117119    iBuilder->CreateCondBr(final_block_cond, pipeline_final_block, pipeline_do_block);
    118120
    119121    iBuilder->SetInsertPoint(pipeline_do_block);
    120122
    121     gep = iBuilder->CreateGEP(input_param, blkNo_phi);
    122     Value * update_blkNo = iBuilder->CreateAdd(blkNo_phi, iBuilder->getInt64(1));
    123     blkNo_phi->addIncoming(update_blkNo, pipeline_do_block);
     123    s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo));
    124124
    125     mS2PKernel->generateDoBlockCall(gep);
    126     mICgrepKernel->generateDoBlockCall(basis_bits);
    127     mScanMatchKernel->generateDoBlockCall(results);
     125    icGrepInstance->call(basis_bits);
     126    scanMatchInstance->call(results);
    128127
    129     Value * update_remaining = iBuilder->CreateSub(remaining_phi, step);
    130     remaining_phi->addIncoming(update_remaining, pipeline_do_block);
     128    blockNo->addIncoming(iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)), pipeline_do_block);
     129    Value * update_remaining = iBuilder->CreateSub(remainingBytes, step);
     130    remainingBytes->addIncoming(update_remaining, pipeline_do_block);
    131131    iBuilder->CreateBr(pipeline_test_block);
    132132
    133133    iBuilder->SetInsertPoint(pipeline_final_block);
    134134
    135     Value * empty_block_cond = iBuilder->CreateICmpEQ(remaining_phi, ConstantInt::get(T, 0));
     135    Value * empty_block_cond = iBuilder->CreateICmpEQ(remainingBytes, ConstantInt::get(T, 0));
    136136    iBuilder->CreateCondBr(empty_block_cond, pipeline_empty_block, pipeline_partial_block);
    137137
    138138    iBuilder->SetInsertPoint(pipeline_partial_block);
    139139
    140     gep = iBuilder->CreateGEP(input_param, blkNo_phi);
    141     mS2PKernel->generateDoBlockCall(gep);
     140    s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo));
     141
    142142    iBuilder->CreateBr(pipeline_end_block);
    143143
     
    154154    iBuilder->SetInsertPoint(pipeline_Unterminated_block);
    155155
    156     Value * remaining = iBuilder->CreateZExt(remaining_phi, iBuilder->getIntNTy(mBlockSize));
     156    Value * remaining = iBuilder->CreateZExt(remainingBytes, iBuilder->getIntNTy(mBlockSize));
    157157    Value * EOF_pos = iBuilder->CreateShl(ConstantInt::get(iBuilder->getIntNTy(mBlockSize), 1), remaining);
    158158    EOF_pos = iBuilder->CreateBitCast(EOF_pos, mBitBlockType);
    159159
    160     Value * gep_bits4 = iBuilder->CreateGEP(basis_bits, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(4)});
    161     Value * bits4 = iBuilder->CreateAlignedLoad(gep_bits4, mBlockSize/8, false, "bits4");
     160    Value * gep_bits4 = s2pInstance->getOutputStream(4);
     161    Value * bits4 = iBuilder->CreateBlockAlignedLoad(gep_bits4);
    162162    bits4 = iBuilder->CreateOr(bits4, EOF_pos);
    163     iBuilder->CreateAlignedStore(bits4, gep_bits4, mBlockSize/8, false);
     163    iBuilder->CreateBlockAlignedStore(bits4, gep_bits4);
    164164
    165     Value * gep_bits6 = iBuilder->CreateGEP(basis_bits, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(6)});
    166     Value * bits6 = iBuilder->CreateAlignedLoad(gep_bits6, mBlockSize/8, false, "bits6");
     165    Value * gep_bits6 = s2pInstance->getOutputStream(6);
     166    Value * bits6 = iBuilder->CreateBlockAlignedLoad(gep_bits6);
    167167    bits6 = iBuilder->CreateOr(bits6, EOF_pos);
    168     iBuilder->CreateAlignedStore(bits6, gep_bits6, mBlockSize/8, false);
     168    iBuilder->CreateBlockAlignedStore(bits6, gep_bits6);
     169
    169170    iBuilder->CreateBr(pipeline_return_block);
    170171
    171172    iBuilder->SetInsertPoint(pipeline_return_block);
    172173
    173     mICgrepKernel->generateDoBlockCall(basis_bits);
    174     mScanMatchKernel->generateDoBlockCall(results);
     174    icGrepInstance->call(basis_bits);
     175    scanMatchInstance->call(results);
    175176    iBuilder->CreateRetVoid();
    176177
     178    mMod->dump();
    177179}
  • icGREP/icgrep-devel/icgrep/kernels/pipeline.h

    r4970 r4974  
    1 #ifndef PIPELINE_H
    2 #define PIPELINE_H
    31/*
    42 *  Copyright (c) 2016 International Characters.
    53 *  This software is licensed to the public under the Open Software License 3.0.
    64 */
    7 
     5#ifndef PIPELINE_H
     6#define PIPELINE_H
    87
    98#include <IDISA/idisa_builder.h>
    10 #include <llvm/IR/Function.h>
    11 #include <llvm/IR/Module.h>
    129#include "kernel.h"
    1310
    1411namespace llvm {
    15     class Value;
    1612    class Module;
    17     class ExecutionEngine;
    18     class VectorType;
    19     class PointerType;
    20     class Constant;
    21     class FunctionType;
    2213    class Function;
    23     class BasicBlock;
    2414    class Type;
    2515}
    2616
    27 namespace pablo { class PabloFunction; class PabloBlock; }
     17namespace pablo {
     18    class PabloFunction;
     19    class PabloBlock;
     20}
    2821
    2922using namespace llvm;
    3023
    31 class PipelineBuilder{
     24namespace kernel {
     25
     26class PipelineBuilder {
    3227public:
    33         PipelineBuilder(Module * m, IDISA::IDISA_Builder * b);
     28    PipelineBuilder(llvm::Module * m, IDISA::IDISA_Builder * b);
     29
    3430        ~PipelineBuilder();
    3531
     
    3834
    3935private:
    40         Module *                            mMod;
     36    llvm::Module *                      mMod;
    4137    IDISA::IDISA_Builder *              iBuilder;
    4238    KernelBuilder *                     mS2PKernel;
    4339    KernelBuilder *                     mICgrepKernel;   
    4440    KernelBuilder *                     mScanMatchKernel;
    45     Type*                               mBitBlockType;
     41    llvm::Type*                         mBitBlockType;
    4642    int                                 mBlockSize;
    4743};
    4844
     45}
     46
    4947#endif // PIPELINE_H
  • icGREP/icgrep-devel/icgrep/kernels/s2p_kernel.cpp

    r4959 r4974  
    66#include <kernels/kernel.h>
    77#include <IDISA/idisa_builder.h>
     8
     9namespace kernel {
    810
    911const int PACK_LANES = 1;
     
    5658    }
    5759    kBuilder->prepareFunction();
    58     for(unsigned i = 0; i < kBuilder->getSegmentBlocks(); ++i){
    59         Value * output[8];
    60         s2p(iBuilder, kBuilder->getInputStream(0), output);
    61         for (unsigned j = 0; j < 8; ++j) {
    62             iBuilder->CreateBlockAlignedStore(output[j], kBuilder->getOutputStream(j));
    63         }
    64         kBuilder->increment();
     60    Value * output[8];
     61    s2p(iBuilder, kBuilder->getInputStream(0), output);
     62    for (unsigned j = 0; j < 8; ++j) {
     63        iBuilder->CreateBlockAlignedStore(output[j], kBuilder->getOutputStream(j));
    6564    }
    6665    kBuilder->finalize();
    6766}
    6867
    69 
    70 
    71 
    72 
    73 
    74 
    75 
    76 
    77 
    78 
    79 
     68}
  • icGREP/icgrep-devel/icgrep/kernels/s2p_kernel.h

    r4959 r4974  
    66#define S2P_KERNEL_H
    77
    8 class KernelBuilder;
    9 
    108namespace llvm { class Module; }
    119
    1210namespace IDISA { class IDISA_Builder; }
    1311
     12namespace kernel {
     13
     14class KernelBuilder;
    1415
    1516void generateS2PKernel(llvm::Module *, IDISA::IDISA_Builder * iBuilder, KernelBuilder * kBuilder);
    1617
     18}
     19
    1720#endif
  • icGREP/icgrep-devel/icgrep/kernels/scanmatchgen.cpp

    r4970 r4974  
    1212using namespace llvm;
    1313
     14namespace kernel {
     15
    1416Value * generateForwardZeroesMask(IDISA::IDISA_Builder * iBuilder, Value * bits) {
    1517    Value * bits_minus1 = iBuilder->CreateSub(bits, ConstantInt::get(bits->getType(), 1));
     
    4850    Type * S = PointerType::get(iBuilder->getIntNTy(8), 0);
    4951    Type * returnType = StructType::get(ctxt, std::vector<Type *>({T, T}));
    50     FunctionType * functionType = FunctionType::get(returnType, std::vector<Type *>({PointerType::get(kBuilder->getKernelStructType(), 0), T, T, T, T, T}), false);
     52    FunctionType * functionType = FunctionType::get(returnType, std::vector<Type *>({PointerType::get(kBuilder->getKernelStateType(), 0), T, T, T, T, T}), false);
    5153
    5254    SmallVector<AttributeSet, 6> Attrs;
     
    6567
    6668    Function::arg_iterator args = function->arg_begin();
    67     Value * this_input_parm = args++;
    68     this_input_parm->setName("this");
     69    Value * instance = args++;
     70    instance->setName("this");
    6971    Value * matches_input_parm = args++;
    7072    matches_input_parm->setName("matches");
     
    151153    Value * matchRecordEnd = iBuilder->CreateAdd(scanwordPos, generateCountForwardZeroes(iBuilder, matches_phi));
    152154
    153     Value* filebuf_gep = kBuilder->getInternalState("FileBuf", this_input_parm);
    154     Value* filebufptr = iBuilder->CreateLoad(filebuf_gep, "filebuf");
    155 
     155    Value * fileBuf = iBuilder->CreateLoad(kBuilder->getInternalState(instance, "FileBuf"));
    156156    if (isNameExpression) {
    157         iBuilder->CreateCall(matchProcessor, std::vector<Value *>({matchRecordNum_phi, matchRecordStart_phi, matchRecordEnd, filebufptr}));
     157        iBuilder->CreateCall(matchProcessor, std::vector<Value *>({matchRecordNum_phi, matchRecordStart_phi, matchRecordEnd, fileBuf}));
    158158    } else {
    159         Value * filesize_gep = kBuilder->getInternalState("FileSize", this_input_parm);
    160         Value * filesize = iBuilder->CreateLoad(filesize_gep, "filesize");
    161 
    162         Value * filename_gep = kBuilder->getInternalState("FileName", this_input_parm);
    163         Value * filenameptr = iBuilder->CreateLoad(filename_gep, "filename");
    164 
    165         iBuilder->CreateCall(matchProcessor, std::vector<Value *>({matchRecordNum_phi, matchRecordStart_phi, matchRecordEnd, filebufptr, filesize, filenameptr}));
     159        Value * fileSize = iBuilder->CreateLoad(kBuilder->getInternalState(instance, "FileSize"));
     160        Value * fileName = iBuilder->CreateLoad(kBuilder->getInternalState(instance, "FileName"));
     161        iBuilder->CreateCall(matchProcessor, std::vector<Value *>({matchRecordNum_phi, matchRecordStart_phi, matchRecordEnd, fileBuf, fileSize, fileName}));
    166162    }
    167163
     
    225221    Function * function = kBuilder->prepareFunction();
    226222
    227     // Type * kernelStuctType = PointerType::get(kBuilder->getKernelStructType(), 0);
    228 
    229223    Function * scanWordFunction = generateScanWordRoutine(m, iBuilder, scanWordBitWidth, kBuilder, isNameExpression);
    230224
    231225    iBuilder->SetInsertPoint(&function->getEntryBlock());
    232226
    233     Value * kernelStuctParam = kBuilder->getKernelStructParam();
     227    Value * kernelStuctParam = kBuilder->getKernelState();
    234228
    235229    Value * scanwordPos = iBuilder->CreateBlockAlignedLoad(kBuilder->getInternalState("BlockNo"));
     
    238232    Value * recordStart = iBuilder->CreateBlockAlignedLoad(kBuilder->getInternalState(lineStart));
    239233    Value * recordNum = iBuilder->CreateBlockAlignedLoad(kBuilder->getInternalState(lineNum));
    240 
    241     Value * wordResult = nullptr;
    242 
    243     const unsigned segmentBlocks = kBuilder->getSegmentBlocks();
    244     const unsigned scanWordBlocks =  segmentBlocks * fieldCount;
    245     for(unsigned j = 0; j < segmentBlocks; ++j) {
    246         Value * matchWordVector = iBuilder->CreateBitCast(iBuilder->CreateBlockAlignedLoad(kBuilder->getInputStream(0)), scanwordVectorType);
    247         Value * breakWordVector = iBuilder->CreateBitCast(iBuilder->CreateBlockAlignedLoad(kBuilder->getInputStream(1)), scanwordVectorType);
    248         for(unsigned i = 0; i < scanWordBlocks; ++i){
    249             Value * matchWord = iBuilder->CreateExtractElement(matchWordVector, ConstantInt::get(T, i));
    250             Value * recordBreaksWord = iBuilder->CreateExtractElement(breakWordVector, ConstantInt::get(T, i));
    251             wordResult = iBuilder->CreateCall(scanWordFunction, std::vector<Value *>({kernelStuctParam, matchWord, recordBreaksWord, scanwordPos, recordStart, recordNum}));
    252             scanwordPos = iBuilder->CreateAdd(scanwordPos, ConstantInt::get(T, scanWordBitWidth));
    253             recordStart = iBuilder->CreateExtractValue(wordResult, std::vector<unsigned>({0}));
    254             recordNum = iBuilder->CreateExtractValue(wordResult, std::vector<unsigned>({1}));
    255         }
    256         kBuilder->increment();
     234    Value * matchWordVector = iBuilder->CreateBitCast(iBuilder->CreateBlockAlignedLoad(kBuilder->getInputStream(0)), scanwordVectorType);
     235    Value * breakWordVector = iBuilder->CreateBitCast(iBuilder->CreateBlockAlignedLoad(kBuilder->getInputStream(1)), scanwordVectorType);
     236    for(unsigned i = 0; i < fieldCount; ++i){
     237        Value * matchWord = iBuilder->CreateExtractElement(matchWordVector, ConstantInt::get(T, i));
     238        Value * recordBreaksWord = iBuilder->CreateExtractElement(breakWordVector, ConstantInt::get(T, i));
     239        Value * wordResult = wordResult = iBuilder->CreateCall(scanWordFunction, std::vector<Value *>({kernelStuctParam, matchWord, recordBreaksWord, scanwordPos, recordStart, recordNum}));
     240        scanwordPos = iBuilder->CreateAdd(scanwordPos, ConstantInt::get(T, scanWordBitWidth));
     241        recordStart = iBuilder->CreateExtractValue(wordResult, std::vector<unsigned>({0}));
     242        recordNum = iBuilder->CreateExtractValue(wordResult, std::vector<unsigned>({1}));
    257243    }
    258244    kBuilder->setInternalState(lineStart, recordStart);
     
    260246    kBuilder->finalize();
    261247}
     248
     249}
  • icGREP/icgrep-devel/icgrep/kernels/scanmatchgen.h

    r4970 r4974  
    66#define SCANMATCHGEN_H
    77
    8 #include <tuple>
    9 
    10 class KernelBuilder;
    11 
    128namespace llvm { class Module; }
    139
    1410namespace IDISA { class IDISA_Builder; }
    1511
     12namespace kernel {
     13
     14class KernelBuilder;
     15
    1616void generateScanMatch(llvm::Module * m, IDISA::IDISA_Builder * iBuilder, unsigned scanWordBitWidth, KernelBuilder * kBuilder, bool isNameExpression);
    1717
     18}
     19
    1820#endif // SCANMATCHGEN_H
  • icGREP/icgrep-devel/icgrep/kernels/symboltablepipeline.cpp

    r4968 r4974  
    1010#include "utf_encoding.h"
    1111
    12 #include <kernels/scanmatchgen.h>
    1312#include <kernels/s2p_kernel.h>
     13#include <kernels/instance.h>
    1414
    1515#include <pablo/function.h>
     
    3030using namespace pablo;
    3131
     32namespace kernel {
     33
    3234SymbolTableBuilder::SymbolTableBuilder(Module * m, IDISA::IDISA_Builder * b)
    3335: mMod(m)
    3436, iBuilder(b)
    35 , mFileBufIdx(7)
    36 , mFileSizeIdx(8)
    37 , mFileNameIdx(9)
    3837, mLongestLookahead(0)
    3938, mBitBlockType(b->getBitBlockType())
    40 , mBlockSize(b->getBitBlockWidth()){
     39, mBlockSize(b->getBitBlockWidth()) {
    4140
    4241}
     
    9897    for (unsigned endpoint : endpoints) {
    9998        PabloAST * const M = function->getParameter(i + 1);
    100         PabloAST * const L = entry->createLookahead(M, endpoint);
     99        PabloAST * const L = entry->createLookahead(M, endpoint, "lookahead" + std::to_string(endpoint));
    101100        PabloAST * S = entry->createAnd(L, R);
    102101        Assign * Si = entry->createAssign("S_" + std::to_string(i), S);
     
    131130
    132131    PabloCompiler pablo_compiler(mMod, iBuilder);
    133 
    134     raw_os_ostream out(std::cerr);
    135 
    136     out << "LEADING:\n";
    137132    PabloFunction * const leading = generateLeadingFunction(endpoints);
    138     PabloPrinter::print(*leading, out);
    139 
    140     out << "\n\nSORTING:\n";
    141133    PabloFunction * const sorting = generateSortingFunction(leading, endpoints);
    142     PabloPrinter::print(*sorting, out);
    143 
    144     out.flush();
    145134
    146135    mS2PKernel = new KernelBuilder("s2p", mMod, iBuilder);
     
    164153}
    165154
    166 void SymbolTableBuilder::ExecuteKernels(){
    167 
    168     Type * T = iBuilder->getIntNTy(64);
    169     Type * S = PointerType::get(iBuilder->getIntNTy(8), 0);
     155Function * SymbolTableBuilder::ExecuteKernels(){
     156
     157    Type * intType = iBuilder->getInt64Ty();
     158
    170159    Type * inputType = PointerType::get(ArrayType::get(StructType::get(mMod->getContext(), std::vector<Type *>({ArrayType::get(mBitBlockType, 8)})), 1), 0);
    171     Function * const main = cast<Function>(mMod->getOrInsertFunction("Main", Type::getVoidTy(mMod->getContext()), inputType, T, nullptr));
     160    Function * const main = cast<Function>(mMod->getOrInsertFunction("Main", Type::getVoidTy(mMod->getContext()), inputType, intType, nullptr));
    172161    main->setCallingConv(CallingConv::C);
    173162    Function::arg_iterator args = main->arg_begin();
    174163
    175     Value * const input_param = args++;
    176     input_param->setName("input");
     164    Value * const inputStream = args++;
     165    inputStream->setName("input");
    177166
    178167    Value * const bufferSize = args++;
     
    183172    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
    184173
    185     BasicBlock * leadingTestBlock = BasicBlock::Create(mMod->getContext(), "ltb", main, 0);
    186     BasicBlock * leadingBodyBlock = BasicBlock::Create(mMod->getContext(), "lbb", main, 0);
    187     BasicBlock * leadingExitBlock = BasicBlock::Create(mMod->getContext(), "leb", main, 0);
    188 
    189     BasicBlock * regularTestBlock = BasicBlock::Create(mMod->getContext(), "rtb", main, 0);
    190     BasicBlock * regularBodyBlock = BasicBlock::Create(mMod->getContext(), "rbb", main, 0);
    191     BasicBlock * regularExitBlock = BasicBlock::Create(mMod->getContext(), "reb", main, 0);
    192 
    193 //    BasicBlock * pipeline_test_block = BasicBlock::Create(mMod->getContext(), "pipeline_test_block", main, 0);
    194 //    BasicBlock * pipeline_do_block = BasicBlock::Create(mMod->getContext(), "pipeline_do_block", main, 0);
    195 //    BasicBlock * pipeline_final_block = BasicBlock::Create(mMod->getContext(), "pipeline_final_block", main, 0);
    196 //    BasicBlock * pipeline_partial_block = BasicBlock::Create(mMod->getContext(), "pipeline_partial_block", main, 0);
    197 //    BasicBlock * pipeline_empty_block = BasicBlock::Create(mMod->getContext(), "pipeline_empty_block", main, 0);
    198 //    BasicBlock * pipeline_end_block = BasicBlock::Create(mMod->getContext(), "pipeline_end_block", main, 0);
    199 //    BasicBlock * pipeline_Unterminated_block = BasicBlock::Create(mMod->getContext(), "pipeline_Unterminated_block", main, 0);
    200 //    BasicBlock * pipeline_return_block = BasicBlock::Create(mMod->getContext(), "pipeline_return_block", main, 0);
    201 
    202     Value * s2pKernelStruct = mS2PKernel->generateKernelInstance();
    203     Value * leadingKernelStruct = mLeadingKernel->generateKernelInstance();
    204     Value * sortingKernelStruct = mSortingKernel->generateKernelInstance();
    205 
    206     Value * basis_bits = iBuilder->CreateGEP(s2pKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    207     Value * leadingData = iBuilder->CreateGEP(leadingKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    208 
     174    BasicBlock * leadingTestBlock = BasicBlock::Create(mMod->getContext(), "leadingCond", main, 0);
     175    BasicBlock * leadingBodyBlock = BasicBlock::Create(mMod->getContext(), "leadingBody", main, 0);
     176
     177    BasicBlock * regularTestBlock = BasicBlock::Create(mMod->getContext(), "fullCond", main, 0);
     178    BasicBlock * regularBodyBlock = BasicBlock::Create(mMod->getContext(), "fullBody", main, 0);
     179    BasicBlock * regularExitBlock = BasicBlock::Create(mMod->getContext(), "fullExit", main, 0);
     180
     181    BasicBlock * partialBlock = BasicBlock::Create(mMod->getContext(),  "partialBlock", main, 0);
     182
     183    BasicBlock * finalTestBlock = BasicBlock::Create(mMod->getContext(),  "finalCond", main, 0);
     184    BasicBlock * finalBodyBlock = BasicBlock::Create(mMod->getContext(),  "finalBody", main, 0);
     185
     186    BasicBlock * exitBlock = BasicBlock::Create(mMod->getContext(), "exit", main, 0);
     187
     188    Instance * s2pInstance = mS2PKernel->instantiate();
     189    Instance * leadingInstance = mLeadingKernel->instantiate();
     190    Instance * sortingInstance = mSortingKernel->instantiate();
     191
     192    Value * basisBits = s2pInstance->getOutputStreamSet();
     193    Value * leadingData = leadingInstance->getOutputStreamSet();
    209194
    210195    const unsigned leadingBlocks = (mLongestLookahead + iBuilder->getBitBlockWidth() - 1) / iBuilder->getBitBlockWidth();
    211196
     197    Value * const requiredBytes = iBuilder->getInt64(mBlockSize * leadingBlocks);
     198    Value * const blockSize = iBuilder->getInt64(mBlockSize);
     199
    212200    // If the buffer size is smaller than our largest length group, only check up to the buffer size.
    213     Value * safetyCheck = iBuilder->CreateICmpSLT(bufferSize, iBuilder->getInt64(leadingBlocks * iBuilder->getBitBlockWidth()));
    214     iBuilder->CreateCondBr(safetyCheck, regularExitBlock, leadingTestBlock);
    215 
    216     // Now process the leading blocks ...
     201    Value * safetyCheck = iBuilder->CreateICmpUGE(bufferSize, blockSize);
     202    if (blockSize == requiredBytes) {
     203        iBuilder->CreateCondBr(safetyCheck, leadingTestBlock, exitBlock); // fix this to be a special case
     204    } else {
     205        throw std::runtime_error("Not supported yet!");
     206    }
     207
     208    // First compute any necessary leading blocks to allow the sorting kernel access to the "future" data produced by
     209    // the leading kernel ...
    217210    iBuilder->SetInsertPoint(leadingTestBlock);
    218     PHINode * remainingBytes = iBuilder->CreatePHI(T, 2, "remainingBytes");
    219     PHINode * leadingOffset = iBuilder->CreatePHI(T, 2, "blockIndex");
     211    PHINode * blockNo = iBuilder->CreatePHI(intType, 2);
     212    blockNo->addIncoming(iBuilder->getInt64(0), entryBlock);
     213    PHINode * remainingBytes = iBuilder->CreatePHI(intType, 2);
    220214    remainingBytes->addIncoming(bufferSize, entryBlock);
    221     leadingOffset->addIncoming(iBuilder->getInt64(0), entryBlock);
    222     Value * remainingLeadingBlocksCond = iBuilder->CreateICmpULT(leadingOffset, iBuilder->getInt64(leadingBlocks));
    223     iBuilder->CreateCondBr(remainingLeadingBlocksCond, leadingBodyBlock, leadingExitBlock);
     215    Value * leadingBlocksCond = iBuilder->CreateICmpULT(blockNo, iBuilder->getInt64(leadingBlocks));
     216    iBuilder->CreateCondBr(leadingBlocksCond, leadingBodyBlock, regularTestBlock);
    224217    iBuilder->SetInsertPoint(leadingBodyBlock);
    225     Value * gep = iBuilder->CreateGEP(input_param, leadingOffset);
    226     mS2PKernel->generateDoBlockCall(gep);
    227     mLeadingKernel->generateDoBlockCall(basis_bits);
    228     leadingOffset->addIncoming(iBuilder->CreateAdd(leadingOffset, iBuilder->getInt64(1)), leadingBodyBlock);
    229     remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, iBuilder->getInt64(mBlockSize)), leadingBodyBlock);
     218    s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo));
     219    leadingInstance->call(basisBits);
     220    blockNo->addIncoming(iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)), leadingBodyBlock);
     221    remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, blockSize), leadingBodyBlock);
    230222    iBuilder->CreateBr(leadingTestBlock);
    231     iBuilder->SetInsertPoint(leadingExitBlock);
    232 
    233     // Now process the leading blocks ...
    234     iBuilder->CreateBr(regularTestBlock);
     223
     224    // Now all the data for which we can produce and consume a full leading block...
    235225    iBuilder->SetInsertPoint(regularTestBlock);
    236     PHINode * remainingBytes2 = iBuilder->CreatePHI(T, 2, "remainingBytes");
    237     PHINode * leadingOffset2 = iBuilder->CreatePHI(T, 2, "blockIndex");
    238     remainingBytes2->addIncoming(remainingBytes, leadingExitBlock);
    239     leadingOffset2->addIncoming(leadingOffset, leadingExitBlock);
    240     Value * remainingBytesCond = iBuilder->CreateICmpUGE(remainingBytes2, iBuilder->getInt64(mBlockSize));
     226    PHINode * blockNo2 = iBuilder->CreatePHI(intType, 2);
     227    blockNo2->addIncoming(blockNo, leadingTestBlock);
     228    PHINode * remainingBytes2 = iBuilder->CreatePHI(intType, 2);
     229    remainingBytes2->addIncoming(remainingBytes, leadingTestBlock);
     230    Value * remainingBytesCond = iBuilder->CreateICmpUGE(remainingBytes2, requiredBytes);
    241231    iBuilder->CreateCondBr(remainingBytesCond, regularBodyBlock, regularExitBlock);
    242232    iBuilder->SetInsertPoint(regularBodyBlock);
    243     Value * gep2 = iBuilder->CreateGEP(input_param, leadingOffset2);
    244     mS2PKernel->generateDoBlockCall(gep2);
    245     mLeadingKernel->generateDoBlockCall(basis_bits);
    246     leadingOffset2->addIncoming(iBuilder->CreateAdd(leadingOffset2, iBuilder->getInt64(1)), regularBodyBlock);
    247     remainingBytes2->addIncoming(iBuilder->CreateSub(remainingBytes2, iBuilder->getInt64(mBlockSize)), regularBodyBlock);
    248     mSortingKernel->generateDoBlockCall(leadingData);
     233    s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo2));
     234    leadingInstance->call(basisBits);
     235    sortingInstance->call(leadingData);
     236    blockNo2->addIncoming(iBuilder->CreateAdd(blockNo2, iBuilder->getInt64(1)), regularBodyBlock);
     237    remainingBytes2->addIncoming(iBuilder->CreateSub(remainingBytes2, blockSize), regularBodyBlock);
    249238    iBuilder->CreateBr(regularTestBlock);
     239
     240
     241    // Check if we have a partial blocks worth of leading data remaining
    250242    iBuilder->SetInsertPoint(regularExitBlock);
    251 
    252 
    253 
    254 //    Value * gep = iBuilder->CreateGEP(sortingKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(mFileBufIdx)});
    255 //    Value* filebuf = iBuilder->CreateBitCast(input_param, S);
    256 //    iBuilder->CreateStore(filebuf, gep);
    257 
    258 //    gep = iBuilder->CreateGEP(sortingKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(mFileSizeIdx)});
    259 //    iBuilder->CreateStore(buffersize_param, gep);
    260 
    261 //    gep = iBuilder->CreateGEP(sortingKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(mFileNameIdx)});
    262 //    iBuilder->CreateStore(filename_param, gep);
    263 
    264 //    Value * basis_bits = iBuilder->CreateGEP(s2pKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    265 //    Value * results = iBuilder->CreateGEP(leadingKernelStruct, {iBuilder->getInt32(0), iBuilder->getInt32(1)});
    266 
    267 //    iBuilder->CreateBr(pipeline_test_block);
    268 
    269 //    iBuilder->SetInsertPoint(pipeline_test_block);
    270 //    PHINode * remaining_phi = iBuilder->CreatePHI(T, 2, "remaining");
    271 //    PHINode * blkNo_phi = iBuilder->CreatePHI(T, 2, "blkNo");
    272 //    remaining_phi->addIncoming(buffersize_param, entry_block);
    273 //    blkNo_phi->addIncoming(iBuilder->getInt64(0), entry_block);
    274 
    275 //    Value * final_block_cond = iBuilder->CreateICmpSLT(remaining_phi, ConstantInt::get(T, mBlockSize));
    276 //    iBuilder->CreateCondBr(final_block_cond, pipeline_final_block, pipeline_do_block);
    277 
    278 //    iBuilder->SetInsertPoint(pipeline_do_block);
    279 
    280 //    gep = iBuilder->CreateGEP(input_param, {blkNo_phi});
    281 //    Value * update_blkNo = iBuilder->CreateAdd(blkNo_phi, iBuilder->getInt64(1));
    282 //    blkNo_phi->addIncoming(update_blkNo, pipeline_do_block);
    283 
    284 //    mS2PKernel->generateDoBlockCall(gep);
    285 //    mICgrepKernel->generateDoBlockCall(basis_bits);
    286 //    mScanMatchKernel->generateDoBlockCall(results);
    287 
    288 //    Value * update_remaining = iBuilder->CreateSub(remaining_phi, iBuilder->getInt64(mBlockSize));
    289 //    remaining_phi->addIncoming(update_remaining, pipeline_do_block);
    290 //    iBuilder->CreateBr(pipeline_test_block);
    291 
    292 //    iBuilder->SetInsertPoint(pipeline_final_block);
    293 
    294 //    Value * empty_block_cond = iBuilder->CreateICmpEQ(remaining_phi, ConstantInt::get(T, 0));
    295 //    iBuilder->CreateCondBr(empty_block_cond, pipeline_empty_block, pipeline_partial_block);
    296 
    297 //    iBuilder->SetInsertPoint(pipeline_partial_block);
    298 
    299 //    gep = iBuilder->CreateGEP(input_param, {blkNo_phi});
    300 //    mS2PKernel->generateDoBlockCall(gep);
    301 //    iBuilder->CreateBr(pipeline_end_block);
    302 
    303 //    iBuilder->SetInsertPoint(pipeline_empty_block);
    304 
    305 //    iBuilder->CreateMemSet(basis_bits, iBuilder->getInt8(0), mBlockSize, 4);
    306 //    iBuilder->CreateBr(pipeline_end_block);
    307 
    308 //    iBuilder->SetInsertPoint(pipeline_end_block);
    309 
    310 //    Value * return_block_cond = iBuilder->CreateICmpEQ(finalLineUnterminated_param, ConstantInt::get(T, 0));
    311 //    iBuilder->CreateCondBr(return_block_cond, pipeline_return_block, pipeline_Unterminated_block);
    312 
    313 //    iBuilder->SetInsertPoint(pipeline_Unterminated_block);
    314 
    315 //    Value * remaining = iBuilder->CreateZExt(remaining_phi, iBuilder->getIntNTy(mBlockSize));
    316 //    Value * EOF_pos = iBuilder->CreateShl(ConstantInt::get(iBuilder->getIntNTy(mBlockSize), 1), remaining);
    317 //    EOF_pos = iBuilder->CreateBitCast(EOF_pos, mBitBlockType);
    318 
    319 //    Value * gep_bits4 = iBuilder->CreateGEP(basis_bits, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(4)});
    320 //    Value * bits4 = iBuilder->CreateAlignedLoad(gep_bits4, mBlockSize/8, false, "bits4");
    321 //    bits4 = iBuilder->CreateOr(bits4, EOF_pos);
    322 //    iBuilder->CreateAlignedStore(bits4, gep_bits4, mBlockSize/8, false);
    323 
    324 //    Value * gep_bits6 = iBuilder->CreateGEP(basis_bits, {iBuilder->getInt32(0), iBuilder->getInt32(0), iBuilder->getInt32(6)});
    325 //    Value * bits6 = iBuilder->CreateAlignedLoad(gep_bits6, mBlockSize/8, false, "bits6");
    326 //    bits6 = iBuilder->CreateOr(bits6, EOF_pos);
    327 //    iBuilder->CreateAlignedStore(bits6, gep_bits6, mBlockSize/8, false);
    328 //    iBuilder->CreateBr(pipeline_return_block);
    329 
    330 //    iBuilder->SetInsertPoint(pipeline_return_block);
    331 
    332 //    mICgrepKernel->generateDoBlockCall(basis_bits);
    333 //    mScanMatchKernel->generateDoBlockCall(results);
     243    Value * partialBlockCond = iBuilder->CreateICmpUGT(remainingBytes2, ConstantInt::getNullValue(intType));
     244    iBuilder->CreateCondBr(partialBlockCond, partialBlock, finalTestBlock);
     245
     246    // If we do, process it and mask out the data
     247    iBuilder->SetInsertPoint(partialBlock);
     248    s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo2));
     249    Value * partialLeadingData[2];
     250    for (unsigned i = 0; i < 2; ++i) {
     251        partialLeadingData[i] = leadingInstance->getOutputStream(i);
     252    }
     253    leadingInstance->call(basisBits);
     254    Type * fullBitBlockType = iBuilder->getIntNTy(mBlockSize);
     255    Value * remaining = iBuilder->CreateZExt(iBuilder->CreateSub(blockSize, remainingBytes2), fullBitBlockType);
     256    Value * eofMask = iBuilder->CreateLShr(ConstantInt::getAllOnesValue(fullBitBlockType), remaining);
     257    eofMask = iBuilder->CreateBitCast(eofMask, mBitBlockType);
     258    for (unsigned i = 0; i < 2; ++i) {
     259        Value * value = iBuilder->CreateAnd(iBuilder->CreateBlockAlignedLoad(partialLeadingData[i]), eofMask);
     260        iBuilder->CreateBlockAlignedStore(value, partialLeadingData[i]);
     261    }
     262    for (unsigned i = 0; i < 2; ++i) {
     263        iBuilder->CreateBlockAlignedStore(ConstantInt::getNullValue(mBitBlockType), leadingInstance->getOutputStream(i));
     264    }
     265    sortingInstance->call(leadingData);
     266    iBuilder->CreateBr(finalTestBlock);
     267
     268    // Now clear the leading data and test the final blocks
     269    iBuilder->SetInsertPoint(finalTestBlock);
     270    PHINode * remainingFullBlocks = iBuilder->CreatePHI(iBuilder->getInt64Ty(), 3);
     271    remainingFullBlocks->addIncoming(iBuilder->getInt64(leadingBlocks), regularExitBlock);
     272    remainingFullBlocks->addIncoming(iBuilder->getInt64(leadingBlocks), partialBlock);
     273    Value * remainingFullBlocksCond = iBuilder->CreateICmpUGT(remainingFullBlocks, ConstantInt::getNullValue(intType));
     274    iBuilder->CreateCondBr(remainingFullBlocksCond, finalBodyBlock, exitBlock);
     275
     276    iBuilder->SetInsertPoint(finalBodyBlock);
     277    for (unsigned i = 0; i < 2; ++i) {
     278        iBuilder->CreateBlockAlignedStore(ConstantInt::getNullValue(mBitBlockType), leadingInstance->getOutputStream(i));
     279    }
     280    Value * blockNoPtr = leadingInstance->getBlockNo();
     281    Value * blockNoValue = iBuilder->CreateLoad(blockNoPtr);
     282    blockNoValue = iBuilder->CreateAdd(blockNoValue, ConstantInt::get(blockNoValue->getType(), 1));
     283    iBuilder->CreateStore(blockNoValue, blockNoPtr);
     284
     285    sortingInstance->call(leadingData);
     286
     287    remainingFullBlocks->addIncoming(iBuilder->CreateSub(remainingFullBlocks, iBuilder->getInt64(1)), finalBodyBlock);
     288
     289    iBuilder->CreateBr(finalTestBlock);
     290
     291    iBuilder->SetInsertPoint(exitBlock);
    334292    iBuilder->CreateRetVoid();
    335293
    336 
    337     mMod->dump();
     294    main->dump();
     295
     296    return main;
    338297}
    339298
     
    343302    delete mSortingKernel;
    344303}
     304
     305}
  • icGREP/icgrep-devel/icgrep/kernels/symboltablepipeline.h

    r4968 r4974  
    88
    99#include <IDISA/idisa_builder.h>
    10 #include <llvm/IR/Function.h>
    11 #include <llvm/IR/Module.h>
    1210#include "kernel.h"
    1311
    1412namespace llvm {
    15     class Value;
    1613    class Module;
    17     class ExecutionEngine;
    18     class VectorType;
    19     class PointerType;
    20     class Constant;
    21     class FunctionType;
    2214    class Function;
    23     class BasicBlock;
    2415    class Type;
    2516}
     
    2718namespace pablo { class PabloFunction; class PabloBlock; }
    2819
    29 using namespace llvm;
     20namespace kernel {
    3021
    3122class SymbolTableBuilder {
    3223public:
    33     SymbolTableBuilder(Module * m, IDISA::IDISA_Builder * b);
     24    SymbolTableBuilder(llvm::Module * m, IDISA::IDISA_Builder * b);
    3425    ~SymbolTableBuilder();
    3526    void createKernels();
    36     void ExecuteKernels();
     27    llvm::Function * ExecuteKernels();
     28
    3729protected:
    3830
     
    4335
    4436private:
    45     Module *                            mMod;
     37    llvm::Module *                      mMod;
    4638    IDISA::IDISA_Builder *              iBuilder;
    4739    KernelBuilder *                     mS2PKernel;
     
    4941    KernelBuilder *                     mSortingKernel;
    5042    unsigned                            mLongestLookahead;
    51     int                                 mFileBufIdx;
    52     int                                 mFileSizeIdx;
    53     int                                 mFileNameIdx;
    54     Type*                               mBitBlockType;
     43    llvm::Type *                        mBitBlockType;
    5544    int                                 mBlockSize;
    5645};
    5746
     47}
     48
    5849#endif // SYMBOLTABLEPIPELINE_H
Note: See TracChangeset for help on using the changeset viewer.