Changeset 4986


Ignore:
Timestamp:
Mar 22, 2016, 5:14:05 PM (3 years ago)
Author:
nmedfort
Message:

First attempt at dynamic segment size intergration.

Location:
icGREP/icgrep-devel/icgrep
Files:
1 added
15 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/IDISA/idisa_builder.cpp

    r4974 r4986  
    8181}
    8282
     83void IDISA_Builder::CallPrintInt(const std::string & name, Value * const value) {
     84    Constant * printRegister = mMod->getFunction("PrintInt");
     85    if (LLVM_UNLIKELY(printRegister == nullptr)) {
     86        FunctionType *FT = FunctionType::get(getVoidTy(), { PointerType::get(getInt8Ty(), 0), getInt64Ty() }, false);
     87        Function * function = Function::Create(FT, Function::InternalLinkage, "PrintInt", mMod);
     88        auto arg = function->arg_begin();
     89        std::string out = "%-40s = %i\n";
     90        BasicBlock * entry = BasicBlock::Create(mMod->getContext(), "entry", function);
     91        IRBuilder<> builder(entry);
     92        std::vector<Value *> args;
     93        args.push_back(geti8StrVal(*mMod, out.c_str(), ""));
     94        Value * const name = arg++;
     95        name->setName("name");
     96        args.push_back(name);
     97        Value * value = arg;
     98        value->setName("value");
     99        args.push_back(value);
     100        builder.CreateCall(create_printf(mMod), args);
     101        builder.CreateRetVoid();
     102
     103        printRegister = function;
     104    }
     105    CreateCall2(printRegister, geti8StrVal(*mMod, name.c_str(), name), CreateBitCast(value, getInt64Ty()));
     106}
     107
    83108Constant * IDISA_Builder::simd_himask(unsigned fw) {
    84109    return Constant::getIntegerValue(getIntNTy(mBitBlockWidth), APInt::getSplat(mBitBlockWidth, APInt::getHighBitsSet(fw, fw/2)));
  • icGREP/icgrep-devel/icgrep/IDISA/idisa_builder.h

    r4974 r4986  
    6666
    6767    void CallPrintRegister(const std::string & regName, Value * const value);
     68    void CallPrintInt(const std::string & name, Value * const value);
    6869
    6970    Constant * simd_himask(unsigned fw);
  • icGREP/icgrep-devel/icgrep/grep_engine.cpp

    r4984 r4986  
    103103        finalLineUnterminated = 1;
    104104   
    105     mMainFcn(mFileBuffer, mFileSize, mFileName.c_str(), finalLineUnterminated);
     105    mGrepFunction(mFileBuffer, mFileSize, mFileName.c_str(), finalLineUnterminated);
    106106
    107107
     
    127127    pipelineBuilder.CreateKernels(function, isNameExpression);
    128128
    129     pipelineBuilder.ExecuteKernels();
     129    llvm::Function * grepIR = pipelineBuilder.ExecuteKernels();
    130130
    131     llvm::Function * main_IR = M->getFunction("Main");
    132131    mEngine = JIT_to_ExecutionEngine(M);
    133132   
     
    139138    delete idb;
    140139
    141     mMainFcn = reinterpret_cast<GrepFunctionType>(mEngine->getPointerToFunction(main_IR));
     140    mGrepFunction = reinterpret_cast<GrepFunctionType>(mEngine->getPointerToFunction(grepIR));
    142141}
    143142
     
    152151    if(finalLineIsUnterminated(mFileBuffer, mFileSize))
    153152        finalLineUnterminated = 1;   
    154     mMainFcn(mFileBuffer, mFileSize, mFileName.c_str(), finalLineUnterminated);
     153    mGrepFunction(mFileBuffer, mFileSize, mFileName.c_str(), finalLineUnterminated);
    155154
    156155    return getParsedCodePointSet();
  • icGREP/icgrep-devel/icgrep/grep_engine.h

    r4973 r4986  
    3333    bool finalLineIsUnterminated(char * fileBuffer, size_t fileSize) const;
    3434
    35     GrepFunctionType mMainFcn;
     35    GrepFunctionType mGrepFunction;
    3636   
    3737    bool mIsNameExpression;
  • icGREP/icgrep-devel/icgrep/icgrep-devel.files

    r4974 r4986  
    701701IDISA/idisa_i64_builder.h
    702702kernels/instance.h
     703kernels/streamset.h
     704util/papi_helper.hpp
     705util/slab_allocator.h
     706util/ispc.cpp
  • icGREP/icgrep-devel/icgrep/icgrep-devel.includes

    r4959 r4986  
    2121CMakeFiles
    2222CMakeFiles/3.2.2/CompilerIdCXX
     23util
  • icGREP/icgrep-devel/icgrep/kernels/instance.h

    r4983 r4986  
    1313public:
    1414
    15     void call(llvm::Value * inputStreams) {
    16         assert (inputStreams);
    17         return mDefinition->call(mMemory, inputStreams);
     15    void CreateDoBlockCall() {
     16        mDefinition->CreateDoBlockCall(mMemory);
    1817    }
    1918
     
    5049    }
    5150
    52     llvm::Value * getOutputStreamSet(const unsigned streamOffset = 0) {
    53         return mDefinition->getOutputStreamSet(mMemory, streamOffset);
     51    void clearOutputStream(const unsigned streamOffset = 0) {
     52        mDefinition->clearOutputStream(mMemory, streamOffset);
     53    }
     54
     55    inline std::pair<llvm::Value *, unsigned> getOutputStreamSet() const {
     56        return std::make_pair(mMemory, mDefinition->getBufferSize());
    5457    }
    5558
     
    6063    llvm::Value * getBlockNo() {
    6164        return mDefinition->getBlockNo(mMemory);
     65    }
     66
     67    unsigned getBufferSize() const {
     68        return mDefinition->getBufferSize();
    6269    }
    6370
  • icGREP/icgrep-devel/icgrep/kernels/kernel.cpp

    r4974 r4986  
    77#include <pablo/function.h>
    88#include <IDISA/idisa_builder.h>
    9 #include <llvm/Support/CommandLine.h>
    109#include <kernels/instance.h>
    1110
     
    1312using namespace pablo;
    1413
    15 static cl::opt<unsigned> SegmentSize("segment-size", cl::desc("Segment Size"), cl::value_desc("positive integer"), cl::init(1));
    16 
    1714inline bool isPowerOfTwo(const unsigned x) {
    1815    return (x != 0) && (x & (x - 1)) == 0;
     
    2118namespace kernel {
    2219
     20enum : unsigned {
     21    INTERNAL_STATE = 0
     22    , INPUT_STREAM_SET = 1
     23    , OUTPUT_STREAM_SET = 2
     24    , OUTPUT_SCALAR_SET = 3
     25};
     26
    2327// sets name & sets internal state to the kernel superclass state
    24 KernelBuilder::KernelBuilder(std::string name, Module * m, IDISA::IDISA_Builder * b)
     28KernelBuilder::KernelBuilder(std::string name, Module * m, IDISA::IDISA_Builder * b, const unsigned bufferSize)
    2529: mMod(m)
    2630, iBuilder(b)
    2731, mKernelName(name)
    2832, mBitBlockType(b->getBitBlockType())
    29 , mBlockSize(b->getBitBlockWidth())
    30 , mBlocksPerSegment(SegmentSize)
    31 , mCircularBufferModulo(1)
    32 , mSegmentIndex(0)
    33 , mBlockIndex(0) {
    34     assert (mBlocksPerSegment > 0);
    35     mBlockIndex = addInternalState(b->getInt64Ty(), "BlockNo");
     33, mBufferSize(bufferSize)
     34, mBlockNoIndex(0) {
     35    assert (mBufferSize > 0);
     36    mBlockNoIndex = addInternalState(b->getInt64Ty(), "BlockNo");
    3637}
    3738
     
    5758}
    5859
    59 
    6060/** ------------------------------------------------------------------------------------------------------------- *
    6161 * @brief getInternalState
    6262 ** ------------------------------------------------------------------------------------------------------------- */
    6363Value * KernelBuilder::getInternalState(Value * const instance, const unsigned index) {
    64     Value* indices[] = {iBuilder->getInt64(0), iBuilder->getInt32(0), iBuilder->getInt32(index)};
    65     return iBuilder->CreateGEP(instance ? instance : mKernelParam, indices);
     64    Value* indices[] = {iBuilder->getInt64(0),
     65                        iBuilder->getInt32(INTERNAL_STATE),
     66                        iBuilder->getInt32(index)};
     67    return iBuilder->CreateGEP(instance, indices);
    6668}
    6769
     
    103105    assert (fields > 0 && !name.empty());
    104106    mInputStreamName.push_back(name);
    105     if (fields == 1){
     107    if (fields == 1) {
    106108        mInputStream.push_back(mBitBlockType);
    107109    } else {
     
    111113
    112114void KernelBuilder::addInputStream(const unsigned fields) {
    113     addInputStream(fields, std::move(mKernelName + "_inputstream_" + std::to_string(mInputStream.size())));
     115    addInputStream(fields, std::move(mKernelName + "_InputStream_" + std::to_string(mInputStream.size())));
    114116}
    115117
     
    117119 * @brief getInputStream
    118120 ** ------------------------------------------------------------------------------------------------------------- */
    119 Value * KernelBuilder::getInputStream(llvm::Value * const instance, const unsigned index, const unsigned streamOffset) {
     121Value * KernelBuilder::getInputStream(Value * const instance, const unsigned index, const unsigned streamOffset) {
    120122    assert (instance);
    121     Value * const indices[] = {getOffset(instance, streamOffset), iBuilder->getInt32(index)};
    122     return iBuilder->CreateGEP(instance, indices);
     123    Value * inputStream = iBuilder->CreateLoad(iBuilder->CreateGEP(instance,
     124        {iBuilder->getInt32(0), iBuilder->getInt32(INPUT_STREAM_SET), iBuilder->getInt32(0)}));
     125    Value * modFunction = iBuilder->CreateLoad(iBuilder->CreateGEP(instance,
     126        {iBuilder->getInt32(0), iBuilder->getInt32(INPUT_STREAM_SET), iBuilder->getInt32(1)}));
     127    Value * offset = iBuilder->CreateLoad(getBlockNo(instance));
     128    if (streamOffset) {
     129        offset = iBuilder->CreateAdd(offset, ConstantInt::get(offset->getType(), streamOffset));
     130    }   
     131    offset = iBuilder->CreateCall(modFunction, offset, "offset");
     132    return iBuilder->CreateGEP(inputStream, { offset, iBuilder->getInt32(index) });
    123133}
    124134
     
    133143
    134144void KernelBuilder::addInputScalar(Type * const type) {
    135     addInputScalar(type, std::move(mKernelName + "_inputscalar_" + std::to_string(mInputScalar.size())));
     145    addInputScalar(type, std::move(mKernelName + "_InputScalar_" + std::to_string(mInputScalar.size())));
    136146}
    137147
     
    168178Value * KernelBuilder::getOutputStream(Value * const instance, const unsigned index, const unsigned streamOffset) {
    169179    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  ** ------------------------------------------------------------------------------------------------------------- */
    177 Value * KernelBuilder::getOutputStreamSet(Value * const instance, const unsigned streamOffset) {
    178     assert (instance);
    179     Value * const indices[] = {getOffset(instance, streamOffset), iBuilder->getInt32(1)};
     180    Value * offset = getOffset(instance, streamOffset);
     181    Value * const indices[] = {iBuilder->getInt32(0), iBuilder->getInt32(OUTPUT_STREAM_SET), offset, iBuilder->getInt32(index)};
    180182    return iBuilder->CreateGEP(instance, indices);
    181183}
     
    191193 * @brief prepareFunction
    192194 ** ------------------------------------------------------------------------------------------------------------- */
    193 Function * KernelBuilder::prepareFunction() {   
    194     if (mCircularBufferModulo > 1) {
    195         mBlockIndex = addInternalState(iBuilder->getInt32Ty());
    196     }
    197     const unsigned capacity = mBlocksPerSegment + mCircularBufferModulo - 1;
    198 
     195Function * KernelBuilder::prepareFunction() {
     196
     197    PointerType * modFunctionType = PointerType::get(FunctionType::get(iBuilder->getInt64Ty(), {iBuilder->getInt64Ty()}, false), 0);
    199198    mInputStreamType = PointerType::get(StructType::get(mMod->getContext(), mInputStream), 0);
    200199    mInputScalarType = PointerType::get(StructType::get(mMod->getContext(), mInputScalar), 0);
    201     Type * outputStreamType = ArrayType::get(StructType::get(mMod->getContext(), mOutputStream), capacity);
    202     Type * outputAccumType = StructType::get(mMod->getContext(), mOutputScalar);
    203     Type * internalStateType = StructType::create(mMod->getContext(), mInternalState, mKernelName);
    204     mKernelStructType = StructType::create(mMod->getContext(),std::vector<Type *>({internalStateType, outputStreamType, outputAccumType}), "KernelStruct_"+ mKernelName);
    205 
    206     FunctionType * functionType = FunctionType::get(Type::getVoidTy(mMod->getContext()),
    207         std::vector<Type *>({PointerType::get(mKernelStructType, 0), mInputStreamType}), false);
    208 
    209     mFunction = Function::Create(functionType, GlobalValue::ExternalLinkage, mKernelName + "_DoBlock", mMod);
    210     mFunction->setCallingConv(CallingConv::C);
    211 
    212     Function::arg_iterator args = mFunction->arg_begin();
     200    mOutputStreamType = StructType::get(mMod->getContext(), mOutputStream);
     201    Type * outputScalarType = StructType::get(mMod->getContext(), mOutputScalar);
     202    Type * internalStateType = StructType::create(mMod->getContext(), mInternalState);
     203    Type * inputStateType = StructType::create(mMod->getContext(), { mInputStreamType, modFunctionType});
     204
     205    Type * outputBufferType = ArrayType::get(mOutputStreamType, mBufferSize);
     206    mKernelStateType = StructType::create(mMod->getContext(), {internalStateType, inputStateType, outputBufferType, outputScalarType}, mKernelName);
     207
     208    FunctionType * const functionType = FunctionType::get(iBuilder->getVoidTy(), {PointerType::get(mKernelStateType, 0)}, false);
     209    mDoBlock = Function::Create(functionType, GlobalValue::ExternalLinkage, mKernelName + "_DoBlock", mMod);
     210    mDoBlock->setCallingConv(CallingConv::C);
     211    mDoBlock->addAttribute(1, Attribute::NoCapture);
     212    mDoBlock->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
     213    mDoBlock->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
     214
     215    Function::arg_iterator args = mDoBlock->arg_begin();
    213216    mKernelParam = args++;
    214217    mKernelParam->setName("this");
    215     mInputParam = args++;
    216     mInputParam->setName("input_stream");
    217 
    218     iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", mFunction, 0));
    219 
    220     mSegmentIndex = 0;
    221 
    222     return mFunction;
     218
     219    iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", mDoBlock, 0));
     220
     221//    mLocalBlockNo = iBuilder->CreateLoad(getBlockNo());
     222//    Value * blockNo = iBuilder->CreateLoad(getBlockNo());
     223//    iBuilder->CallPrintInt(mKernelName + "_BlockNo", blockNo);
     224//    Value * modFunction = iBuilder->CreateLoad(iBuilder->CreateGEP(mKernelParam, {iBuilder->getInt32(0), iBuilder->getInt32(INPUT_STREAM_SET), iBuilder->getInt32(1)}));
     225//    blockNo = iBuilder->CreateCall(modFunction, blockNo);
     226//    iBuilder->CallPrintInt(mKernelName + "_Offset", blockNo);
     227
     228
     229    return mDoBlock;
    223230}
    224231
     
    229236
    230237    // Finish the actual function
    231     Value * startIdx = getInternalState(mBlockIndex);
    232     Value * value = iBuilder->CreateBlockAlignedLoad(startIdx);
     238    Value * blockNo = getBlockNo();
     239    Value * value = iBuilder->CreateLoad(blockNo);
    233240    value = iBuilder->CreateAdd(value, ConstantInt::get(value->getType(), 1));
    234     iBuilder->CreateBlockAlignedStore(value, startIdx);
     241    iBuilder->CreateStore(value, blockNo);
    235242    iBuilder->CreateRetVoid();
    236243
    237     Type * const int64Ty = iBuilder->getInt64Ty(); // TODO: should call getIntPtrTy() instead but we don't have the data layout here.
    238 
    239244    // Generate the zero initializer
    240     mConstructor = cast<Function>(mMod->getOrInsertFunction(mKernelName + "_Constructor", Type::getVoidTy(mMod->getContext()), PointerType::get(mKernelStructType, 0), nullptr));
     245    PointerType * modFunctionType = PointerType::get(FunctionType::get(iBuilder->getInt64Ty(), {iBuilder->getInt64Ty()}, false), 0);
     246    FunctionType * constructorType = FunctionType::get(iBuilder->getVoidTy(), {PointerType::get(mKernelStateType, 0), mInputStreamType, modFunctionType}, false);
     247
     248    mConstructor = Function::Create(constructorType, GlobalValue::ExternalLinkage, mKernelName + "_Constructor", mMod);
    241249    mConstructor->setCallingConv(CallingConv::C);
     250    mConstructor->addAttribute(1, Attribute::NoCapture);
     251    mConstructor->addAttribute(AttributeSet::FunctionIndex, Attribute::InlineHint);
     252    mConstructor->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
     253    mConstructor->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
    242254    auto args = mConstructor->arg_begin();
    243255    mKernelParam = args++;
    244256    mKernelParam->setName("this");
     257    Value * const inputStream = args++;
     258    inputStream->setName("inputStream");
     259    Value * const modFunction = args++;
     260    modFunction->setName("modFunction");
     261
    245262    iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", mConstructor, 0));
    246263    for (unsigned i = 0; i < mInternalState.size(); ++i) {
    247         Value * const gep = getInternalState(i);
    248         Type * const type = gep->getType();
     264        Type * const type = mInternalState[i];
    249265        if (type->isIntegerTy() || type->isArrayTy() || type->isVectorTy()) {
    250266            setInternalState(i, Constant::getNullValue(type));
    251267        } else {
    252             Value * gep_next = iBuilder->CreateGEP(gep, iBuilder->getInt32(1));
    253             Value * get_int = iBuilder->CreatePtrToInt(gep, int64Ty);
    254             Value * get_next_int = iBuilder->CreatePtrToInt(gep_next, int64Ty);
    255             Value * state_size = iBuilder->CreateSub(get_next_int, get_int);
    256             iBuilder->CreateMemSet(gep, iBuilder->getInt8(0), state_size, 4);
     268            Value * const ptr = getInternalState(i);
     269            Value * const size = iBuilder->CreatePtrDiff(iBuilder->CreateGEP(ptr, iBuilder->getInt32(1)), ptr);
     270            iBuilder->CreateMemSet(ptr, iBuilder->getInt8(0), size, 4);
    257271        }
    258272    }
     273
     274    Value * const input = iBuilder->CreateGEP(mKernelParam, {iBuilder->getInt32(0), iBuilder->getInt32(INPUT_STREAM_SET)});
     275    iBuilder->CreateStore(inputStream, iBuilder->CreateGEP(input, {iBuilder->getInt32(0), iBuilder->getInt32(0)}));
     276    iBuilder->CreateStore(modFunction, iBuilder->CreateGEP(input, {iBuilder->getInt32(0), iBuilder->getInt32(1)}));
    259277    iBuilder->CreateRetVoid();
    260278
     279//    if (mOutputStreamType->getStructNumElements()) {
     280//        PointerType * outputStreamType = PointerType::get(mOutputStreamType, 0);
     281//        FunctionType * type = FunctionType::get(outputStreamType, {outputStreamType, PointerType::get(blockNo->getType(), 0)}, false);
     282//        mStreamSetFunction = Function::Create(type, Function::ExternalLinkage, mKernelName + "_StreamSet", mMod);
     283//        auto arg = mStreamSetFunction->arg_begin();
     284//        Value * stream = arg++;
     285//        stream->setName("stream");
     286//        mStreamSetFunction->addAttribute(1, Attribute::NoCapture);
     287//        mStreamSetFunction->addAttribute(2, Attribute::NoCapture);
     288//        mStreamSetFunction->addAttribute(AttributeSet::FunctionIndex, Attribute::InlineHint);
     289//        mStreamSetFunction->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
     290//        mStreamSetFunction->addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
     291//        Value * offset = arg;
     292//        BasicBlock * entry = BasicBlock::Create(mMod->getContext(), "entry", mStreamSetFunction);
     293//        iBuilder->SetInsertPoint(entry);
     294//        if (mBufferSize != 1) {
     295//            offset = iBuilder->CreateLoad(offset);
     296//            if (isPowerOfTwo(mBufferSize)) {
     297//                offset = iBuilder->CreateAnd(offset, iBuilder->getInt64(mBufferSize - 1));
     298//            } else if (mBufferSize > 2) {
     299//                offset = iBuilder->CreateURem(offset, iBuilder->getInt64(mBufferSize));
     300//            }
     301//            stream = iBuilder->CreateGEP(stream, offset);
     302//        }
     303//        iBuilder->CreateRet(stream);
     304//    }
     305
    261306    iBuilder->ClearInsertionPoint();
    262 
    263     mSegmentIndex = 0;
    264307}
    265308
     
    269312 * Generate a new instance of this kernel and call the default constructor to initialize it
    270313 ** ------------------------------------------------------------------------------------------------------------- */
    271 Instance * KernelBuilder::instantiate() {
    272     AllocaInst * const memory = iBuilder->CreateAlloca(mKernelStructType);
    273     iBuilder->CreateCall(mConstructor, memory);
     314Instance * KernelBuilder::instantiate(std::pair<Value *, unsigned> && inputStream) {
     315    AllocaInst * const memory = iBuilder->CreateAlloca(mKernelStateType);
     316    Value * const indices[] = {iBuilder->getInt32(0), iBuilder->getInt32(OUTPUT_STREAM_SET)};
     317    Value * ptr = iBuilder->CreateGEP(std::get<0>(inputStream), indices);
     318    iBuilder->CreateCall3(mConstructor, memory, iBuilder->CreatePointerCast(ptr, mInputStreamType), CreateModFunction(std::get<1>(inputStream)));
    274319    return new Instance(this, memory);
    275320}
    276321
    277322/** ------------------------------------------------------------------------------------------------------------- *
    278  * @brief call
    279  ** ------------------------------------------------------------------------------------------------------------- */
    280 void KernelBuilder::call(llvm::Value * const instance, Value * inputStreams) {
    281     assert (mFunction && instance && inputStreams);
    282     iBuilder->CreateCall2(mFunction, instance, iBuilder->CreatePointerCast(inputStreams, mInputStreamType));
     323 * @brief instantiate
     324 *
     325 * Generate a new instance of this kernel and call the default constructor to initialize it
     326 ** ------------------------------------------------------------------------------------------------------------- */
     327Instance * KernelBuilder::instantiate(llvm::Value * const inputStream) {
     328    AllocaInst * const memory = iBuilder->CreateAlloca(mKernelStateType);
     329    Value * ptr = inputStream;
     330    iBuilder->CreateCall3(mConstructor, memory, iBuilder->CreatePointerCast(ptr, mInputStreamType), CreateModFunction(0));
     331    return new Instance(this, memory);
     332}
     333
     334/** ------------------------------------------------------------------------------------------------------------- *
     335 * @brief CreateDoBlockCall
     336 ** ------------------------------------------------------------------------------------------------------------- */
     337void KernelBuilder::CreateDoBlockCall(Value * const instance) {
     338    assert (mDoBlock && instance);
     339    iBuilder->CreateCall(mDoBlock, instance);
     340}
     341
     342/** ------------------------------------------------------------------------------------------------------------- *
     343 * @brief clearOutputStream
     344 ** ------------------------------------------------------------------------------------------------------------- */
     345void KernelBuilder::clearOutputStream(Value * const instance, const unsigned streamOffset) {
     346    Value * const indices[] = {iBuilder->getInt32(0), iBuilder->getInt32(OUTPUT_STREAM_SET), getOffset(instance, streamOffset)};
     347    Value * ptr = iBuilder->CreateGEP(instance, indices, "ptr");
     348    unsigned size = 0;
     349    for (unsigned i = 0; i < mOutputStreamType->getStructNumElements(); ++i) {
     350        size += mOutputStreamType->getStructElementType(i)->getPrimitiveSizeInBits();
     351    }
     352    iBuilder->CreateMemSet(ptr, iBuilder->getInt8(0), size / 8, 4);
    283353}
    284354
     
    289359 ** ------------------------------------------------------------------------------------------------------------- */
    290360Value * KernelBuilder::getOffset(Value * const instance, const unsigned value) {
    291     const unsigned adjustedOffset = (mSegmentIndex + value);
    292     if (mBlockIndex) {
    293         Value * offset = iBuilder->CreateBlockAlignedLoad(getBlockNo(instance));
    294         if (adjustedOffset) {
    295             offset = iBuilder->CreateAdd(offset, ConstantInt::get(offset->getType(), adjustedOffset));
     361    Value * offset = nullptr;
     362    if (mBufferSize > 1) {
     363        offset = iBuilder->CreateLoad(getBlockNo(instance));
     364        if (value) {
     365            offset = iBuilder->CreateAdd(offset, iBuilder->getInt64(value));
    296366        }
    297         const unsigned bufferSize = (mBlocksPerSegment + mCircularBufferModulo - 1); assert (bufferSize > 1);
    298         if (isPowerOfTwo(bufferSize)) {
    299             offset = iBuilder->CreateAnd(offset, ConstantInt::get(offset->getType(), bufferSize - 1));
     367        if (isPowerOfTwo(mBufferSize)) {
     368            offset = iBuilder->CreateAnd(offset, iBuilder->getInt64(mBufferSize - 1));
    300369        } else {
    301             offset = iBuilder->CreateURem(offset, ConstantInt::get(offset->getType(), bufferSize));
     370            offset = iBuilder->CreateURem(offset, iBuilder->getInt64(mBufferSize));
    302371        }
    303         // TODO: generate branch / phi node when it's sufficiently unlikely that we'll wrap around.
    304         return offset;
    305372    } else {
    306         return iBuilder->getInt32(adjustedOffset);
    307     }
     373        offset = iBuilder->getInt64(value);
     374    }
     375    return offset;
     376}
     377
     378/** ------------------------------------------------------------------------------------------------------------- *
     379 * @brief CreateModFunction
     380 *
     381 * Generate a "modulo" function that dictates the local offset of a given blockNo
     382 ** ------------------------------------------------------------------------------------------------------------- */
     383inline Function * KernelBuilder::CreateModFunction(const unsigned size) {
     384    const std::string name((size == 0) ? "continuous" : "finite" + std::to_string(size));
     385    Function * function = mMod->getFunction(name);
     386    if (function) {
     387        return function;
     388    }
     389    const auto ip = iBuilder->saveIP();
     390    FunctionType * type = FunctionType::get(iBuilder->getInt64Ty(), {iBuilder->getInt64Ty()}, false);
     391    function = Function::Create(type, Function::ExternalLinkage, name, mMod);
     392    Value * offset = function->arg_begin();
     393    offset->setName("index");
     394    BasicBlock * entry = BasicBlock::Create(mMod->getContext(), "entry", function);
     395    iBuilder->SetInsertPoint(entry);
     396    if (size) {
     397        if (size == 1) {
     398            offset = iBuilder->getInt64(0);
     399        } else if (isPowerOfTwo(size)) {
     400            offset = iBuilder->CreateAnd(offset, iBuilder->getInt64(size - 1));
     401        } else {
     402            offset = iBuilder->CreateURem(offset, iBuilder->getInt64(size));
     403        }
     404    }
     405    iBuilder->CreateRet(offset);
     406    iBuilder->restoreIP(ip);
     407    return function;
    308408}
    309409
     
    314414    const unsigned blockWidth = iBuilder->getBitBlockWidth();
    315415    const unsigned lookaheadBlocks = (bits + blockWidth - 1) / blockWidth;
    316     mCircularBufferModulo = (lookaheadBlocks + 1);
     416    mBufferSize = (lookaheadBlocks + 1);
    317417}
    318418
  • icGREP/icgrep-devel/icgrep/kernels/kernel.h

    r4974 r4986  
    4242public:
    4343    // sets name & sets internal state to the kernel superclass state
    44     KernelBuilder(std::string name, llvm::Module * m, IDISA::IDISA_Builder * b);
     44    KernelBuilder(std::string name, llvm::Module * m, IDISA::IDISA_Builder * b, const unsigned bufferSize = 1);
    4545
    4646    unsigned addInternalState(llvm::Type * const type);
     
    5858    llvm::Function * prepareFunction();
    5959
    60     void increment();
    61 
    6260    inline llvm::Value * getInputStream(const unsigned index, const unsigned streamOffset = 0) {
    63         return getInputStream(mInputParam, index, streamOffset);
     61        return getInputStream(mKernelParam, index, streamOffset);
    6462    }
    6563
    6664    inline llvm::Value * getInputScalar(const unsigned index) {
    67         return getInputScalar(mInputParam, index);
     65        return getInputScalar(mKernelParam, index);
    6866    }
    6967
     
    8785        return getOutputStream(mKernelParam, index, streamOffset);
    8886    }
    89     llvm::Value * getOutputStreamSet(const unsigned streamOffset = 0) {
    90         return getOutputStreamSet(mKernelParam, streamOffset);
     87
     88    inline unsigned getNumOfOutputStreams() const {
     89        return mOutputStream.size();
    9190    }
    9291
     
    9594    }
    9695
     96    inline unsigned getNumOfOutputScalars() const {
     97        return mOutputScalar.size();
     98    }
     99
    97100    llvm::Value * getBlockNo() {
    98101        return getBlockNo(mKernelParam);
     
    101104    llvm::Type * getInputStreamType() const;
    102105
     106    void setInputBufferSize(const unsigned bufferSize);
     107
     108    unsigned getInputBufferSize() const;
     109
     110    unsigned getBufferSize() const;
     111
    103112    void finalize();
    104113
    105     kernel::Instance * instantiate();
    106 
    107     unsigned getSegmentBlocks() const;
     114    kernel::Instance * instantiate(llvm::Value * const inputStream);
     115
     116    kernel::Instance * instantiate(std::pair<llvm::Value *, unsigned> &&inputStream);
    108117
    109118    llvm::Type * getKernelStateType() const;
     
    113122    llvm::Function * getDoBlockFunction() const;
    114123
     124    void clearOutputStream(llvm::Value * const instance, const unsigned streamOffset = 0);
     125
    115126    void setLongestLookaheadAmount(const unsigned bits);
    116127
    117     void setBlocksPerSegment(const unsigned blocks);
    118 
    119128protected:
    120129
     
    133142    llvm::Value * getOutputStream(llvm::Value * const instance, const unsigned index, const unsigned streamOffset);
    134143
    135     llvm::Value * getOutputStreamSet(llvm::Value * const instance, const unsigned streamOffset);
    136 
    137144    llvm::Value * getOutputScalar(llvm::Value * const instance, const unsigned index);
    138145
     
    141148    llvm::Value * getBlockNo(llvm::Value * const instance);
    142149
    143     void call(llvm::Value * const instance, llvm::Value * inputStreams);
     150    llvm::Function * getOutputStreamSetFunction() const;
     151
     152    void CreateDoBlockCall(llvm::Value * const instance);
     153
     154    llvm::Function * CreateModFunction(const unsigned size);
    144155
    145156private:
     
    148159    std::string                                                 mKernelName;
    149160    llvm::Type *                        mBitBlockType;
    150     llvm::Function*                                     mConstructor;
    151     llvm::Function*                                             mFunction;
    152     unsigned                            mBlockSize;
    153     unsigned                            mBlocksPerSegment;
    154     unsigned                            mCircularBufferModulo;
    155     llvm::Type *                        mKernelStructType;
     161    llvm::Function *                                    mConstructor;
     162    llvm::Function *                                    mDoBlock;
     163
     164    unsigned                            mBufferSize;
     165
     166    llvm::Type *                        mKernelStateType;
    156167    llvm::Type *                        mInputStreamType;
    157168    llvm::Type *                        mInputScalarType;
     169    llvm::Type *                        mOutputStreamType;
     170
    158171    llvm::Value *                       mInputParam;
    159172    llvm::Value *                       mKernelParam;
    160     unsigned                            mSegmentIndex;
    161     unsigned                            mBlockIndex;
     173    unsigned                            mBlockNoIndex;
     174
    162175    std::vector<llvm::Type *>           mInputStream;
    163176    std::vector<std::string>            mInputStreamName;
    164177    std::vector<llvm::Type *>           mInputScalar;
    165     std::vector<std::string>            mInputScalarName;
     178    std::vector<std::string>            mInputScalarName;   
    166179    std::vector<llvm::Type *>           mOutputStream;
    167180    std::vector<llvm::Type *>           mOutputScalar;
     
    170183};
    171184
    172 inline unsigned KernelBuilder::getSegmentBlocks() const {
    173     return mBlocksPerSegment;
    174 }
    175 
    176185inline llvm::Function * KernelBuilder::getDoBlockFunction() const {
    177     return mFunction;
     186    return mDoBlock;
    178187}
    179188
    180189inline llvm::Type * KernelBuilder::getKernelStateType() const{
    181     return mKernelStructType;
     190    return mKernelStateType;
    182191}
    183192
     
    186195}
    187196
    188 inline void KernelBuilder::setBlocksPerSegment(const unsigned blocks) {
    189     mBlocksPerSegment = blocks;
    190 }
    191 
    192197inline llvm::Type * KernelBuilder::getInputStreamType() const {
    193198    return mInputStreamType;
    194199}
    195200
    196 inline void KernelBuilder::increment() {
    197     ++mSegmentIndex;
    198 }
    199 
    200201inline llvm::Value * KernelBuilder::getBlockNo(llvm::Value * const instance) {
    201     return getInternalState(instance, mBlockIndex);
     202    return getInternalState(instance, mBlockNoIndex);
     203}
     204
     205inline unsigned KernelBuilder::getBufferSize() const {
     206    return mBufferSize;
    202207}
    203208
  • icGREP/icgrep-devel/icgrep/kernels/pipeline.cpp

    r4985 r4986  
    1515#include <pablo/pablo_toolchain.h>
    1616
     17#include <llvm/Support/CommandLine.h>
     18
     19static cl::opt<unsigned> SegmentSize("segment-size", cl::desc("Segment Size"), cl::value_desc("positive integer"), cl::init(1));
    1720
    1821using namespace pablo;
     
    2326, iBuilder(b)
    2427, mBitBlockType(b->getBitBlockType())
    25 , mBlockSize(b->getBitBlockWidth()){
     28, mBlockSize(b->getBitBlockWidth()) {
    2629
    2730}
    2831
    29 PipelineBuilder::~PipelineBuilder(){
     32PipelineBuilder::~PipelineBuilder() {
    3033    delete mS2PKernel;
    3134    delete mICgrepKernel;
     
    3437
    3538void PipelineBuilder::CreateKernels(PabloFunction * function, bool isNameExpression){
    36     mS2PKernel = new KernelBuilder("s2p", mMod, iBuilder);
    37     mICgrepKernel = new KernelBuilder("icgrep", mMod, iBuilder);
    38     mScanMatchKernel = new KernelBuilder("scanMatch", mMod, iBuilder);
    39 
     39    mS2PKernel = new KernelBuilder("s2p", mMod, iBuilder, SegmentSize);
     40    mICgrepKernel = new KernelBuilder("icgrep", mMod, iBuilder, SegmentSize);
     41    mScanMatchKernel = new KernelBuilder("scanMatch", mMod, iBuilder, SegmentSize);
    4042    generateS2PKernel(mMod, iBuilder, mS2PKernel);
    41 
    4243    generateScanMatch(mMod, iBuilder, 64, mScanMatchKernel, isNameExpression);
    43 
    4444    pablo_function_passes(function);
    45 
    4645    PabloCompiler pablo_compiler(mMod, iBuilder);
    4746    try {
     
    5857}
    5958
    60 void PipelineBuilder::ExecuteKernels() {
    61     Type * T = iBuilder->getIntNTy(64);   
    62     Type * S = PointerType::get(iBuilder->getIntNTy(8), 0);
    63     Type * inputType = PointerType::get(ArrayType::get(StructType::get(mMod->getContext(), std::vector<Type *>({ArrayType::get(mBitBlockType, 8)})), 1), 0);
    64     Function * const main = cast<Function>(mMod->getOrInsertFunction("Main", Type::getVoidTy(mMod->getContext()), inputType, T, S, T, nullptr));
     59Function * PipelineBuilder::ExecuteKernels() {
     60    Type * const int64ty = iBuilder->getInt64Ty();
     61    Type * const int8PtrTy = iBuilder->getInt8PtrTy();
     62    Type * const inputType = PointerType::get(ArrayType::get(StructType::get(mMod->getContext(), std::vector<Type *>({ArrayType::get(mBitBlockType, 8)})), 1), 0);
     63
     64    Function * const main = cast<Function>(mMod->getOrInsertFunction("Main", Type::getVoidTy(mMod->getContext()), inputType, int64ty, int8PtrTy, int64ty, nullptr));
    6565    main->setCallingConv(CallingConv::C);
    6666    Function::arg_iterator args = main->arg_begin();
     
    6868    Value * const inputStream = args++;
    6969    inputStream->setName("input");
    70     Value* buffersize_param = args++;
    71     buffersize_param->setName("buffersize");   
    72     Value* filename_param = args++;
    73     filename_param->setName("filename");     
    74     Value* finalLineUnterminated_param = args++;
    75     finalLineUnterminated_param->setName("finalLineUnterminated");
     70    Value * const bufferSize = args++;
     71    bufferSize->setName("bufferSize");
     72    Value * const fileName = args++;
     73    fileName->setName("fileName");
     74    Value * const finalLineUnterminated = args++;
     75    finalLineUnterminated->setName("finalLineUnterminated");
    7676
    7777    iBuilder->SetInsertPoint(BasicBlock::Create(mMod->getContext(), "entry", main,0));
    7878
    79     BasicBlock * entry_block = iBuilder->GetInsertBlock();
    80     BasicBlock * pipeline_test_block = BasicBlock::Create(mMod->getContext(), "pipeline_test_block", main, 0);
    81     BasicBlock * pipeline_do_block = BasicBlock::Create(mMod->getContext(), "pipeline_do_block", main, 0);
    82     BasicBlock * pipeline_final_block = BasicBlock::Create(mMod->getContext(), "pipeline_final_block", main, 0);
    83     BasicBlock * pipeline_partial_block = BasicBlock::Create(mMod->getContext(), "pipeline_partial_block", main, 0);
    84     BasicBlock * pipeline_empty_block = BasicBlock::Create(mMod->getContext(), "pipeline_empty_block", main, 0);
    85     BasicBlock * pipeline_end_block = BasicBlock::Create(mMod->getContext(), "pipeline_end_block", main, 0);
    86     BasicBlock * pipeline_Unterminated_block = BasicBlock::Create(mMod->getContext(), "pipeline_Unterminated_block", main, 0);
    87     BasicBlock * pipeline_return_block = BasicBlock::Create(mMod->getContext(), "pipeline_return_block", main, 0);
     79    BasicBlock * entryBlock = iBuilder->GetInsertBlock();
     80    BasicBlock * segmentCondBlock = nullptr;
     81    BasicBlock * segmentBodyBlock = nullptr;
     82    const unsigned segmentSize = SegmentSize;
     83    if (segmentSize > 1) {
     84        segmentCondBlock = BasicBlock::Create(mMod->getContext(), "segmentCond", main, 0);
     85        segmentBodyBlock = BasicBlock::Create(mMod->getContext(), "segmentBody", main, 0);
     86    }
     87    BasicBlock * fullCondBlock = BasicBlock::Create(mMod->getContext(), "fullCond", main, 0);
     88    BasicBlock * fullBodyBlock = BasicBlock::Create(mMod->getContext(), "fullBody", main, 0);
     89    BasicBlock * finalBlock = BasicBlock::Create(mMod->getContext(), "final", main, 0);
     90    BasicBlock * finalPartialBlock = BasicBlock::Create(mMod->getContext(), "partial", main, 0);
     91    BasicBlock * finalEmptyBlock = BasicBlock::Create(mMod->getContext(), "empty", main, 0);
     92    BasicBlock * endBlock = BasicBlock::Create(mMod->getContext(), "end", main, 0);
     93    BasicBlock * unterminatedBlock = BasicBlock::Create(mMod->getContext(), "unterminated", main, 0);
     94    BasicBlock * exitBlock = BasicBlock::Create(mMod->getContext(), "exit", main, 0);
    8895
    89     Instance * s2pInstance = mS2PKernel->instantiate();
    90     Instance * icGrepInstance = mICgrepKernel->instantiate();
    91     Instance * scanMatchInstance = mScanMatchKernel->instantiate();
     96    Instance * s2pInstance = mS2PKernel->instantiate(inputStream);
     97    Instance * icGrepInstance = mICgrepKernel->instantiate(s2pInstance->getOutputStreamSet());
     98    Instance * scanMatchInstance = mScanMatchKernel->instantiate(icGrepInstance->getOutputStreamSet());
     99
     100    Value * ptr = iBuilder->CreateBitCast(inputStream, int8PtrTy);
     101
     102    scanMatchInstance->setInternalState("FileBuf", ptr);
     103    scanMatchInstance->setInternalState("FileSize", bufferSize);
     104    scanMatchInstance->setInternalState("FileName", fileName);
     105
     106    // iBuilder->CallPrintInt("source", iBuilder->CreatePtrToInt(ptr, iBuilder->getInt64Ty()));
     107
     108    Value * initialBufferSize = nullptr;
     109    BasicBlock * initialBlock = nullptr;
     110
     111    if (segmentSize > 1) {
     112        iBuilder->CreateBr(segmentCondBlock);
     113        iBuilder->SetInsertPoint(segmentCondBlock);
     114        PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
     115        remainingBytes->addIncoming(bufferSize, entryBlock);
     116        Constant * const step = ConstantInt::get(int64ty, mBlockSize * segmentSize);
     117        Value * segmentCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
     118        iBuilder->CreateCondBr(segmentCondTest, fullCondBlock, segmentBodyBlock);
     119        iBuilder->SetInsertPoint(segmentBodyBlock);
     120        for (unsigned i = 0; i < segmentSize; ++i) {
     121            s2pInstance->CreateDoBlockCall();
     122        }
     123        for (unsigned i = 0; i < segmentSize; ++i) {
     124            icGrepInstance->CreateDoBlockCall();
     125        }
     126        for (unsigned i = 0; i < segmentSize; ++i) {
     127            scanMatchInstance->CreateDoBlockCall();
     128        }
     129        remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), segmentBodyBlock);
     130        iBuilder->CreateBr(segmentCondBlock);
     131        initialBufferSize = remainingBytes;
     132        initialBlock = segmentCondBlock;
     133    } else {
     134        initialBufferSize = bufferSize;
     135        initialBlock = entryBlock;
     136        iBuilder->CreateBr(fullCondBlock);
     137    }
     138
     139    iBuilder->SetInsertPoint(fullCondBlock);
     140    PHINode * remainingBytes = iBuilder->CreatePHI(int64ty, 2, "remainingBytes");
     141    remainingBytes->addIncoming(initialBufferSize, initialBlock);
     142
     143    Constant * const step = ConstantInt::get(int64ty, mBlockSize);
     144    Value * fullCondTest = iBuilder->CreateICmpULT(remainingBytes, step);
     145    iBuilder->CreateCondBr(fullCondTest, finalBlock, fullBodyBlock);
     146
     147    iBuilder->SetInsertPoint(fullBodyBlock);
     148    s2pInstance->CreateDoBlockCall();
     149    icGrepInstance->CreateDoBlockCall();
     150    scanMatchInstance->CreateDoBlockCall();
     151
     152    remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, step), fullBodyBlock);
     153    iBuilder->CreateBr(fullCondBlock);
     154
     155    iBuilder->SetInsertPoint(finalBlock);
     156    Value * const b4 = s2pInstance->getOutputStream(4);
     157    Value * const b6 = s2pInstance->getOutputStream(6);
     158    Value * emptyBlockCond = iBuilder->CreateICmpEQ(remainingBytes, ConstantInt::get(int64ty, 0));
     159    iBuilder->CreateCondBr(emptyBlockCond, finalEmptyBlock, finalPartialBlock);
    92160
    93161
    94     Value * gep = scanMatchInstance->getInternalState("FileBuf");
    95     Value * filebuf = iBuilder->CreateBitCast(inputStream, S);
    96     iBuilder->CreateStore(filebuf, gep);
     162    iBuilder->SetInsertPoint(finalPartialBlock);
     163    s2pInstance->CreateDoBlockCall();
     164    iBuilder->CreateBr(endBlock);
    97165
    98     gep = scanMatchInstance->getInternalState("FileSize");
    99     iBuilder->CreateStore(buffersize_param, gep);
     166    iBuilder->SetInsertPoint(finalEmptyBlock);
     167    s2pInstance->clearOutputStream();
     168    iBuilder->CreateBr(endBlock);
    100169
    101     gep = scanMatchInstance->getInternalState("FileName");
    102     iBuilder->CreateStore(filename_param, gep);
    103 
    104     Value * basis_bits = s2pInstance->getOutputStreamSet();
    105 
    106     Value * results = icGrepInstance->getOutputStreamSet();
    107 
    108     iBuilder->CreateBr(pipeline_test_block);
    109 
    110     iBuilder->SetInsertPoint(pipeline_test_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);
    115 
    116     Constant * step = ConstantInt::get(T, mBlockSize * mS2PKernel->getSegmentBlocks());
    117 
    118     Value * final_block_cond = iBuilder->CreateICmpSLT(remainingBytes, step);
    119     iBuilder->CreateCondBr(final_block_cond, pipeline_final_block, pipeline_do_block);
    120 
    121     iBuilder->SetInsertPoint(pipeline_do_block);
    122 
    123     s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo));
    124 
    125     icGrepInstance->call(basis_bits);
    126     scanMatchInstance->call(results);
    127 
    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);
    131     iBuilder->CreateBr(pipeline_test_block);
    132 
    133     iBuilder->SetInsertPoint(pipeline_final_block);
    134 
    135     Value * empty_block_cond = iBuilder->CreateICmpEQ(remainingBytes, ConstantInt::get(T, 0));
    136     iBuilder->CreateCondBr(empty_block_cond, pipeline_empty_block, pipeline_partial_block);
    137 
    138     iBuilder->SetInsertPoint(pipeline_partial_block);
    139 
    140     s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo));
    141 
    142     iBuilder->CreateBr(pipeline_end_block);
    143 
    144     iBuilder->SetInsertPoint(pipeline_empty_block);
    145 
    146     iBuilder->CreateMemSet(basis_bits, iBuilder->getInt8(0), mBlockSize, 4);
    147     iBuilder->CreateBr(pipeline_end_block);
    148 
    149     iBuilder->SetInsertPoint(pipeline_end_block);
    150 
    151     Value * return_block_cond = iBuilder->CreateICmpEQ(finalLineUnterminated_param, ConstantInt::get(T, 0));
    152     iBuilder->CreateCondBr(return_block_cond, pipeline_return_block, pipeline_Unterminated_block);
     170    iBuilder->SetInsertPoint(endBlock);
     171    Value * isFinalLineUnterminated = iBuilder->CreateICmpEQ(finalLineUnterminated, ConstantInt::get(int64ty, 0));
     172    iBuilder->CreateCondBr(isFinalLineUnterminated, exitBlock, unterminatedBlock);
    153173   
    154     iBuilder->SetInsertPoint(pipeline_Unterminated_block);
     174    iBuilder->SetInsertPoint(unterminatedBlock);
    155175
    156176    Value * remaining = iBuilder->CreateZExt(remainingBytes, iBuilder->getIntNTy(mBlockSize));
     
    158178    EOF_pos = iBuilder->CreateBitCast(EOF_pos, mBitBlockType);
    159179
    160     Value * gep_bits4 = s2pInstance->getOutputStream(4);
    161     Value * bits4 = iBuilder->CreateBlockAlignedLoad(gep_bits4);
    162     bits4 = iBuilder->CreateOr(bits4, EOF_pos);
    163     iBuilder->CreateBlockAlignedStore(bits4, gep_bits4);
    164180
    165     Value * gep_bits6 = s2pInstance->getOutputStream(6);
    166     Value * bits6 = iBuilder->CreateBlockAlignedLoad(gep_bits6);
    167     bits6 = iBuilder->CreateOr(bits6, EOF_pos);
    168     iBuilder->CreateBlockAlignedStore(bits6, gep_bits6);
     181    Value * b4val = iBuilder->CreateBlockAlignedLoad(b4);
     182    b4val = iBuilder->CreateOr(b4val, EOF_pos);
     183    iBuilder->CreateBlockAlignedStore(b4val, b4);
    169184
    170     iBuilder->CreateBr(pipeline_return_block);
     185    Value * b6val = iBuilder->CreateBlockAlignedLoad(b6);
     186    b6val = iBuilder->CreateOr(b6val, EOF_pos);
     187    iBuilder->CreateBlockAlignedStore(b6val, b6);
    171188
    172     iBuilder->SetInsertPoint(pipeline_return_block);
     189    iBuilder->CreateBr(exitBlock);
    173190
    174     icGrepInstance->call(basis_bits);
    175     scanMatchInstance->call(results);
     191    iBuilder->SetInsertPoint(exitBlock);
     192
     193    icGrepInstance->CreateDoBlockCall();
     194    scanMatchInstance->CreateDoBlockCall();
    176195    iBuilder->CreateRetVoid();
    177196
     197    return main;
    178198}
  • icGREP/icgrep-devel/icgrep/kernels/pipeline.h

    r4974 r4986  
    3131
    3232        void CreateKernels(pablo::PabloFunction * function, bool isNameExpression);
    33     void ExecuteKernels();
     33    llvm::Function * ExecuteKernels();
    3434
    3535private:
     
    3939    KernelBuilder *                     mICgrepKernel;   
    4040    KernelBuilder *                     mScanMatchKernel;
    41     llvm::Type*                         mBitBlockType;
     41    llvm::Type *                        mBitBlockType;
    4242    int                                 mBlockSize;
    4343};
  • icGREP/icgrep-devel/icgrep/kernels/s2p_kernel.cpp

    r4976 r4986  
    3131    Value * bit00224466[4];
    3232    Value * bit11335577[4];
    33     for (unsigned i = 0; i<4; i++) {
     33
     34    for (unsigned i = 0; i < 4; i++) {
    3435        Value * s0 = iBuilder->CreateBlockAlignedLoad(input, {iBuilder->getInt32(0), iBuilder->getInt32(2 * i)});
    3536        Value * s1 = iBuilder->CreateBlockAlignedLoad(input, {iBuilder->getInt32(0), iBuilder->getInt32(2 * i + 1)});
     
    5960    kBuilder->prepareFunction();
    6061    Value * output[8];
    61     s2p(iBuilder, kBuilder->getInputStream(0), output);
     62
     63    Value * ptr = kBuilder->getInputStream(0);
     64    //iBuilder->CallPrintInt("ptr", iBuilder->CreatePtrToInt(ptr, iBuilder->getInt64Ty()));
     65    s2p(iBuilder, ptr, output);
    6266    for (unsigned j = 0; j < 8; ++j) {
     67        //iBuilder->CallPrintRegister("bit" + std::to_string(j + 1), output[j]);
    6368        iBuilder->CreateBlockAlignedStore(output[j], kBuilder->getOutputStream(j));
    6469    }
  • icGREP/icgrep-devel/icgrep/kernels/symboltablepipeline.cpp

    r4974 r4986  
    186186    BasicBlock * exitBlock = BasicBlock::Create(mMod->getContext(), "exit", main, 0);
    187187
    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();
     188    Instance * s2pInstance = mS2PKernel->instantiate(inputStream);
     189    Instance * leadingInstance = mLeadingKernel->instantiate(s2pInstance->getOutputStreamSet());
     190    Instance * sortingInstance = mSortingKernel->instantiate(leadingInstance->getOutputStreamSet());
    194191
    195192    const unsigned leadingBlocks = (mLongestLookahead + iBuilder->getBitBlockWidth() - 1) / iBuilder->getBitBlockWidth();
     
    216213    iBuilder->CreateCondBr(leadingBlocksCond, leadingBodyBlock, regularTestBlock);
    217214    iBuilder->SetInsertPoint(leadingBodyBlock);
    218     s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo));
    219     leadingInstance->call(basisBits);
     215    s2pInstance->CreateDoBlockCall();
     216    leadingInstance->CreateDoBlockCall();
    220217    blockNo->addIncoming(iBuilder->CreateAdd(blockNo, iBuilder->getInt64(1)), leadingBodyBlock);
    221218    remainingBytes->addIncoming(iBuilder->CreateSub(remainingBytes, blockSize), leadingBodyBlock);
     
    231228    iBuilder->CreateCondBr(remainingBytesCond, regularBodyBlock, regularExitBlock);
    232229    iBuilder->SetInsertPoint(regularBodyBlock);
    233     s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo2));
    234     leadingInstance->call(basisBits);
    235     sortingInstance->call(leadingData);
     230    s2pInstance->CreateDoBlockCall();
     231    leadingInstance->CreateDoBlockCall();
     232    sortingInstance->CreateDoBlockCall();
    236233    blockNo2->addIncoming(iBuilder->CreateAdd(blockNo2, iBuilder->getInt64(1)), regularBodyBlock);
    237234    remainingBytes2->addIncoming(iBuilder->CreateSub(remainingBytes2, blockSize), regularBodyBlock);
     
    246243    // If we do, process it and mask out the data
    247244    iBuilder->SetInsertPoint(partialBlock);
    248     s2pInstance->call(iBuilder->CreateGEP(inputStream, blockNo2));
     245    s2pInstance->CreateDoBlockCall();
    249246    Value * partialLeadingData[2];
    250247    for (unsigned i = 0; i < 2; ++i) {
    251248        partialLeadingData[i] = leadingInstance->getOutputStream(i);
    252249    }
    253     leadingInstance->call(basisBits);
     250    leadingInstance->CreateDoBlockCall();
    254251    Type * fullBitBlockType = iBuilder->getIntNTy(mBlockSize);
    255252    Value * remaining = iBuilder->CreateZExt(iBuilder->CreateSub(blockSize, remainingBytes2), fullBitBlockType);
     
    263260        iBuilder->CreateBlockAlignedStore(ConstantInt::getNullValue(mBitBlockType), leadingInstance->getOutputStream(i));
    264261    }
    265     sortingInstance->call(leadingData);
     262    sortingInstance->CreateDoBlockCall();
    266263    iBuilder->CreateBr(finalTestBlock);
    267264
     
    283280    iBuilder->CreateStore(blockNoValue, blockNoPtr);
    284281
    285     sortingInstance->call(leadingData);
     282    sortingInstance->CreateDoBlockCall();
    286283
    287284    remainingFullBlocks->addIncoming(iBuilder->CreateSub(remainingFullBlocks, iBuilder->getInt64(1)), finalBodyBlock);
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r4980 r4986  
    5050#include <llvm/IR/Verifier.h>
    5151#endif
    52 
    53 //#include <llvm/PassManager.h>
    54 //#include <llvm/Transforms/IPO/PassManagerBuilder.h>
    55 
    5652#include <hrtime.h>
    57 
    58 static cl::OptionCategory eIRDumpOptions("LLVM IR Dump Options", "These options control dumping of LLVM IR.");
    59 static cl::opt<bool> DumpGeneratedIR("dump-generated-IR", cl::init(false), cl::desc("Print LLVM IR generated by Pablo Compiler."), cl::cat(eIRDumpOptions));
    60 static cl::opt<std::string> IROutputFilename("dump-generated-IR-output", cl::init(""), cl::desc("output IR filename"), cl::cat(eIRDumpOptions));
    61 
    6253
    6354static cl::OptionCategory fTracingOptions("Run-time Tracing Options", "These options control execution traces.");
     
    10798    #endif
    10899
    109     if (LLVM_UNLIKELY(DumpGeneratedIR)) {
    110 
    111         if (IROutputFilename.empty()) {
    112             mMod->dump();
    113         } else {
    114             std::error_code error;
    115             llvm::raw_fd_ostream out(IROutputFilename, error, sys::fs::OpenFlags::F_None);
    116             mMod->print(out, nullptr);
    117         }
    118     }
    119100    return mFunction;
    120101}
     
    138119
    139120    for (unsigned j = 0; j < function->getNumOfParameters(); ++j) {
    140         mMarkerMap.insert(std::make_pair(function->getParameter(j), mKernelBuilder->getInputStream(j)));
     121        Value * inputVal = mKernelBuilder->getInputStream(j);
     122        if (DumpTrace) {
     123            iBuilder->CallPrintRegister("param" + std::to_string(j + 1), iBuilder->CreateBlockAlignedLoad(inputVal));
     124        }
     125        mMarkerMap.insert(std::make_pair(function->getParameter(j), inputVal));
    141126    }
    142127
  • icGREP/icgrep-devel/icgrep/toolchain.cpp

    r4984 r4986  
    4242static cl::alias ShowLineNumbersLong("line-number", cl::desc("Alias for -n"), cl::aliasopt(ShowLineNumbers));
    4343
     44static cl::OptionCategory eIRDumpOptions("LLVM IR Dump Options", "These options control dumping of LLVM IR.");
     45static cl::opt<bool> DumpGeneratedIR("dump-generated-IR", cl::init(false), cl::desc("Print LLVM IR generated by Pablo Compiler."), cl::cat(eIRDumpOptions));
     46static cl::opt<std::string> IROutputFilename("dump-generated-IR-output", cl::init(""), cl::desc("output IR filename"), cl::cat(eIRDumpOptions));
    4447
    4548
     
    4750
    4851
    49 static cl::opt<char> OptLevel("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O0')"),
    50                               cl::cat(cMachineCodeOptimization), cl::Prefix, cl::ZeroOrMore, cl::init('0'));
     52static cl::opt<char> OptLevel("O", cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] (default = '-O1')"),
     53                              cl::cat(cMachineCodeOptimization), cl::Prefix, cl::ZeroOrMore, cl::init('1'));
    5154
    5255
     
    6972    initializeCodeGen(*Registry);
    7073    initializeLowerIntrinsicsPass(*Registry);
     74
     75//    llvm::PassManager pm;
     76//    pm.add(createBasicAliasAnalysisPass());
     77//    pm.add(createEarlyCSEPass());
     78//    pm.add(createPromoteMemoryToRegisterPass());
     79//    pm.add(createInstructionCombiningPass());
     80//    pm.add(createConstantPropagationPass());
     81//    pm.add(createDeadCodeEliminationPass());
     82//    pm.run(*m);
    7183
    7284    std::string errMessage;
     
    8597
    8698    if ((strncmp(lGetSystemISA(), "avx2", 4) == 0)) {
    87             std::vector<std::string> attrs;
    88             attrs.push_back("avx2");
    89             builder.setMAttrs(attrs);
    90     }
    91 
     99        std::vector<std::string> attrs;
     100        attrs.push_back("avx2");
     101        builder.setMAttrs(attrs);
     102    }
    92103    // builder.selectTarget();
    93104
    94     //builder.setOptLevel(mMaxWhileDepth ? CodeGenOpt::Level::Less : CodeGenOpt::Level::None);
     105    if (LLVM_UNLIKELY(DumpGeneratedIR)) {
     106        if (IROutputFilename.empty()) {
     107            m->dump();
     108        } else {
     109            std::error_code error;
     110            llvm::raw_fd_ostream out(IROutputFilename, error, sys::fs::OpenFlags::F_None);
     111            m->print(out, nullptr);
     112        }
     113    }
     114
    95115    ExecutionEngine * engine = builder.create();
    96116    ICGrepObjectCache * cache = nullptr;
     
    229249}
    230250
    231 // extern "C" {
    232 //   void wrapped_print_register(char * regName, BitBlock bit_block) {
    233 //       print_register<BitBlock>(regName, bit_block);
    234 //   }
    235 // }
    236 
    237251void icgrep_Linking(Module * m, ExecutionEngine * e) {
    238252    Module::FunctionListType & fns = m->getFunctionList();
     
    243257        if (fnName == "process_block_initialize_carries") continue;
    244258       
    245         // if (fnName == "wrapped_print_register") {
    246         //     e->addGlobalMapping(cast<GlobalValue>(it), (void *)&wrapped_print_register);
    247         // }
    248259        if (fnName == "wrapped_report_match") {
    249260            e->addGlobalMapping(cast<GlobalValue>(it), (void *)&wrapped_report_match);
Note: See TracChangeset for help on using the changeset viewer.