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 |