Ignore:
Timestamp:
Jun 19, 2016, 3:00:47 PM (3 years ago)
Author:
cameron
Message:

New kernel infrastructure

Location:
icGREP/icgrep-devel/icgrep/pablo
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/pablo/carry_manager.cpp

    r5058 r5063  
    2020
    2121/** ------------------------------------------------------------------------------------------------------------- *
    22  * @brief initialize
    23  ** ------------------------------------------------------------------------------------------------------------- */
    24 void CarryManager::initialize(PabloFunction * const function, kernel::KernelBuilder * const kBuilder) {
     22 * @brief initializeCarryData
     23 ** ------------------------------------------------------------------------------------------------------------- */
     24Type * CarryManager::initializeCarryData(PabloFunction * const function) {
    2525    mRootScope = function->getEntryBlock();
    2626    mCarryInfoVector.resize(mRootScope->enumerateScopes(0) + 1);
     
    3434    mTotalCarryDataBitBlocks = totalCarryDataSize;
    3535    ArrayType* cdArrayTy = ArrayType::get(mBitBlockType, mTotalCarryDataBitBlocks);
    36     mCdArrayIdx = kBuilder->addInternalState(cdArrayTy);
    37     if (mPabloCountCount > 0) {
    38         ArrayType* pcArrayTy = ArrayType::get(iBuilder->getIntNTy(64), mPabloCountCount);
    39         mPcArrayIdx = kBuilder->addInternalState(pcArrayTy);
    40     }
     36    return cdArrayTy;
     37}
     38
     39/** ------------------------------------------------------------------------------------------------------------- *
     40 * @brief initializeCodeGen
     41 ** ------------------------------------------------------------------------------------------------------------- */
     42void CarryManager::initializeCodeGen(PabloKernel * const kBuilder, Value * selfPtr) {
    4143    mKernelBuilder = kBuilder;
    42 }
    43 
    44 /** ------------------------------------------------------------------------------------------------------------- *
    45  * @brief reset
    46  ** ------------------------------------------------------------------------------------------------------------- */
    47 void CarryManager::reset() {
    48     Value * cdArrayPtr = mKernelBuilder->getInternalState(mCdArrayIdx);
     44    mSelf = selfPtr;
     45   
     46    Value * cdArrayPtr = iBuilder->CreateGEP(mSelf, {iBuilder->getInt64(0), mKernelBuilder->getScalarIndex("carries")});
     47#ifndef NDEBUG
     48    iBuilder->CallPrintInt("cdArrayPtr", iBuilder->CreatePtrToInt(cdArrayPtr, iBuilder->getInt64Ty()));
     49#endif
    4950    mCarryPackBasePtr = iBuilder->CreateBitCast(cdArrayPtr, PointerType::get(mCarryPackType, 0));
    5051    mCarryBitBlockPtr = iBuilder->CreateBitCast(cdArrayPtr, PointerType::get(mBitBlockType, 0));
    51     if (mPabloCountCount > 0) {
    52         Value * pcArrayPtr = mKernelBuilder->getInternalState(mPcArrayIdx);
    53         mPopcountBasePtr = iBuilder->CreateBitCast(pcArrayPtr, Type::getInt64PtrTy(iBuilder->getContext()));
    54     }
    5552    mCurrentScope = mRootScope;
    5653    mCurrentFrameIndex = 0;
     
    201198    const unsigned bufsize = mCarryInfo->longAdvanceBufferSize(shiftAmount);
    202199    Value * indexMask = iBuilder->getInt64(bufsize - 1);  // A mask to implement circular buffer indexing
    203     Value * blockIndex = iBuilder->CreateBlockAlignedLoad(mKernelBuilder->getBlockNo());
     200    Value * blockIndex = mKernelBuilder->getScalarField(mSelf, "BlockNo");
    204201    Value * loadIndex0 = iBuilder->CreateAdd(iBuilder->CreateAnd(iBuilder->CreateSub(blockIndex, iBuilder->getInt64(advanceEntries)), indexMask), advBaseIndex);
    205202    Value * storeIndex = iBuilder->CreateAdd(iBuilder->CreateAnd(blockIndex, indexMask), advBaseIndex);
     
    243240        storeCarryOut(carrySummaryIndex);
    244241    }
    245 }
    246 
    247 /** ------------------------------------------------------------------------------------------------------------- *
    248  * @brief popCount
    249  ** ------------------------------------------------------------------------------------------------------------- */
    250 Value * CarryManager::popCount(Value * to_count, unsigned globalIdx) {
    251     Value * countPtr = iBuilder->CreateGEP(mPopcountBasePtr, iBuilder->getInt64(globalIdx));
    252     Value * countSoFar = iBuilder->CreateAlignedLoad(countPtr, 8);
    253     Value * fieldCounts = iBuilder->simd_popcount(64, to_count);
    254     for (unsigned i = 0; i < mBitBlockWidth/64; ++i) {
    255         countSoFar = iBuilder->CreateAdd(countSoFar, iBuilder->mvmd_extract(64, fieldCounts, i));
    256     }
    257     iBuilder->CreateAlignedStore(countSoFar, countPtr, 8);
    258     return iBuilder->bitCast(iBuilder->CreateZExt(countSoFar, iBuilder->getIntNTy(mBitBlockWidth)));
    259242}
    260243
     
    407390
    408391    for (Statement * stmt : *blk) {
    409         if (Count * c = dyn_cast<Count>(stmt)) {
    410             c->setGlobalCountIndex(mPabloCountCount);
    411             mPabloCountCount++;
    412         } else if (If * ifStatement = dyn_cast<If>(stmt)) {
     392        if (If * ifStatement = dyn_cast<If>(stmt)) {
    413393            const unsigned ifCarryDataBits = enumerate(ifStatement->getBody(), ifDepth + 1, whileDepth);
    414394            CarryData * nestedBlockData = mCarryInfoVector[ifStatement->getBody()->getScopeIndex()];
  • icGREP/icgrep-devel/icgrep/pablo/carry_manager.h

    r4974 r5063  
    1010#include <llvm/IR/Module.h>
    1111#include <IDISA/idisa_builder.h>
     12#include <pablo/pablo_kernel.h>
    1213#include <pablo/codegenstate.h>
    1314#include <pablo/carry_data.h>
     
    3940    CarryManager(IDISA::IDISA_Builder * idb)
    4041    : iBuilder(idb)
     42    , mKernelBuilder(nullptr)
     43    , mSelf(nullptr)
    4144    , mBitBlockType(idb->getBitBlockType())
    4245    , mBitBlockWidth(idb->getBitBlockWidth())
     
    4750    , mCarryPackBasePtr(nullptr)
    4851    , mCarryBitBlockPtr(nullptr)
    49     , mPopcountBasePtr(nullptr)
    50     , mKernelBuilder(nullptr)
    51     , mPabloCountCount(0)
    5252    , mTotalCarryDataBitBlocks(0)
    5353    , mCarryDataAllocationSize(0)
     
    5959    ~CarryManager();
    6060   
    61     void initialize(PabloFunction * const function, kernel::KernelBuilder * const kBuilder);
     61    Type * initializeCarryData(PabloFunction * const function);
     62    void initializeCodeGen(PabloKernel * const kBuilder, Value * selfPtr);
    6263
    6364    void reset();
     
    9899    void ensureCarriesStoredRecursive();
    99100   
    100     Value * popCount(Value * to_count, unsigned globalIdx);
    101    
    102101    Value * declareCarryDataArray(Module * m);
    103102
     
    130129private:
    131130    IDISA::IDISA_Builder * const iBuilder;
     131    PabloKernel * mKernelBuilder;
     132    Value * mSelf;
    132133    Type * const mBitBlockType;
    133134    const unsigned mBitBlockWidth;
     
    139140    Type * mCarryPackType;
    140141    Value * mCarryBitBlockPtr;
    141     Value * mPopcountBasePtr;
    142     kernel::KernelBuilder * mKernelBuilder;
    143     unsigned mPabloCountCount; // Number of Pablo "Count" operations
    144142    unsigned mTotalCarryDataBitBlocks;
    145143    unsigned mCarryDataAllocationSize;
     
    152150    std::vector<Value *> mCarrySummary;
    153151    int mCdArrayIdx;
    154     int mPcArrayIdx;
    155152    int mFilePosIdx;
    156153};
  • icGREP/icgrep-devel/icgrep/pablo/codegenstate.cpp

    r5061 r5063  
    7676    return insertAtInsertionPoint(new Advance(expr, getInteger(shiftAmount), makeName(prefix, false)));
    7777}
     78
     79Count * PabloBlock::createCount(const std::string counterName, PabloAST * const expr)  {
     80    return insertAtInsertionPoint(new Count(expr, makeName(counterName, false)));
     81}
     82   
    7883
    7984PabloAST * PabloBlock::createLookahead(PabloAST * expr, PabloAST * shiftAmount) {
  • icGREP/icgrep-devel/icgrep/pablo/function.h

    r4876 r5063  
    55#include <pablo/pe_var.h>
    66#include <pablo/ps_assign.h>
     7#include <pablo/pe_count.h>
    78#include <pablo/symbol_generator.h>
    89
     
    139140    }
    140141
     142    void setResultCount(Count * value) {
     143        value->addUser(this);
     144    }
     145   
    141146    void setFunctionPtr(void * functionPtr) {
    142147        mFunctionPtr = functionPtr;
  • icGREP/icgrep-devel/icgrep/pablo/pabloAST.h

    r5042 r5063  
    3636    friend class PabloFunction;
    3737    friend class SymbolGenerator;
     38    friend class Count;
    3839public:
    3940
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r5045 r5063  
    1919#include <iostream>
    2020#include <hrtime.h>
     21#include <llvm/Support/Debug.h>
    2122
    2223
     
    2526#define DSSLI_FIELDWIDTH 64
    2627
    27 PabloCompiler::PabloCompiler(Module * m, IDISA::IDISA_Builder * b)
    28 : mMod(m)
     28PabloCompiler::PabloCompiler(IDISA::IDISA_Builder * b, PabloKernel * k, PabloFunction * const function)
     29: mMod(b->getModule())
    2930, iBuilder(b)
    3031, mBitBlockType(b->getBitBlockType())
    3132, mCarryManager(nullptr)
    32 , mPabloFunction(nullptr)
     33, mPabloFunction(function)
    3334, mPabloBlock(nullptr)
    34 , mKernelBuilder(nullptr)
     35, mKernelBuilder(k)
    3536, mWhileDepth(0)
    3637, mIfDepth(0)
     
    4041}
    4142
    42 void PabloCompiler::setKernel(kernel::KernelBuilder * kBuilder){
    43     mKernelBuilder = kBuilder;
    44 }
    45 
    46 llvm::Function * PabloCompiler::compile(PabloFunction * function) {
    47 
     43
     44Type * PabloCompiler::initializeCarryData() {
     45    mCarryManager = make_unique<CarryManager>(iBuilder);
     46    Type * carryDataType = mCarryManager->initializeCarryData(mPabloFunction);
     47    return carryDataType;
     48}
     49   
     50void PabloCompiler::compile(Function * doBlockFunction) {
     51    // Make sure that we generate code into the right module.
     52    mMod = iBuilder->getModule();
     53    mFunction = doBlockFunction;
    4854    #ifdef PRINT_TIMING_INFORMATION
    4955    const timestamp_t pablo_compilation_start = read_cycle_counter();
    5056    #endif
    51  
    52     Examine(function);
    53 
    54     mCarryManager = new CarryManager(iBuilder);
    55 
    56     GenerateKernel(function);
    57        
    58     delete mCarryManager;
    59     mCarryManager = nullptr;
     57
     58    Examine(mPabloFunction);
     59   
     60    //Generate Kernel//
     61    iBuilder->SetInsertPoint(BasicBlock::Create(iBuilder->getContext(), "entry", doBlockFunction, 0));
     62    mSelf = mKernelBuilder->getParameter(doBlockFunction, "self");
     63    mCarryManager->initializeCodeGen(mKernelBuilder, mSelf);
     64     
     65    Value * inputSet_ptr = mKernelBuilder->getParameter(doBlockFunction, "inputs");
     66   
     67    Value * outputSet_ptr = nullptr;
     68    if (mPabloFunction->getNumOfResults() > 0) {
     69        outputSet_ptr = mKernelBuilder->getParameter(doBlockFunction, "outputs");
     70    }
     71    for (unsigned j = 0; j < mPabloFunction->getNumOfParameters(); ++j) {
     72        Value * inputVal = iBuilder->CreateGEP(inputSet_ptr, {iBuilder->getInt32(0), iBuilder->getInt32(j)});
     73        //Value * inputVal = iBuilder->CreateBlockAlignedLoad(inputSet_ptr, {iBuilder->getInt32(0), iBuilder->getInt32(j)});
     74        const Var * const var = mPabloFunction->getParameter(j);
     75        if (DebugOptionIsSet(DumpTrace)) {
     76            iBuilder->CallPrintRegister(var->getName()->to_string(), iBuilder->CreateBlockAlignedLoad(inputVal));
     77        }
     78        mMarkerMap.insert(std::make_pair(var, inputVal));
     79    }
     80   
     81    compileBlock(mPabloFunction->getEntryBlock());
     82   
     83    for (unsigned j = 0; j < mPabloFunction->getNumOfResults(); ++j) {
     84        const auto f = mMarkerMap.find(mPabloFunction->getResult(j));
     85        if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
     86            throw std::runtime_error("PabloCompiler: result " + std::to_string(j) + " was not assigned a value!");
     87        }
     88        iBuilder->CreateBlockAlignedStore(f->second, outputSet_ptr, {iBuilder->getInt32(0), iBuilder->getInt32(j)});
     89    }
     90    iBuilder->CreateRetVoid();
     91
    6092   
    6193    #ifdef PRINT_TIMING_INFORMATION
     
    6496    #endif
    6597
    66     return mFunction;
    67 }
    68 
    69 inline void PabloCompiler::GenerateKernel(PabloFunction * const function) {
    70  
    71     mPabloFunction = function;
    72 
    73     for (unsigned i = 0; i < function->getNumOfParameters(); ++i) {
    74         mKernelBuilder->addInputStream(1, function->getParameter(i)->getName()->to_string());
    75     }
    76     for (unsigned i = 0; i < function->getNumOfResults(); ++i) {
    77         mKernelBuilder->addOutputStream(1);
    78     }
    79 
    80     mCarryManager->initialize(function, mKernelBuilder);
    81    
    82     mKernelBuilder->addInternalState(mBitBlockType, "EOFmark");
    83    
    84     mFunction = mKernelBuilder->prepareFunction({mInputStreamOffset.begin(), mInputStreamOffset.end()});
    85 
    86     mCarryManager->reset();
    87 
    88     for (unsigned j = 0; j < function->getNumOfParameters(); ++j) {
    89         Value * inputVal = mKernelBuilder->getInputStream(j);
    90         const Var * const var = function->getParameter(j);
    91         if (DebugOptionIsSet(DumpTrace)) {
    92             iBuilder->CallPrintRegister(var->getName()->to_string(), iBuilder->CreateBlockAlignedLoad(inputVal));
    93         }
    94         mMarkerMap.insert(std::make_pair(var, inputVal));
    95     }
    96 
    97     compileBlock(function->getEntryBlock());
    98 
    99     for (unsigned j = 0; j < function->getNumOfResults(); ++j) {
    100         const auto f = mMarkerMap.find(function->getResult(j));
    101         if (LLVM_UNLIKELY(f == mMarkerMap.end())) {
    102             throw std::runtime_error("PabloCompiler: result " + std::to_string(j) + " was not assigned a value!");
    103         }
    104         iBuilder->CreateBlockAlignedStore(f->second, mKernelBuilder->getOutputStream(j));
    105     }
    106 
    107     mKernelBuilder->finalize();
    10898}
    10999
     
    364354        expr = iBuilder->simd_and(sum, iBuilder->simd_not(cc_expr));
    365355    } else if (const InFile * e = dyn_cast<InFile>(stmt)) {
    366         Value * EOFmark = iBuilder->CreateLoad(mKernelBuilder->getInternalState("EOFmark"));
     356        Value * EOFmark = mKernelBuilder->getScalarField(mSelf, "EOFmark");
    367357        Value * infileMask = iBuilder->simd_add(iBuilder->getBitBlockWidth(), EOFmark, iBuilder->allOnes());
    368358        expr = iBuilder->simd_and(compileExpression(e->getExpr()), infileMask);
    369359    } else if (const AtEOF * e = dyn_cast<AtEOF>(stmt)) {
    370         Value * EOFmark = iBuilder->CreateLoad(mKernelBuilder->getInternalState("EOFmark"));
     360        Value * EOFmark = mKernelBuilder->getScalarField(mSelf, "EOFmark");
    371361                expr = iBuilder->simd_and(compileExpression(e->getExpr()), EOFmark);
    372362    } else if (const Count * c = dyn_cast<Count>(stmt)) {
    373363        Value * const to_count = compileExpression(c->getExpr());
    374         expr = mCarryManager->popCount(to_count, c->getGlobalCountIndex());
     364        std::string counter = c->getName()->to_string();
     365        Value * countSoFar = mKernelBuilder->getScalarField(mSelf, counter);
     366        Value * fieldCounts = iBuilder->simd_popcount(64, to_count);
     367        for (unsigned i = 0; i < iBuilder->getBitBlockWidth()/64; ++i) {
     368            countSoFar = iBuilder->CreateAdd(countSoFar, iBuilder->mvmd_extract(64, fieldCounts, i));
     369        }
     370        mKernelBuilder->setScalarField(mSelf, counter, countSoFar);
     371        expr = iBuilder->bitCast(iBuilder->CreateZExt(countSoFar, iBuilder->getIntNTy(iBuilder->getBitBlockWidth())));
    375372    } else if (const Lookahead * l = dyn_cast<Lookahead>(stmt)) {
    376373        PabloAST * const var = l->getExpr();
     
    390387        const unsigned offset1 = ((l->getAmount() + iBuilder->getBitBlockWidth() - 1) / iBuilder->getBitBlockWidth());
    391388        const unsigned shift = (l->getAmount() % iBuilder->getBitBlockWidth());
    392         Value * const v0 = iBuilder->CreateBlockAlignedLoad(mKernelBuilder->getInputStream(index, offset0));
    393         Value * const v1 = iBuilder->CreateBlockAlignedLoad(mKernelBuilder->getInputStream(index, offset1));
     389        Value * const v0 = nullptr;//iBuilder->CreateBlockAlignedLoad(mKernelBuilder->getInputStream(index, offset0));
     390        Value * const v1 = nullptr;//iBuilder->CreateBlockAlignedLoad(mKernelBuilder->getInputStream(index, offset1));
    394391        if (LLVM_UNLIKELY((shift % 8) == 0)) { // Use a single whole-byte shift, if possible.
    395392            expr = iBuilder->mvmd_dslli(8, v1, v0, (shift / 8));
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.h

    r5000 r5063  
    1313#include <unordered_map>
    1414#include <pablo/carry_manager.h>
     15#include <pablo/pablo_kernel.h>
    1516#include <llvm/ADT/Twine.h>
    1617#include <llvm/IR/IRBuilder.h>
     
    4849    using LookaheadOffsetMap = std::unordered_map<const PabloAST *, IntSet>;
    4950public:
    50     PabloCompiler(Module * m, IDISA::IDISA_Builder * b);
    51 
    52     llvm::Function * compile(PabloFunction * function);
    53     void setKernel(kernel::KernelBuilder * kBuilder);
     51    PabloCompiler(IDISA::IDISA_Builder * b, PabloKernel * k, PabloFunction * function);
     52    Type * initializeCarryData();
     53    void compile(Function * doBlockFunction);
    5454
    5555private:
     
    7171    Type* const                         mBitBlockType;
    7272
    73     CarryManager *                      mCarryManager;
     73    std::unique_ptr<CarryManager>       mCarryManager;
    7474
    75     const PabloFunction *               mPabloFunction;
     75    PabloFunction *  const             mPabloFunction;
    7676    const PabloBlock *                  mPabloBlock;
    7777
    78     kernel::KernelBuilder *             mKernelBuilder;
     78    PabloKernel *                       mKernelBuilder;
     79    Value *                             mSelf;
    7980
    8081    unsigned                            mWhileDepth;
  • icGREP/icgrep-devel/icgrep/pablo/pablo_kernel.cpp

    r5062 r5063  
    1818    KernelBuilder(builder, kernelName,
    1919                    {StreamSetBinding{StreamSetType(function->getNumOfParameters(), 1), "inputs"}},
    20                     {StreamSetBinding{StreamSetType(function->getNumOfResults(), 1), "outputs"}},
     20                    {},
    2121                    {},
    2222                    {},
    2323                    {ScalarBinding{builder->getBitBlockType(), "EOFmark"}}),
    2424    mPabloFunction(function) {
     25    unsigned output_streams = function->getNumOfResults();
     26    if (output_streams > 0) {
     27        mStreamSetOutputs = {StreamSetBinding{StreamSetType(output_streams, 1), "outputs"}};
     28    }
    2529    mScalarOutputs = accumBindings(accumulators);
    2630    pablo_compiler = new PabloCompiler(builder, this, function);
     
    3236    for (auto a : accum_names) {
    3337        vec.push_back(ScalarBinding{accum_t, a});
     38        addScalar(accum_t, a);
    3439    }
    3540    return vec;
     
    3742
    3843void PabloKernel::prepareKernel() {
    39     errs() << "PabloKernel::prepareKernel\n";
    4044    Type * carryDataType = pablo_compiler->initializeCarryData();
    4145    addScalar(carryDataType, "carries");
     
    4448
    4549void PabloKernel::generateKernel() {
     50    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
    4651    KernelBuilder::generateKernel();
    4752    Module * m = iBuilder->getModule();
    4853    addFinalBlockMethod(m);
    4954    pablo_compiler->compile(m->getFunction(mKernelName + doBlock_suffix));
     55    iBuilder->restoreIP(savePoint);
    5056}
    5157
    5258void PabloKernel::addFinalBlockMethod(Module * m) {
     59    IDISA::IDISA_Builder::InsertPoint savePoint = iBuilder->saveIP();
     60    Module * saveModule = iBuilder->getModule();
     61    iBuilder->setModule(m);
    5362    Function * doBlockFunction = m->getFunction(mKernelName + doBlock_suffix);
    5463    Function * finalBlockFunction = m->getFunction(mKernelName + finalBlock_suffix);
     
    6978    iBuilder->CreateCall(doBlockFunction, doBlockArgs);
    7079    iBuilder->CreateRetVoid();
     80    iBuilder->setModule(saveModule);
     81    iBuilder->restoreIP(savePoint);
    7182}
    7283
  • icGREP/icgrep-devel/icgrep/pablo/pe_count.h

    r5061 r5063  
    3030    : Statement(ClassTypeId::Count, {expr}, counter)
    3131    {
    32 
    3332    }
    3433private:
Note: See TracChangeset for help on using the changeset viewer.