Ignore:
Timestamp:
Oct 23, 2014, 8:02:32 PM (5 years ago)
Author:
nmedfort
Message:

Eliminated need for Mem2Reg pass. Automatic introduction of PHI nodes for Next nodes.

File:
1 edited

Legend:

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

    r4261 r4264  
    9898    InitializeNativeTarget();
    9999    std::string ErrStr;
    100     mExecutionEngine = EngineBuilder(mMod).setUseMCJIT(true).setErrorStr(&ErrStr).setOptLevel(CodeGenOpt::Level::Less).create();
     100    mExecutionEngine = EngineBuilder(mMod).setUseMCJIT(true).setErrorStr(&ErrStr).setOptLevel(CodeGenOpt::Level::None).create();
    101101    if (mExecutionEngine == nullptr) {
    102102        throw std::runtime_error("Could not create ExecutionEngine: " + ErrStr);
     
    170170        Value* indices[] = {b.getInt64(0), b.getInt32(i)};
    171171        const String * const name = mBasisBitVars[i]->getName();
    172         mMarkerMap.insert(std::make_pair(name, b.CreateGEP(mBasisBitsAddr, indices, name->str())));
     172        Value * gep = b.CreateGEP(mBasisBitsAddr, indices);
     173        LoadInst * basisBit = b.CreateAlignedLoad(gep, BLOCK_SIZE/8, false, name->str());
     174        mMarkerMap.insert(std::make_pair(name, basisBit));
    173175    }
    174176
     
    176178    Value * result = compileStatements(pb.expressions());
    177179    SetReturnMarker(result, 0); // matches
    178 
    179180    const String * lf = pb.createVar(mNameMap["LineFeed"]->getName())->getName();
    180 
    181     SetReturnMarker(GetMarker(lf), 1); // line feeds
     181    SetReturnMarker(mMarkerMap.find(lf)->second, 1); // line feeds
    182182
    183183    assert (mCarryQueueIdx == mCarryQueueSize);
     
    212212#endif
    213213
    214     fpm.add(createPromoteMemoryToRegisterPass()); //Transform to SSA form.
    215     fpm.add(createBasicAliasAnalysisPass());      //Provide basic AliasAnalysis support for GVN. (Global Value Numbering)
    216     fpm.add(createCFGSimplificationPass());       //Simplify the control flow graph.
     214    //fpm.add(createPromoteMemoryToRegisterPass()); //Transform to SSA form.
     215    //fpm.add(createBasicAliasAnalysisPass());      //Provide basic AliasAnalysis support for GVN. (Global Value Numbering)
     216    //fpm.add(createCFGSimplificationPass());       //Simplify the control flow graph.
    217217    fpm.add(createInstructionCombiningPass());    //Simple peephole optimizations and bit-twiddling.
    218218    fpm.add(createReassociatePass());             //Reassociate expressions.
     
    371371}
    372372
    373 void PabloCompiler::DeclareCallFunctions(const ExpressionList & stmts) {
     373void PabloCompiler::DeclareCallFunctions(const StatementList & stmts) {
    374374    for (PabloAST * stmt : stmts) {
    375375        if (const Assign * assign = dyn_cast<Assign>(stmt)) {
     
    496496void PabloCompiler::SetReturnMarker(Value * marker, const unsigned index) {
    497497    IRBuilder<> b(mBasicBlock);
    498     Value* marker_bitblock = b.CreateAlignedLoad(marker, BLOCK_SIZE/8, false);
    499     Value* output_indices[] = {b.getInt64(0), b.getInt32(index)};
    500     Value* output_struct_GEP = b.CreateGEP(mOutputAddrPtr, output_indices);
    501     b.CreateAlignedStore(marker_bitblock, output_struct_GEP, BLOCK_SIZE/8, false);
    502 }
    503 
    504 
    505 Value * PabloCompiler::compileStatements(const ExpressionList & stmts) {
     498    if (marker->getType()->isPointerTy()) {
     499        marker = b.CreateAlignedLoad(marker, BLOCK_SIZE/8, false);
     500    }
     501    Value* indices[] = {b.getInt64(0), b.getInt32(index)};
     502    Value* gep = b.CreateGEP(mOutputAddrPtr, indices);
     503    b.CreateAlignedStore(marker, gep, BLOCK_SIZE/8, false);
     504}
     505
     506
     507Value * PabloCompiler::compileStatements(const StatementList & stmts) {
    506508    Value * retVal = nullptr;
    507509    for (PabloAST * statement : stmts) {
     
    517519    {
    518520        Value* expr = compileExpression(assign->getExpr());
    519         Value* marker = GetMarker(assign->getName());
    520         IRBuilder<> b(mBasicBlock);
    521         b.CreateAlignedStore(expr, marker, BLOCK_SIZE/8, false);
    522         retVal = marker;
     521        mMarkerMap[assign->getName()] = expr;
     522        retVal = expr;
    523523    }
    524524    if (const Next * next = dyn_cast<const Next>(stmt))
    525525    {
    526         IRBuilder<> b(mBasicBlock);
    527         auto f = mMarkerMap.find(next->getName());
    528         assert (f != mMarkerMap.end());
    529         Value * marker = f->second;
    530         Value * expr = compileExpression(next->getExpr());
    531         b.CreateAlignedStore(expr, marker, BLOCK_SIZE/8, false);
    532         retVal = marker;
     526        Value* expr = compileExpression(next->getExpr());
     527        mMarkerMap[next->getName()] = expr;
     528        retVal = expr;
    533529    }
    534530    else if (const If * ifstmt = dyn_cast<const If>(stmt))
     
    584580        retVal = returnMarker;
    585581    }
    586     else if (const While * whl = dyn_cast<const While>(stmt))
     582    else if (const While * whileStatement = dyn_cast<const While>(stmt))
    587583    {
    588584        const auto baseCarryQueueIdx = mCarryQueueIdx;
    589585        if (mNestingDepth == 0) {
    590             for (auto i = 0; i != whl->getInclusiveCarryCount(); ++i) {
     586            for (auto i = 0; i != whileStatement->getInclusiveCarryCount(); ++i) {
    591587                genCarryInLoad(baseCarryQueueIdx + i);
    592588            }
    593589        }       
    594590
    595         // First compile the initial iteration statements; the calls to genCarryOutStore will update the
     591        SmallVector<Next*, 4> nextNodes;
     592        for (PabloAST * node : whileStatement->getBody()) {
     593            if (isa<Next>(node)) {
     594                nextNodes.push_back(cast<Next>(node));
     595            }
     596        }
     597
     598        // Compile the initial iteration statements; the calls to genCarryOutStore will update the
    596599        // mCarryQueueVector with the appropriate values. Although we're not actually entering a new basic
    597600        // block yet, increment the nesting depth so that any calls to genCarryInLoad or genCarryOutStore
    598601        // will refer to the previous value.
    599602        ++mNestingDepth;
    600         compileStatements(whl->getBody());
     603        compileStatements(whileStatement->getBody());
    601604        // Reset the carry queue index. Note: this ought to be changed in the future. Currently this assumes
    602605        // that compiling the while body twice will generate the equivalent IR. This is not necessarily true
     
    616619        IRBuilder<> bCond(whileCondBlock);
    617620        // generate phi nodes for any carry propogating instruction
    618         std::vector<PHINode*> carryQueuePhiNodes(whl->getInclusiveCarryCount());
    619         for (auto i = 0; i != whl->getInclusiveCarryCount(); ++i) {
     621        std::vector<PHINode*> phiNodes(whileStatement->getInclusiveCarryCount() + nextNodes.size());
     622        unsigned index = 0;
     623        for (index = 0; index != whileStatement->getInclusiveCarryCount(); ++index) {
    620624            PHINode * phi = bCond.CreatePHI(mXi64Vect, 2);
    621             phi->addIncoming(mCarryQueueVector[baseCarryQueueIdx + i], mBasicBlock);
    622             mCarryQueueVector[baseCarryQueueIdx + i] = mZeroInitializer; // phi; // (use phi for multi-carry mode.)
    623             carryQueuePhiNodes[i] = phi;
     625            phi->addIncoming(mCarryQueueVector[baseCarryQueueIdx + index], mBasicBlock);
     626            mCarryQueueVector[baseCarryQueueIdx + index] = mZeroInitializer; // (use phi for multi-carry mode.)
     627            phiNodes[index] = phi;
     628        }
     629        // and for any Next nodes in the loop body
     630        for (Next * n : nextNodes) {
     631            PHINode * phi = bCond.CreatePHI(mXi64Vect, 2, n->getName()->str());
     632            auto f = mMarkerMap.find(n->getName());
     633            assert (f != mMarkerMap.end());
     634            phi->addIncoming(f->second, mBasicBlock);
     635            mMarkerMap[n->getName()] = phi;
     636            phiNodes[index++] = phi;
    624637        }
    625638
    626639        mBasicBlock = whileCondBlock;
    627         bCond.CreateCondBr(genBitBlockAny(compileExpression(whl->getCondition())), whileEndBlock, whileBodyBlock);
     640        bCond.CreateCondBr(genBitBlockAny(compileExpression(whileStatement->getCondition())), whileEndBlock, whileBodyBlock);
    628641
    629642        // BODY BLOCK
    630643        mBasicBlock = whileBodyBlock;
    631         retVal = compileStatements(whl->getBody());
     644        retVal = compileStatements(whileStatement->getBody());
    632645        // update phi nodes for any carry propogating instruction
    633646        IRBuilder<> bWhileBody(mBasicBlock);
    634         for (auto i = 0; i != whl->getInclusiveCarryCount(); ++i) {
    635             Value * carryOut = bWhileBody.CreateOr(carryQueuePhiNodes[i], mCarryQueueVector[baseCarryQueueIdx + i]);
    636             carryQueuePhiNodes[i]->addIncoming(carryOut, mBasicBlock);
    637             mCarryQueueVector[baseCarryQueueIdx + i] = carryQueuePhiNodes[i];
     647        for (index = 0; index != whileStatement->getInclusiveCarryCount(); ++index) {
     648            Value * carryOut = bWhileBody.CreateOr(phiNodes[index], mCarryQueueVector[baseCarryQueueIdx + index]);
     649            PHINode * phi = phiNodes[index];
     650            phi->addIncoming(carryOut, mBasicBlock);
     651            mCarryQueueVector[baseCarryQueueIdx + index] = phi;
     652        }
     653        // and for any Next nodes in the loop body
     654        for (Next * n : nextNodes) {
     655            auto f = mMarkerMap.find(n->getName());
     656            assert (f != mMarkerMap.end());
     657            PHINode * phi = phiNodes[index++];
     658            phi->addIncoming(f->second, mBasicBlock);
     659            mMarkerMap[n->getName()] = phi;
    638660        }
    639661
     
    643665        mBasicBlock = whileEndBlock;   
    644666        if (--mNestingDepth == 0) {
    645             for (auto i = 0; i != whl->getInclusiveCarryCount(); ++i) {
    646                 genCarryOutStore(carryQueuePhiNodes[i], baseCarryQueueIdx + i);
     667            for (index = 0; index != whileStatement->getInclusiveCarryCount(); ++index) {
     668                genCarryOutStore(phiNodes[index], baseCarryQueueIdx + index);
    647669            }
    648670        }
     
    669691                throw std::runtime_error("Unexpected error locating static function for \"" + call->getCallee()->str() + "\"");
    670692            }
    671             Value * unicode_category = b.CreateCall(ci->second, mBasisBitsAddr);
    672             Value * ptr = b.CreateAlloca(mXi64Vect);
    673             b.CreateAlignedStore(unicode_category, ptr, BLOCK_SIZE/8, false);
    674             mi = mMarkerMap.insert(std::make_pair(call->getCallee(), ptr)).first;
    675         }
    676         retVal = b.CreateAlignedLoad(mi->second, BLOCK_SIZE/8, false, call->getCallee()->str() );
     693            mi = mMarkerMap.insert(std::make_pair(call->getCallee(), b.CreateCall(ci->second, mBasisBitsAddr))).first;
     694        }
     695        retVal = mi->second;
    677696    }
    678697    else if (const Var * var = dyn_cast<Var>(expr))
    679     {
     698    {       
    680699        auto f = mMarkerMap.find(var->getName());
    681700        assert (f != mMarkerMap.end());
    682         retVal = b.CreateAlignedLoad(f->second, BLOCK_SIZE/8, false, var->getName()->str() );
     701        retVal = f->second;
    683702    }
    684703    else if (const And * pablo_and = dyn_cast<And>(expr))
     
    690709        retVal = b.CreateOr(compileExpression(pablo_or->getExpr1()), compileExpression(pablo_or->getExpr2()), "or");
    691710    }
    692     else if (const Sel * pablo_sel = dyn_cast<Sel>(expr))
    693     {
    694         Value* ifMask = compileExpression(pablo_sel->getCondition());
    695         Value* and_if_true_result = b.CreateAnd(ifMask, compileExpression(pablo_sel->getTrueExpr()));
    696         Value* and_if_false_result = b.CreateAnd(genNot(ifMask), compileExpression(pablo_sel->getFalseExpr()));
    697         retVal = b.CreateOr(and_if_true_result, and_if_false_result);
     711    else if (const Sel * sel = dyn_cast<Sel>(expr))
     712    {
     713        Value* ifMask = compileExpression(sel->getCondition());
     714        Value* ifTrue = b.CreateAnd(ifMask, compileExpression(sel->getTrueExpr()));
     715        Value* ifFalse = b.CreateAnd(genNot(ifMask), compileExpression(sel->getFalseExpr()));
     716        retVal = b.CreateOr(ifTrue, ifFalse);
    698717    }
    699718    else if (const Not * pablo_not = dyn_cast<Not>(expr))
Note: See TracChangeset for help on using the changeset viewer.