Changeset 4288 for icGREP/icgrepdevel/icgrep/pablo/pablo_compiler.cpp
 Timestamp:
 Nov 2, 2014, 5:06:13 PM (5 years ago)
 File:

 1 edited
Legend:
 Unmodified
 Added
 Removed

icGREP/icgrepdevel/icgrep/pablo/pablo_compiler.cpp
r4284 r4288 123 123 , mNestingDepth(0) 124 124 , mCarryQueueSize(0) 125 , mAdvanceQueueIdx(0) 126 , mAdvanceQueuePtr(nullptr) 127 , mAdvanceQueueSize(0) 125 128 , mZeroInitializer(ConstantAggregateZero::get(mBitBlockType)) 126 129 , mOneInitializer(ConstantVector::getAllOnesValue(mBitBlockType)) … … 179 182 mMaxNestingDepth = 0; 180 183 mCarryQueueSize = 0; 184 mAdvanceQueueSize = 0; 181 185 Examine(pb.statements()); 182 186 mCarryQueueVector.resize(mCarryQueueSize); 183 187 mAdvanceQueueVector.resize(mAdvanceQueueSize); 184 188 std::string errMessage; 185 189 EngineBuilder builder(mMod); … … 202 206 mCarryQueuePtr = args++; 203 207 mCarryQueuePtr>setName("carry_q"); 208 mAdvanceQueuePtr = args++; 209 mAdvanceQueuePtr>setName("advance_q"); 204 210 mOutputAddrPtr = args++; 205 211 mOutputAddrPtr>setName("output"); 206 212 207 //Create the carry queue.213 //Create the carry and advance queues. 208 214 mCarryQueueIdx = 0; 215 mAdvanceQueueIdx = 0; 209 216 mNestingDepth = 0; 210 217 mMaxNestingDepth = 0; … … 220 227 mMarkerMap.insert(std::make_pair(name, basisBit)); 221 228 } 222 229 223 230 //Generate the IR instructions for the function. 224 231 compileStatements(pb.statements()); 225 232 226 233 assert (mCarryQueueIdx == mCarryQueueSize); 234 assert (mAdvanceQueueIdx == mAdvanceQueueSize); 227 235 assert (mNestingDepth == 0); 228 236 //Terminate the block … … 262 270 //Return the required size of the carry queue and a pointer to the process_block function. 263 271 retVal.carry_q_size = mCarryQueueSize; 272 retVal.advance_q_size = mAdvanceQueueSize; 264 273 retVal.process_block_fptr = mExecutionEngine>getPointerToFunction(mFunction); 265 274 … … 288 297 //The carry q array. 289 298 //A pointer to the BitBlock vector. 299 functionTypeArgs.push_back(PointerType::get(mBitBlockType, 0)); 300 // Advance q array 290 301 functionTypeArgs.push_back(PointerType::get(mBitBlockType, 0)); 291 302 … … 362 373 363 374 //Starts on process_block 364 SmallVector<AttributeSet, 4> Attrs;375 SmallVector<AttributeSet, 5> Attrs; 365 376 AttributeSet PAS; 366 377 { … … 381 392 B.addAttribute(Attribute::NoCapture); 382 393 PAS = AttributeSet::get(mMod>getContext(), 3U, B); 394 } 395 Attrs.push_back(PAS); 396 { 397 AttrBuilder B; 398 B.addAttribute(Attribute::NoCapture); 399 PAS = AttributeSet::get(mMod>getContext(), 4U, B); 383 400 } 384 401 Attrs.push_back(PAS); … … 413 430 else if (If * ifStatement = dyn_cast<If>(stmt)) { 414 431 const auto preIfCarryCount = mCarryQueueSize; 432 const auto preIfAdvanceCount = mAdvanceQueueSize; 415 433 Examine(ifStatement>getCondition()); 416 434 mMaxNestingDepth = std::max(mMaxNestingDepth, ++mNestingDepth); … … 418 436 mNestingDepth; 419 437 ifStatement>setInclusiveCarryCount(mCarryQueueSize  preIfCarryCount); 438 ifStatement>setInclusiveAdvanceCount(mAdvanceQueueSize  preIfAdvanceCount); 420 439 } 421 440 else if (While * whileStatement = dyn_cast<While>(stmt)) { 422 441 const auto preWhileCarryCount = mCarryQueueSize; 442 const auto preWhileAdvanceCount = mAdvanceQueueSize; 423 443 Examine(whileStatement>getCondition()); 424 444 mMaxNestingDepth = std::max(mMaxNestingDepth, ++mNestingDepth); … … 426 446 mNestingDepth; 427 447 whileStatement>setInclusiveCarryCount(mCarryQueueSize  preWhileCarryCount); 448 whileStatement>setInclusiveAdvanceCount(mAdvanceQueueSize  preWhileAdvanceCount); 428 449 } 429 450 } … … 452 473 } 453 474 else if (Advance * adv = dyn_cast<Advance>(expr)) { 454 ++m CarryQueueSize;475 ++mAdvanceQueueSize; 455 476 Examine(adv>getExpr()); 456 477 } … … 550 571 551 572 int if_start_idx = mCarryQueueIdx; 573 int if_start_idx_advance = mAdvanceQueueIdx; 552 574 553 575 Value* if_test_value = compileExpression(ifstmt>getCondition()); … … 564 586 565 587 int if_end_idx = mCarryQueueIdx; 588 int if_end_idx_advance = mAdvanceQueueIdx; 566 589 if (if_start_idx < if_end_idx + 1) { 567 590 // Have at least two internal carries. Accumulate and store. … … 576 599 } 577 600 genCarryOutStore(if_carry_accum_value, if_accum_idx); 601 602 } 603 if (if_start_idx_advance < if_end_idx_advance + 1) { 604 // Have at least two internal advances. Accumulate and store. 605 int if_accum_idx = mAdvanceQueueIdx++; 606 607 Value* if_advance_accum_value = genAdvanceInLoad(if_start_idx_advance); 608 609 for (int c = if_start_idx_advance+1; c < if_end_idx_advance; c++) 610 { 611 Value* advance_q_value = genAdvanceInLoad(c); 612 if_advance_accum_value = bIfBody.CreateOr(advance_q_value, if_advance_accum_value); 613 } 614 genAdvanceOutStore(if_advance_accum_value, if_accum_idx); 578 615 579 616 } … … 588 625 if_test_value = b_entry.CreateOr(if_test_value, last_if_pending_carries); 589 626 } 627 if (if_start_idx_advance < if_end_idx_advance) { 628 // Have at least one internal carry. 629 int if_accum_idx = mAdvanceQueueIdx  1; 630 Value* last_if_pending_advances = genAdvanceInLoad(if_accum_idx); 631 if_test_value = b_entry.CreateOr(if_test_value, last_if_pending_advances); 632 } 590 633 b_entry.CreateCondBr(genBitBlockAny(if_test_value), ifEndBlock, ifBodyBlock); 591 634 … … 598 641 { 599 642 const auto baseCarryQueueIdx = mCarryQueueIdx; 643 const auto baseAdvanceQueueIdx = mAdvanceQueueIdx; 600 644 if (mNestingDepth == 0) { 601 645 for (auto i = 0; i != whileStatement>getInclusiveCarryCount(); ++i) { 602 646 genCarryInLoad(baseCarryQueueIdx + i); 647 } 648 for (auto i = 0; i != whileStatement>getInclusiveAdvanceCount(); ++i) { 649 genAdvanceInLoad(baseAdvanceQueueIdx + i); 603 650 } 604 651 } … … 624 671 // but works for now. 625 672 mCarryQueueIdx = baseCarryQueueIdx; 673 mAdvanceQueueIdx = baseAdvanceQueueIdx; 626 674 627 675 BasicBlock* whileCondBlock = BasicBlock::Create(mMod>getContext(), "while.cond", mFunction, 0); … … 637 685 IRBuilder<> bCond(whileCondBlock); 638 686 // generate phi nodes for any carry propogating instruction 639 std::vector<PHINode*> phiNodes(whileStatement>getInclusiveCarryCount() + nextNodes.size()); 687 int whileCarryCount = whileStatement>getInclusiveCarryCount(); 688 int whileAdvanceCount = whileStatement>getInclusiveAdvanceCount(); 689 std::vector<PHINode*> phiNodes(whileCarryCount + whileAdvanceCount + nextNodes.size()); 640 690 unsigned index = 0; 641 for (index = 0; index != while Statement>getInclusiveCarryCount(); ++index) {691 for (index = 0; index != whileCarryCount; ++index) { 642 692 PHINode * phi = bCond.CreatePHI(mBitBlockType, 2); 643 693 phi>addIncoming(mCarryQueueVector[baseCarryQueueIdx + index], mBasicBlock); 644 694 mCarryQueueVector[baseCarryQueueIdx + index] = mZeroInitializer; // (use phi for multicarry mode.) 645 695 phiNodes[index] = phi; 696 } 697 for (int i = 0; i != whileAdvanceCount; ++i) { 698 PHINode * phi = bCond.CreatePHI(mBitBlockType, 2); 699 phi>addIncoming(mAdvanceQueueVector[baseAdvanceQueueIdx + i], mBasicBlock); 700 mAdvanceQueueVector[baseAdvanceQueueIdx + i] = mZeroInitializer; // (use phi for multicarry mode.) 701 phiNodes[index++] = phi; 646 702 } 647 703 // and for any Next nodes in the loop body … … 669 725 mCarryQueueVector[baseCarryQueueIdx + index] = phi; 670 726 } 727 for (int i = 0; i != whileAdvanceCount; ++i) { 728 Value * advOut = bWhileBody.CreateOr(phiNodes[index], mAdvanceQueueVector[baseAdvanceQueueIdx + i]); 729 PHINode * phi = phiNodes[index++]; 730 phi>addIncoming(advOut, mBasicBlock); 731 mAdvanceQueueVector[baseAdvanceQueueIdx + i] = phi; 732 } 671 733 // and for any Next nodes in the loop body 672 734 for (const Next * n : nextNodes) { … … 683 745 mBasicBlock = whileEndBlock; 684 746 if (mNestingDepth == 0) { 685 for (index = 0; index != while Statement>getInclusiveCarryCount(); ++index) {747 for (index = 0; index != whileCarryCount; ++index) { 686 748 genCarryOutStore(phiNodes[index], baseCarryQueueIdx + index); 749 } 750 for (index = 0; index != whileAdvanceCount; ++index) { 751 genAdvanceOutStore(phiNodes[whileCarryCount + index], baseAdvanceQueueIdx + index); 687 752 } 688 753 } … … 845 910 } 846 911 912 Value* PabloCompiler::genAdvanceInLoad(const unsigned index) { 913 assert (index < mAdvanceQueueVector.size()); 914 if (mNestingDepth == 0) { 915 IRBuilder<> b(mBasicBlock); 916 mAdvanceQueueVector[index] = b.CreateAlignedLoad(b.CreateGEP(mAdvanceQueuePtr, b.getInt64(index)), BLOCK_SIZE/8, false); 917 } 918 return mAdvanceQueueVector[index]; 919 } 920 921 void PabloCompiler::genAdvanceOutStore(Value* advanceOut, const unsigned index ) { 922 assert (advanceOut); 923 assert (index < mAdvanceQueueVector.size()); 924 if (mNestingDepth == 0) { 925 IRBuilder<> b(mBasicBlock); 926 b.CreateAlignedStore(advanceOut, b.CreateGEP(mAdvanceQueuePtr, b.getInt64(index)), BLOCK_SIZE/8, false); 927 } 928 mAdvanceQueueVector[index] = advanceOut; 929 } 930 847 931 inline Value* PabloCompiler::genBitBlockAny(Value* test) { 848 932 IRBuilder<> b(mBasicBlock); … … 872 956 IRBuilder<> b(mBasicBlock); 873 957 #if (BLOCK_SIZE == 128) 874 const auto carryIdx = mCarryQueueIdx++;958 const auto advanceIdx = mAdvanceQueueIdx++; 875 959 if (shift_amount == 1) { 876 Value* carryq_value = genCarryInLoad(carryIdx);960 Value* advanceq_value = genAdvanceInLoad(advanceIdx); 877 961 Value* srli_1_value = b.CreateLShr(strm_value, 63); 878 962 Value* packed_shuffle; 879 963 Constant* const_packed_1_elems [] = {b.getInt32(0), b.getInt32(2)}; 880 964 Constant* const_packed_1 = ConstantVector::get(const_packed_1_elems); 881 packed_shuffle = b.CreateShuffleVector( carryq_value, srli_1_value, const_packed_1);965 packed_shuffle = b.CreateShuffleVector(advanceq_value, srli_1_value, const_packed_1); 882 966 883 967 Constant* const_packed_2_elems[] = {b.getInt64(1), b.getInt64(1)}; … … 887 971 Value* result_value = b.CreateOr(shl_value, packed_shuffle, "advance"); 888 972 889 Value* carry_out = genShiftHighbitToLow(strm_value, "carry_out");973 Value* advance_out = genShiftHighbitToLow(strm_value, "advance_out"); 890 974 //CarryQ  carry out: 891 gen CarryOutStore(carry_out, carryIdx);975 genAdvanceOutStore(advance_out, advanceIdx); 892 976 893 977 return result_value; … … 896 980 // This is the preferred logic, but is too slow for the general case. 897 981 // We need to speed up our custom LLVM for this code. 898 Value* carryq_longint = b.CreateBitCast(genCarryInLoad(carryIdx), IntegerType::get(mMod>getContext(), BLOCK_SIZE));982 Value* advanceq_longint = b.CreateBitCast(genAdvanceInLoad(advanceIdx), IntegerType::get(mMod>getContext(), BLOCK_SIZE)); 899 983 Value* strm_longint = b.CreateBitCast(strm_value, IntegerType::get(mMod>getContext(), BLOCK_SIZE)); 900 Value* adv_longint = b.CreateOr(b.CreateShl(strm_longint, shift_amount), carryq_longint, "advance"); 901 Value* result_value = b.CreateBitCast(adv_longint, mBitBlockType); 902 Value* carry_out = b.CreateBitCast(b.CreateLShr(strm_longint, BLOCK_SIZE  shift_amount, "advance_out"), mBitBlockType); 903 //CarryQ  carry out: 904 genCarryOutStore(carry_out, carryIdx); 984 Value* adv_longint = b.CreateOr(b.CreateShl(strm_longint, shift_amount), advanceq_longint, "advance"); 985 Value* result_value = b.CreateBitCast(adv_longint, mBitBlockType); 986 Value* advance_out = b.CreateBitCast(b.CreateLShr(strm_longint, BLOCK_SIZE  shift_amount, "advance_out"), mBitBlockType); 987 genAdvanceOutStore(advance_out, advanceIdx); 905 988 906 989 return result_value;
Note: See TracChangeset
for help on using the changeset viewer.