| OLD | NEW |
| 1 //===- subzero/src/IceRegAlloc.cpp - Linear-scan implementation -----------===// | 1 //===- subzero/src/IceRegAlloc.cpp - Linear-scan 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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 // register allocation since no overlap opportunities should be available and | 92 // register allocation since no overlap opportunities should be available and |
| 93 // it's more expensive to look for opportunities. | 93 // it's more expensive to look for opportunities. |
| 94 FindOverlap = (Kind != RAK_Phi); | 94 FindOverlap = (Kind != RAK_Phi); |
| 95 const VarList &Vars = Func->getVariables(); | 95 const VarList &Vars = Func->getVariables(); |
| 96 Unhandled.reserve(Vars.size()); | 96 Unhandled.reserve(Vars.size()); |
| 97 UnhandledPrecolored.reserve(Vars.size()); | 97 UnhandledPrecolored.reserve(Vars.size()); |
| 98 // Gather the live ranges of all variables and add them to the Unhandled set. | 98 // Gather the live ranges of all variables and add them to the Unhandled set. |
| 99 for (Variable *Var : Vars) { | 99 for (Variable *Var : Vars) { |
| 100 // Explicitly don't consider zero-weight variables, which are meant to be | 100 // Explicitly don't consider zero-weight variables, which are meant to be |
| 101 // spill slots. | 101 // spill slots. |
| 102 if (Var->getWeight().isZero()) | 102 if (Var->mustNotHaveReg()) |
| 103 continue; | 103 continue; |
| 104 // Don't bother if the variable has a null live range, which means it was | 104 // Don't bother if the variable has a null live range, which means it was |
| 105 // never referenced. | 105 // never referenced. |
| 106 if (Var->getLiveRange().isEmpty()) | 106 if (Var->getLiveRange().isEmpty()) |
| 107 continue; | 107 continue; |
| 108 Var->untrimLiveRange(); | 108 Var->untrimLiveRange(); |
| 109 Unhandled.push_back(Var); | 109 Unhandled.push_back(Var); |
| 110 if (Var->hasReg()) { | 110 if (Var->hasReg()) { |
| 111 Var->setRegNumTmp(Var->getRegNum()); | 111 Var->setRegNumTmp(Var->getRegNum()); |
| 112 Var->setLiveRangeInfiniteWeight(); | 112 Var->setMustHaveReg(); |
| 113 UnhandledPrecolored.push_back(Var); | 113 UnhandledPrecolored.push_back(Var); |
| 114 } | 114 } |
| 115 } | 115 } |
| 116 | 116 |
| 117 // Build the (ordered) list of FakeKill instruction numbers. | 117 // Build the (ordered) list of FakeKill instruction numbers. |
| 118 Kills.clear(); | 118 Kills.clear(); |
| 119 // Phi lowering should not be creating new call instructions, so there should | 119 // Phi lowering should not be creating new call instructions, so there should |
| 120 // be no infinite-weight not-yet-colored live ranges that span a call | 120 // be no infinite-weight not-yet-colored live ranges that span a call |
| 121 // instruction, hence no need to construct the Kills list. | 121 // instruction, hence no need to construct the Kills list. |
| 122 if (Kind == RAK_Phi) | 122 if (Kind == RAK_Phi) |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 // Iterate across all instructions and record the begin and end of the live | 166 // Iterate across all instructions and record the begin and end of the live |
| 167 // range for each variable that is pre-colored or infinite weight. | 167 // range for each variable that is pre-colored or infinite weight. |
| 168 std::vector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel); | 168 std::vector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel); |
| 169 std::vector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel); | 169 std::vector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel); |
| 170 for (CfgNode *Node : Func->getNodes()) { | 170 for (CfgNode *Node : Func->getNodes()) { |
| 171 for (Inst &Inst : Node->getInsts()) { | 171 for (Inst &Inst : Node->getInsts()) { |
| 172 if (Inst.isDeleted()) | 172 if (Inst.isDeleted()) |
| 173 continue; | 173 continue; |
| 174 if (const Variable *Var = Inst.getDest()) { | 174 if (const Variable *Var = Inst.getDest()) { |
| 175 if (!Var->getIgnoreLiveness() && | 175 if (!Var->getIgnoreLiveness() && |
| 176 (Var->hasReg() || Var->getWeight().isInf())) { | 176 (Var->hasReg() || Var->mustHaveReg())) { |
| 177 if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) { | 177 if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) { |
| 178 LRBegin[Var->getIndex()] = Inst.getNumber(); | 178 LRBegin[Var->getIndex()] = Inst.getNumber(); |
| 179 ++NumVars; | 179 ++NumVars; |
| 180 } | 180 } |
| 181 } | 181 } |
| 182 } | 182 } |
| 183 for (SizeT I = 0; I < Inst.getSrcSize(); ++I) { | 183 for (SizeT I = 0; I < Inst.getSrcSize(); ++I) { |
| 184 Operand *Src = Inst.getSrc(I); | 184 Operand *Src = Inst.getSrc(I); |
| 185 SizeT NumVars = Src->getNumVars(); | 185 SizeT NumVars = Src->getNumVars(); |
| 186 for (SizeT J = 0; J < NumVars; ++J) { | 186 for (SizeT J = 0; J < NumVars; ++J) { |
| 187 const Variable *Var = Src->getVar(J); | 187 const Variable *Var = Src->getVar(J); |
| 188 if (Var->getIgnoreLiveness()) | 188 if (Var->getIgnoreLiveness()) |
| 189 continue; | 189 continue; |
| 190 if (Var->hasReg() || Var->getWeight().isInf()) | 190 if (Var->hasReg() || Var->mustHaveReg()) |
| 191 LREnd[Var->getIndex()] = Inst.getNumber(); | 191 LREnd[Var->getIndex()] = Inst.getNumber(); |
| 192 } | 192 } |
| 193 } | 193 } |
| 194 } | 194 } |
| 195 } | 195 } |
| 196 | 196 |
| 197 Unhandled.reserve(NumVars); | 197 Unhandled.reserve(NumVars); |
| 198 UnhandledPrecolored.reserve(NumVars); | 198 UnhandledPrecolored.reserve(NumVars); |
| 199 for (SizeT i = 0; i < Vars.size(); ++i) { | 199 for (SizeT i = 0; i < Vars.size(); ++i) { |
| 200 Variable *Var = Vars[i]; | 200 Variable *Var = Vars[i]; |
| 201 if (LRBegin[i] != Inst::NumberSentinel) { | 201 if (LRBegin[i] != Inst::NumberSentinel) { |
| 202 assert(LREnd[i] != Inst::NumberSentinel); | 202 assert(LREnd[i] != Inst::NumberSentinel); |
| 203 Unhandled.push_back(Var); | 203 Unhandled.push_back(Var); |
| 204 Var->resetLiveRange(); | 204 Var->resetLiveRange(); |
| 205 constexpr uint32_t WeightDelta = 1; | 205 Var->addLiveRange(LRBegin[i], LREnd[i]); |
| 206 Var->addLiveRange(LRBegin[i], LREnd[i], WeightDelta); | |
| 207 Var->untrimLiveRange(); | 206 Var->untrimLiveRange(); |
| 208 if (Var->hasReg()) { | 207 if (Var->hasReg()) { |
| 209 Var->setRegNumTmp(Var->getRegNum()); | 208 Var->setRegNumTmp(Var->getRegNum()); |
| 210 Var->setLiveRangeInfiniteWeight(); | 209 Var->setMustHaveReg(); |
| 211 UnhandledPrecolored.push_back(Var); | 210 UnhandledPrecolored.push_back(Var); |
| 212 } | 211 } |
| 213 --NumVars; | 212 --NumVars; |
| 214 } | 213 } |
| 215 } | 214 } |
| 216 // This isn't actually a fatal condition, but it would be nice to know if we | 215 // This isn't actually a fatal condition, but it would be nice to know if we |
| 217 // somehow pre-calculated Unhandled's size wrong. | 216 // somehow pre-calculated Unhandled's size wrong. |
| 218 assert(NumVars == 0); | 217 assert(NumVars == 0); |
| 219 | 218 |
| 220 // Don't build up the list of Kills because we know that no infinite-weight | 219 // Don't build up the list of Kills because we know that no infinite-weight |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 512 ++RegUses[RegNum]; | 511 ++RegUses[RegNum]; |
| 513 Active.push_back(Iter.Cur); | 512 Active.push_back(Iter.Cur); |
| 514 } | 513 } |
| 515 | 514 |
| 516 void LinearScan::handleNoFreeRegisters(IterationState &Iter) { | 515 void LinearScan::handleNoFreeRegisters(IterationState &Iter) { |
| 517 // Check Active ranges. | 516 // Check Active ranges. |
| 518 for (const Variable *Item : Active) { | 517 for (const Variable *Item : Active) { |
| 519 assert(Item->rangeOverlaps(Iter.Cur)); | 518 assert(Item->rangeOverlaps(Iter.Cur)); |
| 520 int32_t RegNum = Item->getRegNumTmp(); | 519 int32_t RegNum = Item->getRegNumTmp(); |
| 521 assert(Item->hasRegTmp()); | 520 assert(Item->hasRegTmp()); |
| 522 Iter.Weights[RegNum].addWeight(Item->getLiveRange().getWeight()); | 521 Iter.Weights[RegNum].addWeight(Item->getWeight(Func)); |
| 523 } | 522 } |
| 524 // Same as above, but check Inactive ranges instead of Active. | 523 // Same as above, but check Inactive ranges instead of Active. |
| 525 for (const Variable *Item : Inactive) { | 524 for (const Variable *Item : Inactive) { |
| 526 int32_t RegNum = Item->getRegNumTmp(); | 525 int32_t RegNum = Item->getRegNumTmp(); |
| 527 assert(Item->hasRegTmp()); | 526 assert(Item->hasRegTmp()); |
| 528 if (Item->rangeOverlaps(Iter.Cur)) | 527 if (Item->rangeOverlaps(Iter.Cur)) |
| 529 Iter.Weights[RegNum].addWeight(Item->getLiveRange().getWeight()); | 528 Iter.Weights[RegNum].addWeight(Item->getWeight(Func)); |
| 530 } | 529 } |
| 531 | 530 |
| 532 // All the weights are now calculated. Find the register with smallest | 531 // All the weights are now calculated. Find the register with smallest |
| 533 // weight. | 532 // weight. |
| 534 int32_t MinWeightIndex = Iter.RegMask.find_first(); | 533 int32_t MinWeightIndex = Iter.RegMask.find_first(); |
| 535 // MinWeightIndex must be valid because of the initial RegMask.any() test. | 534 // MinWeightIndex must be valid because of the initial RegMask.any() test. |
| 536 assert(MinWeightIndex >= 0); | 535 assert(MinWeightIndex >= 0); |
| 537 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) { | 536 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) { |
| 538 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex]) | 537 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex]) |
| 539 MinWeightIndex = i; | 538 MinWeightIndex = i; |
| 540 } | 539 } |
| 541 | 540 |
| 542 if (Iter.Cur->getLiveRange().getWeight() <= Iter.Weights[MinWeightIndex]) { | 541 if (Iter.Cur->getWeight(Func) <= Iter.Weights[MinWeightIndex]) { |
| 543 // Cur doesn't have priority over any other live ranges, so don't allocate | 542 // Cur doesn't have priority over any other live ranges, so don't allocate |
| 544 // any register to it, and move it to the Handled state. | 543 // any register to it, and move it to the Handled state. |
| 545 Handled.push_back(Iter.Cur); | 544 Handled.push_back(Iter.Cur); |
| 546 if (Iter.Cur->getLiveRange().getWeight().isInf()) { | 545 if (Iter.Cur->mustHaveReg()) { |
| 547 if (Kind == RAK_Phi) | 546 if (Kind == RAK_Phi) |
| 548 addSpillFill(Iter); | 547 addSpillFill(Iter); |
| 549 else | 548 else |
| 550 Func->setError("Unable to find a physical register for an " | 549 Func->setError("Unable to find a physical register for an " |
| 551 "infinite-weight live range"); | 550 "infinite-weight live range"); |
| 552 } | 551 } |
| 553 } else { | 552 } else { |
| 554 // Evict all live ranges in Active that register number MinWeightIndex is | 553 // Evict all live ranges in Active that register number MinWeightIndex is |
| 555 // assigned to. | 554 // assigned to. |
| 556 for (SizeT I = Active.size(); I > 0; --I) { | 555 for (SizeT I = Active.size(); I > 0; --I) { |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 838 Str << "\n"; | 837 Str << "\n"; |
| 839 } | 838 } |
| 840 Str << "++++++ Inactive:\n"; | 839 Str << "++++++ Inactive:\n"; |
| 841 for (const Variable *Item : Inactive) { | 840 for (const Variable *Item : Inactive) { |
| 842 dumpLiveRange(Item, Func); | 841 dumpLiveRange(Item, Func); |
| 843 Str << "\n"; | 842 Str << "\n"; |
| 844 } | 843 } |
| 845 } | 844 } |
| 846 | 845 |
| 847 } // end of namespace Ice | 846 } // end of namespace Ice |
| OLD | NEW |