Changeset 4344
 Timestamp:
 Dec 17, 2014, 5:05:34 PM (4 years ago)
 Location:
 icGREP/icgrepdevel/icgrep/pablo
 Files:

 3 edited
Legend:
 Unmodified
 Added
 Removed

icGREP/icgrepdevel/icgrep/pablo/codegenstate.h
r4280 r4344 116 116 PabloAST * createSel(PabloAST * condition, PabloAST * trueExpr, PabloAST * falseExpr); 117 117 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); 120 120 mStatements.push_back(statement); 121 121 return statement; 
icGREP/icgrepdevel/icgrep/pablo/pablo_compiler.cpp
r4343 r4344 269 269 LLVM_Gen_RetVal retVal; 270 270 //Return the required size of the carry queue and a pointer to the process_block function. 271 retVal.carry_q_size = mCarryQueue Size;272 retVal.advance_q_size = mAdvanceQueue Size;271 retVal.carry_q_size = mCarryQueueVector.size(); 272 retVal.advance_q_size = mAdvanceQueueVector.size(); 273 273 retVal.process_block_fptr = mExecutionEngine>getPointerToFunction(mFunction); 274 274 … … 473 473 const auto preIfAdvanceCount = mAdvanceQueueSize; 474 474 Examine(ifStatement>getCondition()); 475 mMaxNestingDepth = std::max(mMaxNestingDepth, ++mNestingDepth);476 475 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); 480 484 } 481 485 else if (While * whileStatement = dyn_cast<While>(stmt)) { … … 580 584 581 585 void PabloCompiler::compileStatements(const StatementList & stmts) { 582 Value * retVal = nullptr;583 586 for (const PabloAST * statement : stmts) { 584 587 compileStatement(statement); … … 601 604 mMarkerMap[next>getName()] = expr; 602 605 } 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 IfElseZero 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. 606 626 BasicBlock * ifBodyBlock = BasicBlock::Create(mMod>getContext(), "if.body", mFunction, 0); 607 627 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 617 667 IRBuilder<> bIfBody(ifBodyBlock); 618 668 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++) 633 680 { 634 681 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); 636 683 } 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++) 647 687 { 648 688 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); 650 690 } 651 genAdvanceOutStore(if_advance_accum_value, if_accum_idx); 652 691 genAdvanceOutStore(carry_summary, mAdvanceQueueIdx++); //baseAdvanceQueueIdx + ifAdvanceCount  1); 653 692 } 654 693 bIfBody.CreateBr(ifEndBlock); 655 694 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); 672 697 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 } 674 707 } 675 708 else if (const While * whileStatement = dyn_cast<const While>(stmt)) 
icGREP/icgrepdevel/icgrep/pablo/ps_if.h
r4288 r4344 43 43 return mBody; 44 44 } 45 inline const std::vector<Assign *> & getDefined() const { 46 return mDefined; 47 } 45 48 inline void setInclusiveCarryCount(const unsigned count) { 46 49 mCarryCount = count; … … 56 59 } 57 60 protected: 58 If(PabloAST * expr, StatementList && body, StatementList * parent)61 If(PabloAST * expr, std::vector<Assign *> && definedVars, StatementList && body, StatementList * parent) 59 62 : Statement(ClassTypeId::If, parent) 60 63 , mExpr(expr) 61 64 , mBody(std::move(body)) 65 , mDefined(std::move(definedVars)) 62 66 , mCarryCount(0) 63 67 , mAdvanceCount(0) … … 70 74 PabloAST * mExpr; 71 75 StatementList mBody; 76 std::vector<Assign *> mDefined; 72 77 unsigned mCarryCount; 73 78 unsigned mAdvanceCount;
Note: See TracChangeset
for help on using the changeset viewer.