Changeset 4344


Ignore:
Timestamp:
Dec 17, 2014, 5:05:34 PM (4 years ago)
Author:
cameron
Message:

If statement support

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

Legend:

Unmodified
Added
Removed
  • icGREP/icgrep-devel/icgrep/pablo/codegenstate.h

    r4280 r4344  
    116116    PabloAST * createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr);
    117117
    118     inline If * createIf(PabloAST * condition, PabloBlock && body) {
    119         If * statement = new If(condition, std::move(body.statements()), &mStatements);
     118    inline If * createIf(PabloAST * condition, std::vector<Assign *> && definedVars, PabloBlock && body) {
     119        If * statement = new If(condition, std::move(definedVars), std::move(body.statements()), &mStatements);
    120120        mStatements.push_back(statement);
    121121        return statement;
  • icGREP/icgrep-devel/icgrep/pablo/pablo_compiler.cpp

    r4343 r4344  
    269269    LLVM_Gen_RetVal retVal;
    270270    //Return the required size of the carry queue and a pointer to the process_block function.
    271     retVal.carry_q_size = mCarryQueueSize;
    272     retVal.advance_q_size = mAdvanceQueueSize;
     271    retVal.carry_q_size = mCarryQueueVector.size();
     272    retVal.advance_q_size = mAdvanceQueueVector.size();
    273273    retVal.process_block_fptr = mExecutionEngine->getPointerToFunction(mFunction);
    274274
     
    473473            const auto preIfAdvanceCount = mAdvanceQueueSize;
    474474            Examine(ifStatement->getCondition());
    475             mMaxNestingDepth = std::max(mMaxNestingDepth, ++mNestingDepth);
    476475            Examine(ifStatement->getBody());
    477             --mNestingDepth;
    478             ifStatement->setInclusiveCarryCount(mCarryQueueSize - preIfCarryCount);
    479             ifStatement->setInclusiveAdvanceCount(mAdvanceQueueSize - preIfAdvanceCount);
     476            int ifCarryCount = mCarryQueueSize - preIfCarryCount;
     477            int ifAdvanceCount = mAdvanceQueueSize - preIfAdvanceCount;
     478            if ((ifCarryCount + ifAdvanceCount) > 1) {
     479              ++mAdvanceQueueSize;
     480              ++ifAdvanceCount;
     481            }
     482            ifStatement->setInclusiveCarryCount(ifCarryCount);
     483            ifStatement->setInclusiveAdvanceCount(ifAdvanceCount);
    480484        }
    481485        else if (While * whileStatement = dyn_cast<While>(stmt)) {
     
    580584
    581585void PabloCompiler::compileStatements(const StatementList & stmts) {
    582     Value * retVal = nullptr;
    583586    for (const PabloAST * statement : stmts) {
    584587        compileStatement(statement);
     
    601604        mMarkerMap[next->getName()] = expr;
    602605    }
    603     else if (const If * ifstmt = dyn_cast<const If>(stmt))
    604     {
    605         BasicBlock * ifEntryBlock = mBasicBlock;
     606    else if (const If * ifStatement = dyn_cast<const If>(stmt))
     607    //
     608    //  The If-ElseZero stmt:
     609    //  if <predicate:expr> then <body:stmt>* elsezero <defined:var>* endif
     610    //  If the value of the predicate is nonzero, then determine the values of variables
     611    //  <var>* by executing the given statements.  Otherwise, the value of the
     612    //  variables are all zero.  Requirements: (a) no variable that is defined within
     613    //  the body of the if may be accessed outside unless it is explicitly 
     614    //  listed in the variable list, (b) every variable in the defined list receives
     615    //  a value within the body, and (c) the logical consequence of executing
     616    //  the statements in the event that the predicate is zero is that the
     617    //  values of all defined variables indeed work out to be 0.
     618    //
     619    //  Simple Implementation with Phi nodes:  a phi node in the if exit block
     620    //  is inserted for each variable in the defined variable list.  It receives
     621    //  a zero value from the ifentry block and the defined value from the if
     622    //  body.
     623    //
     624    {
     625        BasicBlock * ifEntryBlock = mBasicBlock;  // The block we are in.
    606626        BasicBlock * ifBodyBlock = BasicBlock::Create(mMod->getContext(), "if.body", mFunction, 0);
    607627        BasicBlock * ifEndBlock = BasicBlock::Create(mMod->getContext(), "if.end", mFunction, 0);
    608 
    609         int if_start_idx = mCarryQueueIdx;
    610         int if_start_idx_advance = mAdvanceQueueIdx;
    611 
    612         Value* if_test_value = compileExpression(ifstmt->getCondition());
    613 
    614         /* Generate the statements into the if body block, and also determine the
    615            final carry index.  */
    616 
     628       
     629        const auto baseCarryQueueIdx = mCarryQueueIdx;
     630        const auto baseAdvanceQueueIdx = mAdvanceQueueIdx;
     631       
     632        int ifCarryCount = ifStatement->getInclusiveCarryCount();
     633        int ifAdvanceCount = ifStatement->getInclusiveAdvanceCount();
     634        //  Carry/Advance queue strategy.   
     635        //  If there are any carries or advances at any nesting level within the
     636        //  if statement, then the statement must be executed.   A "summary"
     637        //  carryover variable is determined for this purpose, consisting of the
     638        //  or of all of the carry and advance variables within the if.
     639        //  This variable is determined as follows.
     640        //  (a)  If the CarryCount and AdvanceCount are both 0, there is no summary variable.
     641        //  (b)  If the CarryCount is 1 and the AdvanceCount is 0, then the summary
     642        //       carryover variable is just the single carry queue entry.
     643        //  (c)  If the CarryCount is 0 and the AdvanceCount is 1, then the summary
     644        //       carryover variable is just the advance carry queue entry.
     645        //  (d)  Otherwise, an additional advance queue entry is created for the
     646        //       summary variable.
     647        //  Note that the test for cases (c) and (d) may be combined: the summary carryover
     648        //  variable is just last advance queue entry.
     649        //
     650       
     651        IRBuilder<> b_entry(ifEntryBlock);
     652        mBasicBlock = ifEntryBlock;
     653        Value* if_test_value = compileExpression(ifStatement->getCondition());
     654       
     655        if ((ifCarryCount == 1) && (ifAdvanceCount == 0)) {
     656            Value* last_if_pending_carries = genCarryInLoad(baseCarryQueueIdx);
     657            if_test_value = b_entry.CreateOr(if_test_value, last_if_pending_carries);
     658        }
     659        else if ((ifCarryCount > 0) || (ifAdvanceCount > 0)) {
     660            Value* last_if_pending_advances = genAdvanceInLoad(baseAdvanceQueueIdx + ifAdvanceCount - 1);
     661            if_test_value = b_entry.CreateOr(if_test_value, last_if_pending_advances);
     662        }
     663        b_entry.CreateCondBr(genBitBlockAny(if_test_value), ifEndBlock, ifBodyBlock);
     664
     665        // Entry processing is complete, now handle the body of the if.
     666       
    617667        IRBuilder<> bIfBody(ifBodyBlock);
    618668        mBasicBlock = ifBodyBlock;
    619 
    620         ++mNestingDepth;
    621 
    622         compileStatements(ifstmt->getBody());
    623 
    624         int if_end_idx = mCarryQueueIdx;
    625         int if_end_idx_advance = mAdvanceQueueIdx;
    626         if (if_start_idx < if_end_idx + 1) {
    627             // Have at least two internal carries.   Accumulate and store.
    628             int if_accum_idx = mCarryQueueIdx++;
    629 
    630             Value* if_carry_accum_value = genCarryInLoad(if_start_idx);
    631 
    632             for (int c = if_start_idx+1; c < if_end_idx; c++)
     669       
     670        compileStatements(ifStatement->getBody());
     671       
     672        // After the recursive compile, now insert the code to compute the summary
     673        // carry over variable.
     674       
     675        if ((ifCarryCount + ifAdvanceCount) > 1) {
     676            // A summary variable is needed.
     677
     678            Value * carry_summary = mZeroInitializer;
     679            for (int c = baseCarryQueueIdx; c < baseCarryQueueIdx + ifCarryCount; c++)
    633680            {
    634681                Value* carryq_value = genCarryInLoad(c);
    635                 if_carry_accum_value = bIfBody.CreateOr(carryq_value, if_carry_accum_value);
     682                carry_summary = bIfBody.CreateOr(carry_summary, carryq_value);
    636683            }
    637             genCarryOutStore(if_carry_accum_value, if_accum_idx);
    638 
    639         }
    640         if (if_start_idx_advance < if_end_idx_advance + 1) {
    641             // Have at least two internal advances.   Accumulate and store.
    642             int if_accum_idx = mAdvanceQueueIdx++;
    643 
    644             Value* if_advance_accum_value = genAdvanceInLoad(if_start_idx_advance);
    645 
    646             for (int c = if_start_idx_advance+1; c < if_end_idx_advance; c++)
     684            // Note that the limit in the following uses -1, because
     685            // last entry of the advance queue is for the summary variable.
     686            for (int c = baseAdvanceQueueIdx; c < baseAdvanceQueueIdx + ifAdvanceCount - 1; c++)
    647687            {
    648688                Value* advance_q_value = genAdvanceInLoad(c);
    649                 if_advance_accum_value = bIfBody.CreateOr(advance_q_value, if_advance_accum_value);
     689                carry_summary = bIfBody.CreateOr(advance_q_value, carry_summary);
    650690            }
    651             genAdvanceOutStore(if_advance_accum_value, if_accum_idx);
    652 
     691            genAdvanceOutStore(carry_summary, mAdvanceQueueIdx++); //baseAdvanceQueueIdx + ifAdvanceCount - 1);
    653692        }
    654693        bIfBody.CreateBr(ifEndBlock);
    655694
    656         IRBuilder<> b_entry(ifEntryBlock);
    657         mBasicBlock = ifEntryBlock;
    658         if (if_start_idx < if_end_idx) {
    659             // Have at least one internal carry.
    660             int if_accum_idx = mCarryQueueIdx - 1;
    661             Value* last_if_pending_carries = genCarryInLoad(if_accum_idx);
    662             if_test_value = b_entry.CreateOr(if_test_value, last_if_pending_carries);
    663         }
    664         if (if_start_idx_advance < if_end_idx_advance) {
    665             // Have at least one internal carry.
    666             int if_accum_idx = mAdvanceQueueIdx - 1;
    667             Value* last_if_pending_advances = genAdvanceInLoad(if_accum_idx);
    668             if_test_value = b_entry.CreateOr(if_test_value, last_if_pending_advances);
    669         }
    670         b_entry.CreateCondBr(genBitBlockAny(if_test_value), ifEndBlock, ifBodyBlock);
    671 
     695        //End Block
     696        IRBuilder<> bEnd(ifEndBlock);
    672697        mBasicBlock = ifEndBlock;
    673         --mNestingDepth;
     698       
     699        for (const Assign * a : ifStatement->getDefined()) {
     700            PHINode * phi = bEnd.CreatePHI(mBitBlockType, 2, a->getName()->str());
     701            auto f = mMarkerMap.find(a->getName());
     702            assert (f != mMarkerMap.end());
     703            phi->addIncoming(mZeroInitializer, ifEntryBlock);
     704            phi->addIncoming(f->second, ifBodyBlock);
     705            mMarkerMap[a->getName()] = phi;
     706        }
    674707    }
    675708    else if (const While * whileStatement = dyn_cast<const While>(stmt))
  • icGREP/icgrep-devel/icgrep/pablo/ps_if.h

    r4288 r4344  
    4343        return mBody;
    4444    }
     45    inline const std::vector<Assign *> & getDefined() const {
     46        return mDefined;
     47    }
    4548    inline void setInclusiveCarryCount(const unsigned count) {
    4649        mCarryCount = count;
     
    5659    }
    5760protected:
    58     If(PabloAST * expr, StatementList && body, StatementList * parent)
     61    If(PabloAST * expr, std::vector<Assign *> && definedVars, StatementList && body, StatementList * parent)
    5962    : Statement(ClassTypeId::If, parent)
    6063    , mExpr(expr)
    6164    , mBody(std::move(body))
     65    , mDefined(std::move(definedVars))
    6266    , mCarryCount(0)
    6367    , mAdvanceCount(0)
     
    7074    PabloAST *          mExpr;
    7175    StatementList       mBody;
     76    std::vector<Assign *>    mDefined;
    7277    unsigned            mCarryCount;
    7378    unsigned            mAdvanceCount;
Note: See TracChangeset for help on using the changeset viewer.