Changeset 4974 for icGREP


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
Files:
1 added
19 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/CMakeLists.txt

    r4962 r4974  
    99
    1010option(ENABLE_MULTIPLEXING "Compiling the Multiplexing Module")
    11 option(USE_BOOST_MMAP "Using mmap from Boost.Iostreams")
    1211option(ENABLE_PREGENERATED_UCD_FUNCTIONS "Enable compiling the pregenerated UCD functions")
    1312option(PRINT_TIMING_INFORMATION "Write compilation and execution timing information to standard error stream")
     
    5049set(Boost_USE_MULTITHREADED OFF)
    5150set(Boost_USE_STATIC_RUNTIME ON)
    52 SET(REQ_BOOST_COMPONENTS ${REQ_BOOST_COMPONENTS} system)
    53 if(USE_BOOST_MMAP)
    54   SET(REQ_BOOST_COMPONENTS ${REQ_BOOST_COMPONENTS} iostreams filesystem)
    55 endif()
    56 find_package(Boost COMPONENTS ${REQ_BOOST_COMPONENTS} REQUIRED)
     51
     52find_package(Boost 1.46 COMPONENTS system iostreams filesystem REQUIRED)
    5753
    5854SET(PABLO_SRC pablo/pabloAST.cpp pablo/ps_if.cpp pablo/ps_while.cpp pablo/function.cpp pablo/codegenstate.cpp pablo/builder.cpp pablo/symbol_generator.cpp pablo/printer_pablos.cpp)
     
    126122
    127123target_link_libraries (icgrep UCDlib PabloADT RegExpCompiler CCADT ${REQ_LLVM_LIBRARIES})
    128 
    129 IF(USE_BOOST_MMAP)
    130   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUSE_BOOST_MMAP")
    131 ENDIF()
    132 
    133124
    134125IF(ENABLE_MULTIPLEXING)
  • icGREP/icgrep-devel/icgrep/IDISA/idisa_builder.cpp

    r4957 r4974  
    1111#include <llvm/IR/Function.h>
    1212#include <llvm/IR/TypeBuilder.h>
     13#include <llvm/Support/raw_ostream.h>
    1314
    1415namespace IDISA {
     
    3435}
    3536
    36 static Function *create_printf(LLVMContext &ctx, Module *mod) {
    37 
    38   FunctionType *printf_type =
    39       TypeBuilder<int(char *, ...), false>::get(getGlobalContext());
    40 
    41   Function *func = cast<Function>(mod->getOrInsertFunction(
    42       "printf", printf_type,
    43       AttributeSet().addAttribute(mod->getContext(), 1U, Attribute::NoAlias)));
    44 
    45   return func;
    46 }
    47 
    48 void IDISA_Builder::genPrintRegister(std::string regName, Value * bitblockValue) {
    49     Function *printf_func = create_printf(mMod->getContext(), mMod);
    50     Type * printType = VectorType::get(getIntNTy(8), mBitBlockWidth/8);
    51     Value * val = CreateBitCast(bitblockValue, printType);
    52     std::vector<Value *> args;
    53     std::string str = regName;
    54     for (unsigned int i = 0; i < 40 - regName.length(); i++) str += " ";
    55     str += "= %02X";
    56     for (unsigned int i=0; i<mBitBlockWidth/8-1; i++)
    57         str += " %02X";
    58     str += "\n";
    59     args.push_back(geti8StrVal(*mMod, str.c_str(), regName));
    60     for(unsigned int i=0; i<mBitBlockWidth/8; i++)
    61         args.push_back(CreateExtractElement(val, ConstantInt::get(getIntNTy(32), i)));
    62     args.push_back(val);
    63     CreateCall(printf_func, args);
     37static Function * create_printf(Module * const mod) {
     38    Function * printf = mod->getFunction("printf");
     39    if (printf == nullptr) {
     40        FunctionType *printf_type =
     41            TypeBuilder<int(char *, ...), false>::get(mod->getContext());
     42        printf = cast<Function>(mod->getOrInsertFunction("printf", printf_type,
     43            AttributeSet().addAttribute(mod->getContext(), 1U, Attribute::NoAlias)));
     44    }
     45    return printf;
     46}
     47
     48void IDISA_Builder::CallPrintRegister(const std::string & name, Value * const value) {
     49    Constant * printRegister = mMod->getFunction("PrintRegister");
     50    if (LLVM_UNLIKELY(printRegister == nullptr)) {
     51        FunctionType *FT = FunctionType::get(getVoidTy(), { PointerType::get(getInt8Ty(), 0), mBitBlockType }, false);
     52        Function * function = Function::Create(FT, Function::InternalLinkage, "PrintRegister", mMod);
     53        auto arg = function->arg_begin();
     54        std::string tmp;
     55        raw_string_ostream out(tmp);
     56        out << "%-40s =";
     57        for(unsigned i = 0; i < (mBitBlockWidth / 8); ++i) {
     58            out << " %02x";
     59        }
     60        out << '\n';
     61        BasicBlock * entry = BasicBlock::Create(mMod->getContext(), "entry", function);
     62        IRBuilder<> builder(entry);
     63        std::vector<Value *> args;
     64        args.push_back(geti8StrVal(*mMod, out.str().c_str(), ""));
     65        Value * const name = arg++;
     66        name->setName("name");
     67        args.push_back(name);
     68        Value * value = arg;
     69        value->setName("value");
     70        Type * const byteVectorType = VectorType::get(getInt8Ty(), (mBitBlockWidth / 8));
     71        value = builder.CreateBitCast(value, byteVectorType);
     72        for(unsigned i = (mBitBlockWidth / 8); i != 0; --i) {
     73            args.push_back(builder.CreateExtractElement(value, builder.getInt32(i - 1)));
     74        }
     75        builder.CreateCall(create_printf(mMod), args);
     76        builder.CreateRetVoid();
     77
     78        printRegister = function;
     79    }
     80    CreateCall2(printRegister, geti8StrVal(*mMod, name.c_str(), name), CreateBitCast(value, mBitBlockType));
    6481}
    6582
  • icGREP/icgrep-devel/icgrep/IDISA/idisa_builder.h

    r4968 r4974  
    2020public:
    2121
    22     IDISA_Builder(Module * m, Type * bitBlockType) : IRBuilder<>(m->getContext())
     22    IDISA_Builder(Module * m, Type * bitBlockType)
     23    : IRBuilder<>(m->getContext())
    2324    , mMod(m)
    2425    , mBitBlockType(bitBlockType)
     
    2930
    3031    }
     32
    3133    virtual ~IDISA_Builder() {}
    3234   
    33     Type * getBitBlockType() { return mBitBlockType;}
    34     Value * bitCast(Value * a) {return a->getType() == mBitBlockType ? a : CreateBitCast(a, mBitBlockType);}
    35     int getBitBlockWidth() { return mBitBlockWidth;}
    36     Module * getModule() {return mMod;}
    37     void genPrintRegister(std::string regName, Value * bitblockValue);
     35    Type * getBitBlockType() const {
     36        return mBitBlockType;
     37    }
     38
     39    Value * bitCast(Value * a) {
     40        return a->getType() == mBitBlockType ? a : CreateBitCast(a, mBitBlockType);
     41    }
     42
     43    unsigned getBitBlockWidth() const {
     44        return mBitBlockWidth;
     45    }
     46
     47    Module * getModule() const {
     48        return mMod;
     49    }
    3850   
    39    
    40     Constant * allZeroes() {return mZeroInitializer;}
    41     Constant * allOnes() {return mOneInitializer;}
    42     Constant * simd_himask(unsigned fw);
    43     Constant * simd_lomask(unsigned fw);
    44        
     51    Constant * allZeroes() const {
     52        return mZeroInitializer;
     53    }
     54
     55    Constant * allOnes() const {
     56        return mOneInitializer;
     57    }
     58
    4559    LoadInst * CreateBlockAlignedLoad(Value * const ptr);
    4660    LoadInst * CreateBlockAlignedLoad(Value * const ptr, Value * const index);
    4761    LoadInst * CreateBlockAlignedLoad(Value * const ptr, std::initializer_list<Value *> indicies);
     62
    4863    void CreateBlockAlignedStore(Value * const value, Value * const ptr);
    4964    void CreateBlockAlignedStore(Value * const value, Value * const ptr, Value * const index);
    5065    void CreateBlockAlignedStore(Value * const value, Value * const ptr, std::initializer_list<Value *> indicies);
     66
     67    void CallPrintRegister(const std::string & regName, Value * const value);
     68
     69    Constant * simd_himask(unsigned fw);
     70    Constant * simd_lomask(unsigned fw);
    5171
    5272    virtual Value * simd_add(unsigned fw, Value * a, Value * b);
  • icGREP/icgrep-devel/icgrep/grep_engine.cpp

    r4969 r4974  
    3838
    3939// mmap system
    40 #ifdef USE_BOOST_MMAP
    4140#include <boost/filesystem.hpp>
    4241#include <boost/iostreams/device/mapped_file.hpp>
    4342using namespace boost::iostreams;
    4443using namespace boost::filesystem;
    45 #else
    46 #include <sys/mman.h>
    47 #endif
     44
    4845#include <fcntl.h>
    4946
     
    7370    char * mFileBuffer;
    7471
    75 #ifdef USE_BOOST_MMAP
    7672    const path file(mFileName);
    7773    if (exists(file)) {
     
    9894        mFileBuffer = mFile.data();
    9995    }
    100 #else
    101     struct stat infile_sb;
    102     const int fdSrc = open(mFileName.c_str(), O_RDONLY);
    103     if (fdSrc == -1) {
    104         std::cerr << "Error: cannot open " << mFileName << " for processing. Skipped.\n";
    105         return;
    106     }
    107     if (fstat(fdSrc, &infile_sb) == -1) {
    108         std::cerr << "Error: cannot stat " << mFileName << " for processing. Skipped.\n";
    109         close (fdSrc);
    110         return;
    111     }
    112     if (S_ISDIR(infile_sb.st_mode)) {
    113         close (fdSrc);
    114         return;
    115     }
    116     mFileSize = infile_sb.st_size;
    117     if (mFileSize == 0) {
    118         mFileBuffer = nullptr;
    119     }
    120     else {
    121         mFileBuffer = (char *) mmap(NULL, mFileSize, PROT_READ, MAP_PRIVATE, fdSrc, 0);
    122         if (mFileBuffer == MAP_FAILED) {
    123             if (errno ==  ENOMEM) {
    124                 std::cerr << "Error:  mmap of " << mFileName << " failed: out of memory\n";
    125                 close (fdSrc);
    126             }
    127             else {
    128                 std::cerr << "Error: mmap of " << mFileName << " failed with errno " << errno << ". Skipped.\n";
    129                 close (fdSrc);
    130             }
    131             return;
    132         }
    133     }
    134     close(fdSrc);
    135 
    136 #endif
    13796   
    13897    uint64_t finalLineUnterminated = 0;
     
    142101    mMainFcn(mFileBuffer, mFileSize, mFileName.c_str(), finalLineUnterminated);
    143102
    144 #ifdef USE_BOOST_MMAP
     103
    145104    mFile.close();
    146 #else
    147     munmap((void *)mFileBuffer, mFileSize);
    148 #endif
    149105
    150106}
     
    157113    IDISA::IDISA_Builder * idb = GetIDISA_Builder(M);
    158114
    159     PipelineBuilder pipelineBuilder(M, idb);
     115    kernel::PipelineBuilder pipelineBuilder(M, idb);
    160116
    161117    Encoding encoding(Encoding::Type::UTF_8, 8);
     
    182138
    183139re::CC *  GrepEngine::grepCodepoints() {
     140
    184141    setParsedCodePointSet();
    185142    char * mFileBuffer = getUnicodeNameDataPtr();
  • icGREP/icgrep-devel/icgrep/icgrep-devel.files

    r4968 r4974  
    700700IDISA/idisa_i64_builder.cpp
    701701IDISA/idisa_i64_builder.h
     702kernels/instance.h
  • 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
  • icGREP/icgrep-devel/icgrep/pablo/carry_manager.cpp

    r4970 r4974  
    2222 * @brief initialize
    2323 ** ------------------------------------------------------------------------------------------------------------- */
    24 void CarryManager::initialize(PabloFunction * const function, KernelBuilder * const kBuilder) {
     24void CarryManager::initialize(PabloFunction * const function, kernel::KernelBuilder * const kBuilder) {
    2525    mRootScope = function->getEntryBlock();
    2626    mCarryInfoVector.resize(mRootScope->enumerateScopes(0) + 1);
     
    2828    const unsigned totalCarryDataSize = std::max<unsigned>(enumerate(mRootScope, 0, 0), 1);
    2929    mCarryPackPtr.resize(totalCarryDataSize, nullptr);
    30     mCarryInPack.resize(totalCarryDataSize);
     30    mCarryInPack.resize(totalCarryDataSize, nullptr);
    3131    mCarryOutPack.resize(totalCarryDataSize, nullptr);
    3232    mTotalCarryDataBitBlocks = totalCarryDataSize;
     
    5656    mCarryOutPack[summaryPack()] = Constant::getNullValue(mCarryPackType);
    5757    assert (mCarrySummary.empty());
    58     std::fill(mCarryInPack.begin(), mCarryInPack.end(), nullptr);
    5958}
    6059
     
    153152        storeCarryOut(index);
    154153    }
    155     if (LLVM_LIKELY(shiftAmount == 1)) {
    156         Value * ahead = iBuilder->mvmd_dslli(DSSLI_FIELDWIDTH, value, carryIn, iBuilder->getBitBlockWidth()/DSSLI_FIELDWIDTH -1);
    157         result = iBuilder->simd_or(iBuilder->simd_srli(DSSLI_FIELDWIDTH, ahead, DSSLI_FIELDWIDTH-1), iBuilder->simd_slli(DSSLI_FIELDWIDTH, value, 1));
    158     } else if (shiftAmount % 8 == 0) { // Use a single whole-byte shift, if possible.
     154    if (LLVM_UNLIKELY((shiftAmount % 8) == 0)) { // Use a single whole-byte shift, if possible.
    159155        result = iBuilder->mvmd_dslli(8, value, carryIn, (iBuilder->getBitBlockWidth() / 8) - (shiftAmount / 8));
    160     } else if (shiftAmount < DSSLI_FIELDWIDTH) {
    161         Value * ahead = iBuilder->mvmd_dslli(DSSLI_FIELDWIDTH, value, carryIn, iBuilder->getBitBlockWidth()/DSSLI_FIELDWIDTH - 1);
    162         result = iBuilder->simd_or(iBuilder->simd_srli(DSSLI_FIELDWIDTH, ahead, DSSLI_FIELDWIDTH-shiftAmount), iBuilder->simd_slli(DSSLI_FIELDWIDTH, value, shiftAmount));
     156    } else if (LLVM_LIKELY(shiftAmount < DSSLI_FIELDWIDTH)) {
     157        Value * ahead = iBuilder->mvmd_dslli(DSSLI_FIELDWIDTH, value, carryIn, iBuilder->getBitBlockWidth() / DSSLI_FIELDWIDTH - 1);
     158        result = iBuilder->simd_or(iBuilder->simd_srli(DSSLI_FIELDWIDTH, ahead, DSSLI_FIELDWIDTH - shiftAmount), iBuilder->simd_slli(DSSLI_FIELDWIDTH, value, shiftAmount));
    163159    } else {
    164160        Value* advanceq_longint = iBuilder->CreateBitCast(carryIn, iBuilder->getIntNTy(mBitBlockWidth));
     
    196192    const unsigned bufsize = mCarryInfo->longAdvanceBufferSize(shiftAmount);
    197193    Value * indexMask = iBuilder->getInt64(bufsize - 1);  // A mask to implement circular buffer indexing
    198     Value * blockIndex = iBuilder->CreateBlockAlignedLoad(mKernelBuilder->getBlockIndexScalar());
     194    Value * blockIndex = iBuilder->CreateBlockAlignedLoad(mKernelBuilder->getBlockNo());
    199195    Value * loadIndex0 = iBuilder->CreateAdd(iBuilder->CreateAnd(iBuilder->CreateSub(blockIndex, iBuilder->getInt64(advanceEntries)), indexMask), advBaseIndex);
    200196    Value * storeIndex = iBuilder->CreateAdd(iBuilder->CreateAnd(blockIndex, indexMask), advBaseIndex);
  • icGREP/icgrep-devel/icgrep/pablo/carry_manager.h

    r4970 r4974  
    5959    ~CarryManager();
    6060   
    61     void initialize(PabloFunction * const function, KernelBuilder * const kBuilder);
     61    void initialize(PabloFunction * const function, kernel::KernelBuilder * const kBuilder);
    6262
    6363    void reset();
     
    140140    Value * mCarryBitBlockPtr;
    141141    Value * mPopcountBasePtr;
    142     KernelBuilder * mKernelBuilder;
     142    kernel::KernelBuilder * mKernelBuilder;
    143143    unsigned mPabloCountCount; // Number of Pablo "Count" operations
    144144    unsigned mTotalCarryDataBitBlocks;
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r4970 r4974  
    6666namespace pablo {
    6767
     68#define DSSLI_FIELDWIDTH 64
     69
    6870PabloCompiler::PabloCompiler(Module * m, IDISA::IDISA_Builder * b)
    6971: mMod(m)
     
    8183}
    8284
    83 void PabloCompiler::setKernel(KernelBuilder * kBuilder){
     85void PabloCompiler::setKernel(kernel::KernelBuilder * kBuilder){
    8486    mKernelBuilder = kBuilder;
    8587}
     
    131133    mCarryManager->initialize(function, mKernelBuilder);
    132134
    133     mKernelBuilder->prepareFunction();
    134 
    135     mFunction = mKernelBuilder->getDoBlockFunction();
    136 
    137     for(unsigned i = 0; i < mKernelBuilder->getSegmentBlocks(); ++i){
    138 
    139         mCarryManager->reset();
    140 
    141         for (unsigned j = 0; j < function->getNumOfParameters(); ++j) {
    142             mMarkerMap.insert(std::make_pair(function->getParameter(j), mKernelBuilder->getInputStream(j)));
    143         }
    144 
    145         compileBlock(function->getEntryBlock());
    146 
    147         for (unsigned j = 0; j < function->getNumOfResults(); ++j) {
    148             const auto f = mMarkerMap.find(function->getResult(j));
    149             Value * result = nullptr;
    150             if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
    151                 result = iBuilder->allZeroes();
    152             } else {
    153                 result = f->second;
    154             }
    155             iBuilder->CreateBlockAlignedStore(result, mKernelBuilder->getOutputStream(j));
    156         }
    157 
    158         mMarkerMap.clear();
    159 
    160         mKernelBuilder->increment();
    161     }   
     135    mFunction = mKernelBuilder->prepareFunction();
     136
     137    mCarryManager->reset();
     138
     139    for (unsigned j = 0; j < function->getNumOfParameters(); ++j) {
     140        mMarkerMap.insert(std::make_pair(function->getParameter(j), mKernelBuilder->getInputStream(j)));
     141    }
     142
     143    compileBlock(function->getEntryBlock());
     144
     145    for (unsigned j = 0; j < function->getNumOfResults(); ++j) {
     146        const auto f = mMarkerMap.find(function->getResult(j));
     147        Value * result = nullptr;
     148        if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
     149            result = iBuilder->allZeroes();
     150        } else {
     151            result = f->second;
     152        }
     153        iBuilder->CreateBlockAlignedStore(result, mKernelBuilder->getOutputStream(j));
     154    }
    162155
    163156    mKernelBuilder->finalize();
     
    414407            throw std::runtime_error("Lookahead input type must be a Var object");
    415408        }
    416         Value * index = nullptr;
    417         for (unsigned i = 0; i < mPabloFunction->getNumOfParameters(); ++i) {
    418             if (mPabloFunction->getParameter(i) == var) {
    419                 index = iBuilder->getInt32(i);
     409        unsigned index = 0;
     410        for (; index < mPabloFunction->getNumOfParameters(); ++index) {
     411            if (mPabloFunction->getParameter(index) == var) {
    420412                break;
    421413            }
    422414        }
    423         if (LLVM_UNLIKELY(index == nullptr)) {
     415        if (LLVM_UNLIKELY(index >= mPabloFunction->getNumOfParameters())) {
    424416            throw std::runtime_error("Lookahead has an illegal Var operand");
    425417        }
    426         Type * const streamType = iBuilder->getIntNTy(iBuilder->getBitBlockWidth());
    427418        const unsigned offset = l->getAmount() / iBuilder->getBitBlockWidth();
    428419        const unsigned shift = (l->getAmount() % iBuilder->getBitBlockWidth());
    429         Value * const b0 = iBuilder->CreateBitCast(iBuilder->CreateBlockAlignedLoad(mKernelBuilder->getInputStream(offset), index), streamType);
    430         Value * const b1 = iBuilder->CreateBitCast(iBuilder->CreateBlockAlignedLoad(mKernelBuilder->getInputStream(offset + 1), index), streamType);
    431         Value * result = iBuilder->CreateOr(iBuilder->CreateLShr(b0, shift), iBuilder->CreateShl(b1, iBuilder->getBitBlockWidth() - shift), "lookahead");
    432         expr = iBuilder->CreateBitCast(result, iBuilder->getBitBlockType());
     420        Value * const v0 = iBuilder->CreateBlockAlignedLoad(mKernelBuilder->getInputStream(index, offset));
     421        Value * const v1 = iBuilder->CreateBlockAlignedLoad(mKernelBuilder->getInputStream(index, offset + 1));
     422        if (LLVM_UNLIKELY((shift % 8) == 0)) { // Use a single whole-byte shift, if possible.
     423            expr = iBuilder->mvmd_dslli(8, v1, v0, (shift / 8));
     424        } else if (LLVM_LIKELY(shift < DSSLI_FIELDWIDTH)) {
     425            Value * ahead = iBuilder->mvmd_dslli(DSSLI_FIELDWIDTH, v1, v0, 1);
     426            ahead = iBuilder->simd_slli(DSSLI_FIELDWIDTH, ahead, DSSLI_FIELDWIDTH - shift);
     427            Value * value = iBuilder->simd_srli(DSSLI_FIELDWIDTH, v0, shift);
     428            expr = iBuilder->simd_or(value, ahead);
     429        } else {
     430            Type  * const streamType = iBuilder->getIntNTy(iBuilder->getBitBlockWidth());
     431            Value * b0 = iBuilder->CreateBitCast(v0, streamType);
     432            Value * b1 = iBuilder->CreateBitCast(v1, streamType);
     433            Value * result = iBuilder->CreateOr(iBuilder->CreateShl(b1, iBuilder->getBitBlockWidth() - shift), iBuilder->CreateLShr(b0, shift));
     434            expr = iBuilder->CreateBitCast(result, mBitBlockType);
     435        }
    433436    } else {
    434437        std::string tmp;
     
    441444    mMarkerMap[stmt] = expr;
    442445    if (DumpTrace) {
    443         iBuilder->genPrintRegister(stmt->getName()->to_string(), expr);
     446        iBuilder->CallPrintRegister(stmt->getName()->to_string(), expr);
    444447    }
    445448   
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.h

    r4970 r4974  
    5151
    5252    llvm::Function * compile(PabloFunction * function);
    53     void setKernel(KernelBuilder * kBuilder);
     53    void setKernel(kernel::KernelBuilder * kBuilder);
    5454
    5555private:
     
    7676    const PabloBlock *                  mPabloBlock;
    7777
    78     KernelBuilder *                     mKernelBuilder;
     78    kernel::KernelBuilder *             mKernelBuilder;
    7979
    8080    unsigned                            mWhileDepth;
Note: See TracChangeset for help on using the changeset viewer.