Ignore:
Timestamp:
Oct 30, 2014, 1:19:34 PM (5 years ago)
Author:
nmedfort
Message:

Created an "insertion friendly" Pablo AST structure similar to LLVM; fixed engine builder bug when creating a unicode class.

File:
1 edited

Legend:

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

    r4275 r4276  
    5555#include <llvm/Bitcode/ReaderWriter.h>
    5656#include <llvm/Support/MemoryBuffer.h>
    57 
    5857#include <llvm/IR/IRBuilder.h>
    5958
     
    130129, mBasisBitsAddr(nullptr)
    131130, mOutputAddrPtr(nullptr)
    132 , mMaxPabloWhileDepth(0)
     131, mMaxNestingDepth(0)
    133132{
    134133    //Create the jit execution engine.up
     
    178177LLVM_Gen_RetVal PabloCompiler::compile(PabloBlock & pb)
    179178{
     179    mNestingDepth = 0;
     180    mMaxNestingDepth = 0;
    180181    mCarryQueueSize = 0;
    181     DeclareCallFunctions(pb.statements());
     182    Examine(pb.statements());
    182183    mCarryQueueVector.resize(mCarryQueueSize);
     184
     185    std::string errMessage;
     186    EngineBuilder builder(mMod);
     187    builder.setErrorStr(&errMessage);
     188    builder.setMCPU(sys::getHostCPUName());
     189    builder.setUseMCJIT(true);
     190    builder.setOptLevel(mMaxNestingDepth > 1 ? CodeGenOpt::Level::Less : CodeGenOpt::Level::None);
     191    mExecutionEngine = builder.create();
     192    if (mExecutionEngine == nullptr) {
     193        throw std::runtime_error("Could not create ExecutionEngine: " + errMessage);
     194    }
     195
     196    if (!mCalleeMap.empty()) {
     197        DeclareCallFunctions();
     198    }
    183199
    184200    Function::arg_iterator args = mFunction->arg_begin();
     
    193209    mCarryQueueIdx = 0;
    194210    mNestingDepth = 0;
     211    mMaxNestingDepth = 0;
    195212    mBasicBlock = BasicBlock::Create(mMod->getContext(), "parabix_entry", mFunction,0);
    196213
     
    228245    //Use the pass manager to run optimizations on the function.
    229246    FunctionPassManager fpm(mMod);
    230     if (true) {
    231         std::string errMessage;
    232         EngineBuilder builder(mMod);
    233         builder.setErrorStr(&errMessage);
    234         builder.setMCPU(sys::getHostCPUName());
    235         builder.setUseMCJIT(true);
    236         builder.setOptLevel(mMaxPabloWhileDepth == 0 ? CodeGenOpt::Level::None : CodeGenOpt::Level::Less);
    237         mExecutionEngine = builder.create();
    238         if (mExecutionEngine == nullptr) {
    239             throw std::runtime_error("Could not create ExecutionEngine: " + errMessage);
    240         }
    241     }
    242 #ifdef USE_LLVM_3_5
     247 #ifdef USE_LLVM_3_5
    243248    mMod->setDataLayout(mExecutionEngine->getDataLayout());
    244249    // Set up the optimizer pipeline.  Start with registering info about how the target lays out data structures.
     
    249254    fpm.add(new DataLayout(*mExecutionEngine->getDataLayout()));
    250255#endif
    251 
    252     //fpm.add(createPromoteMemoryToRegisterPass()); //Transform to SSA form.
    253     //fpm.add(createBasicAliasAnalysisPass());      //Provide basic AliasAnalysis support for GVN. (Global Value Numbering)
    254     //fpm.add(createCFGSimplificationPass());       //Simplify the control flow graph.
    255256
    256257    fpm.add(createCorrelatedValuePropagationPass());
     
    260261    fpm.add(createGVNPass());                     //Eliminate common subexpressions.   
    261262
    262 
    263     // -O1 is based on -O0
    264 
    265     // adds: -adce -always-inline -basicaa -basiccg -correlated-propagation -deadargelim -dse -early-cse -functionattrs -globalopt -indvars
    266     // -inline-cost -instcombine -ipsccp -jump-threading -lazy-value-info -lcssa -licm -loop-deletion -loop-idiom -loop-rotate -loop-simplify
    267     // -loop-unroll -loop-unswitch -loops -lower-expect -memcpyopt -memdep -no-aa -notti -prune-eh -reassociate -scalar-evolution -sccp
    268     // -simplifycfg -sroa -strip-dead-prototypes -tailcallelim -tbaa
    269 
    270 /// no noticable impact on performance
    271 
    272 //    fpm.add(createConstantPropagationPass());
    273 //    fpm.add(createDeadCodeEliminationPass());
    274 //    fpm.add(createJumpThreadingPass());
    275 //    fpm.add(createLoopIdiomPass());
    276 //    fpm.add(createLoopRotatePass());
    277 //    fpm.add(createLCSSAPass());
    278 //    fpm.add(createLazyValueInfoPass());
    279 //    fpm.add(createLowerExpectIntrinsicPass());
    280 //    fpm.add(createLoopStrengthReducePass());
    281 //    fpm.add(createLoopUnswitchPass());
    282 //    fpm.add(createSCCPPass());
    283 //    fpm.add(createLICMPass());
    284 
    285 /// hurt performance significantly
    286 
    287 //    fpm.add(createLoopUnrollPass());
    288 //    fpm.add(createIndVarSimplifyPass());
    289263    fpm.doInitialization();
    290264
     
    440414}
    441415
    442 void PabloCompiler::DeclareCallFunctions(const StatementList & stmts) {
    443     for (PabloAST * stmt : stmts) {
    444         if (const Assign * assign = dyn_cast<Assign>(stmt)) {
    445             DeclareCallFunctions(assign->getExpr());
    446         }
    447         if (const Next * next = dyn_cast<Next>(stmt)) {
    448             DeclareCallFunctions(next->getExpr());
     416void PabloCompiler::Examine(StatementList & stmts) {
     417    for (Statement * stmt : stmts) {
     418        if (Assign * assign = dyn_cast<Assign>(stmt)) {
     419            Examine(assign->getExpr());
     420        }
     421        if (Next * next = dyn_cast<Next>(stmt)) {
     422            Examine(next->getExpr());
    449423        }
    450424        else if (If * ifStatement = dyn_cast<If>(stmt)) {
    451425            const auto preIfCarryCount = mCarryQueueSize;
    452             DeclareCallFunctions(ifStatement->getCondition());
    453             DeclareCallFunctions(ifStatement->getBody());
     426            Examine(ifStatement->getCondition());
     427            mMaxNestingDepth = std::max(mMaxNestingDepth, ++mNestingDepth);
     428            Examine(ifStatement->getBody());
     429            --mNestingDepth;
    454430            ifStatement->setInclusiveCarryCount(mCarryQueueSize - preIfCarryCount);
    455431        }
    456432        else if (While * whileStatement = dyn_cast<While>(stmt)) {
    457433            const auto preWhileCarryCount = mCarryQueueSize;
    458             DeclareCallFunctions(whileStatement->getCondition());
    459             DeclareCallFunctions(whileStatement->getBody());
     434            Examine(whileStatement->getCondition());
     435            mMaxNestingDepth = std::max(mMaxNestingDepth, ++mNestingDepth);
     436            Examine(whileStatement->getBody());
     437            --mNestingDepth;
    460438            whileStatement->setInclusiveCarryCount(mCarryQueueSize - preWhileCarryCount);
    461439        }
     
    463441}
    464442
    465 void PabloCompiler::DeclareCallFunctions(const PabloAST * expr)
     443void PabloCompiler::Examine(PabloAST *expr)
    466444{
    467     if (const Call * call = dyn_cast<const Call>(expr)) {
    468         const String * const callee = call->getCallee();
    469         assert (callee);
    470         if (mCalleeMap.find(callee) == mCalleeMap.end()) {
    471             void * callee_ptr = nullptr;
    472             #define CHECK_GENERAL_CODE_CATEGORY(SUFFIX) \
    473                 if (callee->str() == #SUFFIX) { \
    474                     callee_ptr = (void*)&__get_category_##SUFFIX; \
    475                 } else
    476             CHECK_GENERAL_CODE_CATEGORY(Cc)
    477             CHECK_GENERAL_CODE_CATEGORY(Cf)
    478             CHECK_GENERAL_CODE_CATEGORY(Cn)
    479             CHECK_GENERAL_CODE_CATEGORY(Co)
    480             CHECK_GENERAL_CODE_CATEGORY(Cs)
    481             CHECK_GENERAL_CODE_CATEGORY(Ll)
    482             CHECK_GENERAL_CODE_CATEGORY(Lm)
    483             CHECK_GENERAL_CODE_CATEGORY(Lo)
    484             CHECK_GENERAL_CODE_CATEGORY(Lt)
    485             CHECK_GENERAL_CODE_CATEGORY(Lu)
    486             CHECK_GENERAL_CODE_CATEGORY(Mc)
    487             CHECK_GENERAL_CODE_CATEGORY(Me)
    488             CHECK_GENERAL_CODE_CATEGORY(Mn)
    489             CHECK_GENERAL_CODE_CATEGORY(Nd)
    490             CHECK_GENERAL_CODE_CATEGORY(Nl)
    491             CHECK_GENERAL_CODE_CATEGORY(No)
    492             CHECK_GENERAL_CODE_CATEGORY(Pc)
    493             CHECK_GENERAL_CODE_CATEGORY(Pd)
    494             CHECK_GENERAL_CODE_CATEGORY(Pe)
    495             CHECK_GENERAL_CODE_CATEGORY(Pf)
    496             CHECK_GENERAL_CODE_CATEGORY(Pi)
    497             CHECK_GENERAL_CODE_CATEGORY(Po)
    498             CHECK_GENERAL_CODE_CATEGORY(Ps)
    499             CHECK_GENERAL_CODE_CATEGORY(Sc)
    500             CHECK_GENERAL_CODE_CATEGORY(Sk)
    501             CHECK_GENERAL_CODE_CATEGORY(Sm)
    502             CHECK_GENERAL_CODE_CATEGORY(So)
    503             CHECK_GENERAL_CODE_CATEGORY(Zl)
    504             CHECK_GENERAL_CODE_CATEGORY(Zp)
    505             CHECK_GENERAL_CODE_CATEGORY(Zs)
    506             // OTHERWISE ...
    507             throw std::runtime_error("Unknown unicode category \"" + callee->str() + "\"");
    508             #undef CHECK_GENERAL_CODE_CATEGORY
    509             Value * unicodeCategory = mMod->getOrInsertFunction("__get_category_" + callee->str(), mBitBlockType, mBasisBitsInputPtr, NULL);
    510             if (unicodeCategory == nullptr) {
    511                 throw std::runtime_error("Could not create static method call for unicode category \"" + callee->str() + "\"");
    512             }
    513             mExecutionEngine->addGlobalMapping(cast<GlobalValue>(unicodeCategory), callee_ptr);
    514             mCalleeMap.insert(std::make_pair(callee, unicodeCategory));
    515         }
    516     }
    517     else if (const And * pablo_and = dyn_cast<const And>(expr))
    518     {
    519         DeclareCallFunctions(pablo_and->getExpr1());
    520         DeclareCallFunctions(pablo_and->getExpr2());
    521     }
    522     else if (const Or * pablo_or = dyn_cast<const Or>(expr))
    523     {
    524         DeclareCallFunctions(pablo_or->getExpr1());
    525         DeclareCallFunctions(pablo_or->getExpr2());
    526     }
    527     else if (const Sel * pablo_sel = dyn_cast<const Sel>(expr))
    528     {
    529         DeclareCallFunctions(pablo_sel->getCondition());
    530         DeclareCallFunctions(pablo_sel->getTrueExpr());
    531         DeclareCallFunctions(pablo_sel->getFalseExpr());
    532     }
    533     else if (const Not * pablo_not = dyn_cast<const Not>(expr))
    534     {
    535         DeclareCallFunctions(pablo_not->getExpr());
    536     }
    537     else if (const Advance * adv = dyn_cast<const Advance>(expr))
    538     {
     445    if (Call * call = dyn_cast<Call>(expr)) {
     446        mCalleeMap.insert(std::make_pair(call->getCallee(), nullptr));
     447    }
     448    else if (And * pablo_and = dyn_cast<And>(expr)) {
     449        Examine(pablo_and->getExpr1());
     450        Examine(pablo_and->getExpr2());
     451    }
     452    else if (Or * pablo_or = dyn_cast<Or>(expr)) {
     453        Examine(pablo_or->getExpr1());
     454        Examine(pablo_or->getExpr2());
     455    }
     456    else if (Sel * pablo_sel = dyn_cast<Sel>(expr)) {
     457        Examine(pablo_sel->getCondition());
     458        Examine(pablo_sel->getTrueExpr());
     459        Examine(pablo_sel->getFalseExpr());
     460    }
     461    else if (Not * pablo_not = dyn_cast<Not>(expr)) {
     462        Examine(pablo_not->getExpr());
     463    }
     464    else if (Advance * adv = dyn_cast<Advance>(expr)) {
    539465        ++mCarryQueueSize;
    540         DeclareCallFunctions(adv->getExpr());
    541     }
    542     else if (const MatchStar * mstar = dyn_cast<const MatchStar>(expr))
    543     {
     466        Examine(adv->getExpr());
     467    }
     468    else if (MatchStar * mstar = dyn_cast<MatchStar>(expr)) {
    544469        ++mCarryQueueSize;
    545         DeclareCallFunctions(mstar->getMarker());
    546         DeclareCallFunctions(mstar->getCharClass());
    547     }
    548     else if (const ScanThru * sthru = dyn_cast<const ScanThru>(expr))
    549     {
     470        Examine(mstar->getMarker());
     471        Examine(mstar->getCharClass());
     472    }
     473    else if (ScanThru * sthru = dyn_cast<ScanThru>(expr)) {
    550474        ++mCarryQueueSize;
    551         DeclareCallFunctions(sthru->getScanFrom());
    552         DeclareCallFunctions(sthru->getScanThru());
     475        Examine(sthru->getScanFrom());
     476        Examine(sthru->getScanThru());
     477    }
     478}
     479
     480void PabloCompiler::DeclareCallFunctions() {
     481    for (auto mapping : mCalleeMap) {
     482        const String * callee = mapping.first;
     483        void * callee_ptr = nullptr;
     484        #define CHECK_GENERAL_CODE_CATEGORY(SUFFIX) \
     485            if (callee->str() == #SUFFIX) { \
     486                callee_ptr = (void*)&__get_category_##SUFFIX; \
     487            } else
     488        CHECK_GENERAL_CODE_CATEGORY(Cc)
     489        CHECK_GENERAL_CODE_CATEGORY(Cf)
     490        CHECK_GENERAL_CODE_CATEGORY(Cn)
     491        CHECK_GENERAL_CODE_CATEGORY(Co)
     492        CHECK_GENERAL_CODE_CATEGORY(Cs)
     493        CHECK_GENERAL_CODE_CATEGORY(Ll)
     494        CHECK_GENERAL_CODE_CATEGORY(Lm)
     495        CHECK_GENERAL_CODE_CATEGORY(Lo)
     496        CHECK_GENERAL_CODE_CATEGORY(Lt)
     497        CHECK_GENERAL_CODE_CATEGORY(Lu)
     498        CHECK_GENERAL_CODE_CATEGORY(Mc)
     499        CHECK_GENERAL_CODE_CATEGORY(Me)
     500        CHECK_GENERAL_CODE_CATEGORY(Mn)
     501        CHECK_GENERAL_CODE_CATEGORY(Nd)
     502        CHECK_GENERAL_CODE_CATEGORY(Nl)
     503        CHECK_GENERAL_CODE_CATEGORY(No)
     504        CHECK_GENERAL_CODE_CATEGORY(Pc)
     505        CHECK_GENERAL_CODE_CATEGORY(Pd)
     506        CHECK_GENERAL_CODE_CATEGORY(Pe)
     507        CHECK_GENERAL_CODE_CATEGORY(Pf)
     508        CHECK_GENERAL_CODE_CATEGORY(Pi)
     509        CHECK_GENERAL_CODE_CATEGORY(Po)
     510        CHECK_GENERAL_CODE_CATEGORY(Ps)
     511        CHECK_GENERAL_CODE_CATEGORY(Sc)
     512        CHECK_GENERAL_CODE_CATEGORY(Sk)
     513        CHECK_GENERAL_CODE_CATEGORY(Sm)
     514        CHECK_GENERAL_CODE_CATEGORY(So)
     515        CHECK_GENERAL_CODE_CATEGORY(Zl)
     516        CHECK_GENERAL_CODE_CATEGORY(Zp)
     517        CHECK_GENERAL_CODE_CATEGORY(Zs)
     518        // OTHERWISE ...
     519        throw std::runtime_error("Unknown unicode category \"" + callee->str() + "\"");
     520        #undef CHECK_GENERAL_CODE_CATEGORY
     521        Value * unicodeCategory = mMod->getOrInsertFunction("__get_category_" + callee->str(), mBitBlockType, mBasisBitsInputPtr, NULL);
     522        if (unicodeCategory == nullptr) {
     523            throw std::runtime_error("Could not create static method call for unicode category \"" + callee->str() + "\"");
     524        }
     525        mExecutionEngine->addGlobalMapping(cast<GlobalValue>(unicodeCategory), callee_ptr);
     526        mCalleeMap[callee] = unicodeCategory;
    553527    }
    554528}
     
    556530Value * PabloCompiler::compileStatements(const StatementList & stmts) {
    557531    Value * retVal = nullptr;
    558     for (PabloAST * statement : stmts) {
     532    for (const PabloAST * statement : stmts) {
    559533        retVal = compileStatement(statement);
    560534    }
     
    641615        }       
    642616
    643         SmallVector<Next*, 4> nextNodes;
    644         for (PabloAST * node : whileStatement->getBody()) {
     617        SmallVector<const Next*, 4> nextNodes;
     618        for (const PabloAST * node : whileStatement->getBody()) {
    645619            if (isa<Next>(node)) {
    646620                nextNodes.push_back(cast<Next>(node));
     
    651625        // mCarryQueueVector with the appropriate values. Although we're not actually entering a new basic
    652626        // block yet, increment the nesting depth so that any calls to genCarryInLoad or genCarryOutStore
    653         // will refer to the previous value.
     627        // will refer to the previous value.       
     628
    654629        ++mNestingDepth;
    655         if (mMaxPabloWhileDepth < mNestingDepth) mMaxPabloWhileDepth = mNestingDepth;
     630
    656631        compileStatements(whileStatement->getBody());
    657632       
     
    682657        }
    683658        // and for any Next nodes in the loop body
    684         for (Next * n : nextNodes) {
     659        for (const Next * n : nextNodes) {
    685660            PHINode * phi = bCond.CreatePHI(mBitBlockType, 2, n->getName()->str());
    686661            auto f = mMarkerMap.find(n->getName());
     
    706681        }
    707682        // and for any Next nodes in the loop body
    708         for (Next * n : nextNodes) {
     683        for (const Next * n : nextNodes) {
    709684            auto f = mMarkerMap.find(n->getName());
    710685            assert (f != mMarkerMap.end());
Note: See TracChangeset for help on using the changeset viewer.