| OLD | NEW |
| 1 //===- subzero/src/IceCfgNode.cpp - Basic block (node) implementation -----===// | 1 //===- subzero/src/IceCfgNode.cpp - Basic block (node) implementation -----===// |
| 2 // | 2 // |
| 3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 /// | 9 /// |
| 10 /// \file | 10 /// \file |
| (...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 674 // Check result, set LiveIn=Live | 674 // Check result, set LiveIn=Live |
| 675 SizeT &PrevNumNonDeadPhis = Liveness->getNumNonDeadPhis(this); | 675 SizeT &PrevNumNonDeadPhis = Liveness->getNumNonDeadPhis(this); |
| 676 bool LiveInChanged = (Live != LiveIn); | 676 bool LiveInChanged = (Live != LiveIn); |
| 677 Changed = (NumNonDeadPhis != PrevNumNonDeadPhis || LiveInChanged); | 677 Changed = (NumNonDeadPhis != PrevNumNonDeadPhis || LiveInChanged); |
| 678 if (LiveInChanged) | 678 if (LiveInChanged) |
| 679 LiveIn = Live; | 679 LiveIn = Live; |
| 680 PrevNumNonDeadPhis = NumNonDeadPhis; | 680 PrevNumNonDeadPhis = NumNonDeadPhis; |
| 681 return Changed; | 681 return Changed; |
| 682 } | 682 } |
| 683 | 683 |
| 684 // Validate the integrity of the live ranges in this block. If there are any |
| 685 // errors, it prints details and returns false. On success, it returns true. |
| 686 bool CfgNode::livenessValidateIntervals(Liveness *Liveness) { |
| 687 if (!BuildDefs::asserts()) |
| 688 return true; |
| 689 |
| 690 // Verify there are no duplicates. |
| 691 auto ComparePair = |
| 692 [](const LiveBeginEndMapEntry &A, const LiveBeginEndMapEntry &B) { |
| 693 return A.first == B.first; |
| 694 }; |
| 695 LiveBeginEndMap &MapBegin = *Liveness->getLiveBegin(this); |
| 696 LiveBeginEndMap &MapEnd = *Liveness->getLiveEnd(this); |
| 697 if (std::adjacent_find(MapBegin.begin(), MapBegin.end(), ComparePair) == |
| 698 MapBegin.end() && |
| 699 std::adjacent_find(MapEnd.begin(), MapEnd.end(), ComparePair) == |
| 700 MapEnd.end()) |
| 701 return true; |
| 702 |
| 703 // There is definitely a liveness error. All paths from here return false. |
| 704 if (!BuildDefs::dump()) |
| 705 return false; |
| 706 |
| 707 // Print all the errors. |
| 708 if (BuildDefs::dump()) { |
| 709 GlobalContext *Ctx = Func->getContext(); |
| 710 OstreamLocker L(Ctx); |
| 711 Ostream &Str = Ctx->getStrDump(); |
| 712 if (Func->isVerbose()) { |
| 713 Str << "Live range errors in the following block:\n"; |
| 714 dump(Func); |
| 715 } |
| 716 for (auto Start = MapBegin.begin(); |
| 717 (Start = std::adjacent_find(Start, MapBegin.end(), ComparePair)) != |
| 718 MapBegin.end(); |
| 719 ++Start) { |
| 720 auto Next = Start + 1; |
| 721 Str << "Duplicate LR begin, block " << getName() << ", instructions " |
| 722 << Start->second << " & " << Next->second << ", variable " |
| 723 << Liveness->getVariable(Start->first, this)->getName(Func) << "\n"; |
| 724 } |
| 725 for (auto Start = MapEnd.begin(); |
| 726 (Start = std::adjacent_find(Start, MapEnd.end(), ComparePair)) != |
| 727 MapEnd.end(); |
| 728 ++Start) { |
| 729 auto Next = Start + 1; |
| 730 Str << "Duplicate LR end, block " << getName() << ", instructions " |
| 731 << Start->second << " & " << Next->second << ", variable " |
| 732 << Liveness->getVariable(Start->first, this)->getName(Func) << "\n"; |
| 733 } |
| 734 } |
| 735 |
| 736 return false; |
| 737 } |
| 738 |
| 684 // Once basic liveness is complete, compute actual live ranges. It is assumed | 739 // Once basic liveness is complete, compute actual live ranges. It is assumed |
| 685 // that within a single basic block, a live range begins at most once and ends | 740 // that within a single basic block, a live range begins at most once and ends |
| 686 // at most once. This is certainly true for pure SSA form. It is also true once | 741 // at most once. This is certainly true for pure SSA form. It is also true once |
| 687 // phis are lowered, since each assignment to the phi-based temporary is in a | 742 // phis are lowered, since each assignment to the phi-based temporary is in a |
| 688 // different basic block, and there is a single read that ends the live in the | 743 // different basic block, and there is a single read that ends the live in the |
| 689 // basic block that contained the actual phi instruction. | 744 // basic block that contained the actual phi instruction. |
| 690 void CfgNode::livenessAddIntervals(Liveness *Liveness, InstNumberT FirstInstNum, | 745 void CfgNode::livenessAddIntervals(Liveness *Liveness, InstNumberT FirstInstNum, |
| 691 InstNumberT LastInstNum) { | 746 InstNumberT LastInstNum) { |
| 692 TimerMarker T1(TimerStack::TT_liveRange, Func); | 747 TimerMarker T1(TimerStack::TT_liveRange, Func); |
| 693 | 748 |
| 694 SizeT NumVars = Liveness->getNumVarsInNode(this); | 749 SizeT NumVars = Liveness->getNumVarsInNode(this); |
| 695 LivenessBV &LiveIn = Liveness->getLiveIn(this); | 750 LivenessBV &LiveIn = Liveness->getLiveIn(this); |
| 696 LivenessBV &LiveOut = Liveness->getLiveOut(this); | 751 LivenessBV &LiveOut = Liveness->getLiveOut(this); |
| 697 LiveBeginEndMap &MapBegin = *Liveness->getLiveBegin(this); | 752 LiveBeginEndMap &MapBegin = *Liveness->getLiveBegin(this); |
| 698 LiveBeginEndMap &MapEnd = *Liveness->getLiveEnd(this); | 753 LiveBeginEndMap &MapEnd = *Liveness->getLiveEnd(this); |
| 699 std::sort(MapBegin.begin(), MapBegin.end()); | 754 std::sort(MapBegin.begin(), MapBegin.end()); |
| 700 std::sort(MapEnd.begin(), MapEnd.end()); | 755 std::sort(MapEnd.begin(), MapEnd.end()); |
| 701 // Verify there are no duplicates. | 756 |
| 702 auto ComparePair = | 757 if (!livenessValidateIntervals(Liveness)) { |
| 703 [](const LiveBeginEndMapEntry &A, const LiveBeginEndMapEntry &B) { | 758 llvm::report_fatal_error("livenessAddIntervals: Liveness error"); |
| 704 return A.first == B.first; | 759 return; |
| 705 }; | 760 } |
| 706 (void)ComparePair; | |
| 707 assert(std::adjacent_find(MapBegin.begin(), MapBegin.end(), ComparePair) == | |
| 708 MapBegin.end()); | |
| 709 assert(std::adjacent_find(MapEnd.begin(), MapEnd.end(), ComparePair) == | |
| 710 MapEnd.end()); | |
| 711 | 761 |
| 712 LivenessBV LiveInAndOut = LiveIn; | 762 LivenessBV LiveInAndOut = LiveIn; |
| 713 LiveInAndOut &= LiveOut; | 763 LiveInAndOut &= LiveOut; |
| 714 | 764 |
| 715 // Iterate in parallel across the sorted MapBegin[] and MapEnd[]. | 765 // Iterate in parallel across the sorted MapBegin[] and MapEnd[]. |
| 716 auto IBB = MapBegin.begin(), IEB = MapEnd.begin(); | 766 auto IBB = MapBegin.begin(), IEB = MapEnd.begin(); |
| 717 auto IBE = MapBegin.end(), IEE = MapEnd.end(); | 767 auto IBE = MapBegin.end(), IEE = MapEnd.end(); |
| 718 while (IBB != IBE || IEB != IEE) { | 768 while (IBB != IBE || IEB != IEE) { |
| 719 SizeT i1 = IBB == IBE ? NumVars : IBB->first; | 769 SizeT i1 = IBB == IBE ? NumVars : IBB->first; |
| 720 SizeT i2 = IEB == IEE ? NumVars : IEB->first; | 770 SizeT i2 = IEB == IEE ? NumVars : IEB->first; |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 868 Str << "\n"; | 918 Str << "\n"; |
| 869 } | 919 } |
| 870 | 920 |
| 871 void emitLiveRangesEnded(Ostream &Str, const Cfg *Func, const Inst *Instr, | 921 void emitLiveRangesEnded(Ostream &Str, const Cfg *Func, const Inst *Instr, |
| 872 CfgVector<SizeT> &LiveRegCount) { | 922 CfgVector<SizeT> &LiveRegCount) { |
| 873 if (!BuildDefs::dump()) | 923 if (!BuildDefs::dump()) |
| 874 return; | 924 return; |
| 875 bool First = true; | 925 bool First = true; |
| 876 Variable *Dest = Instr->getDest(); | 926 Variable *Dest = Instr->getDest(); |
| 877 // Normally we increment the live count for the dest register. But we | 927 // Normally we increment the live count for the dest register. But we |
| 878 // shouldn't if the instruction's IsDestNonKillable flag is set, because this | 928 // shouldn't if the instruction's IsDestRedefined flag is set, because this |
| 879 // means that the target lowering created this instruction as a non-SSA | 929 // means that the target lowering created this instruction as a non-SSA |
| 880 // assignment; i.e., a different, previous instruction started the dest | 930 // assignment; i.e., a different, previous instruction started the dest |
| 881 // variable's live range. | 931 // variable's live range. |
| 882 if (!Instr->isDestNonKillable() && Dest && Dest->hasReg()) | 932 if (!Instr->isDestRedefined() && Dest && Dest->hasReg()) |
| 883 ++LiveRegCount[Dest->getRegNum()]; | 933 ++LiveRegCount[Dest->getRegNum()]; |
| 884 FOREACH_VAR_IN_INST(Var, *Instr) { | 934 FOREACH_VAR_IN_INST(Var, *Instr) { |
| 885 bool ShouldReport = Instr->isLastUse(Var); | 935 bool ShouldReport = Instr->isLastUse(Var); |
| 886 if (ShouldReport && Var->hasReg()) { | 936 if (ShouldReport && Var->hasReg()) { |
| 887 // Don't report end of live range until the live count reaches 0. | 937 // Don't report end of live range until the live count reaches 0. |
| 888 SizeT NewCount = --LiveRegCount[Var->getRegNum()]; | 938 SizeT NewCount = --LiveRegCount[Var->getRegNum()]; |
| 889 if (NewCount) | 939 if (NewCount) |
| 890 ShouldReport = false; | 940 ShouldReport = false; |
| 891 } | 941 } |
| 892 if (ShouldReport) { | 942 if (ShouldReport) { |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1303 InstIntrinsicCall *Inst = InstIntrinsicCall::create( | 1353 InstIntrinsicCall *Inst = InstIntrinsicCall::create( |
| 1304 Func, 5, Func->makeVariable(IceType_i64), RMWI64Name, Info->Info); | 1354 Func, 5, Func->makeVariable(IceType_i64), RMWI64Name, Info->Info); |
| 1305 Inst->addArg(AtomicRMWOp); | 1355 Inst->addArg(AtomicRMWOp); |
| 1306 Inst->addArg(Counter); | 1356 Inst->addArg(Counter); |
| 1307 Inst->addArg(One); | 1357 Inst->addArg(One); |
| 1308 Inst->addArg(OrderAcquireRelease); | 1358 Inst->addArg(OrderAcquireRelease); |
| 1309 Insts.push_front(Inst); | 1359 Insts.push_front(Inst); |
| 1310 } | 1360 } |
| 1311 | 1361 |
| 1312 } // end of namespace Ice | 1362 } // end of namespace Ice |
| OLD | NEW |