| 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 // (meaning we look for opportunities for two overlapping live ranges to | 91 // (meaning we look for opportunities for two overlapping live ranges to |
| 92 // safely share the same register). However, we disable it for phi-lowering | 92 // safely share the same register). However, we disable it for phi-lowering |
| 93 // register allocation since no overlap opportunities should be available and | 93 // register allocation since no overlap opportunities should be available and |
| 94 // it's more expensive to look for opportunities. | 94 // it's more expensive to look for opportunities. |
| 95 FindOverlap = (Kind != RAK_Phi); | 95 FindOverlap = (Kind != RAK_Phi); |
| 96 const VarList &Vars = Func->getVariables(); | 96 const VarList &Vars = Func->getVariables(); |
| 97 Unhandled.reserve(Vars.size()); | 97 Unhandled.reserve(Vars.size()); |
| 98 UnhandledPrecolored.reserve(Vars.size()); | 98 UnhandledPrecolored.reserve(Vars.size()); |
| 99 // Gather the live ranges of all variables and add them to the Unhandled set. | 99 // Gather the live ranges of all variables and add them to the Unhandled set. |
| 100 for (Variable *Var : Vars) { | 100 for (Variable *Var : Vars) { |
| 101 // Don't consider rematerializable variables. |
| 102 if (Var->isRematerializable()) |
| 103 continue; |
| 101 // Explicitly don't consider zero-weight variables, which are meant to be | 104 // Explicitly don't consider zero-weight variables, which are meant to be |
| 102 // spill slots. | 105 // spill slots. |
| 103 if (Var->mustNotHaveReg()) | 106 if (Var->mustNotHaveReg()) |
| 104 continue; | 107 continue; |
| 105 // Don't bother if the variable has a null live range, which means it was | 108 // Don't bother if the variable has a null live range, which means it was |
| 106 // never referenced. | 109 // never referenced. |
| 107 if (Var->getLiveRange().isEmpty()) | 110 if (Var->getLiveRange().isEmpty()) |
| 108 continue; | 111 continue; |
| 109 Var->untrimLiveRange(); | 112 Var->untrimLiveRange(); |
| 110 Unhandled.push_back(Var); | 113 Unhandled.push_back(Var); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 // Iterate across all instructions and record the begin and end of the live | 197 // Iterate across all instructions and record the begin and end of the live |
| 195 // range for each variable that is pre-colored or infinite weight. | 198 // range for each variable that is pre-colored or infinite weight. |
| 196 CfgVector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel); | 199 CfgVector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel); |
| 197 CfgVector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel); | 200 CfgVector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel); |
| 198 DefUseErrorList DefsWithoutUses, UsesBeforeDefs; | 201 DefUseErrorList DefsWithoutUses, UsesBeforeDefs; |
| 199 for (CfgNode *Node : Func->getNodes()) { | 202 for (CfgNode *Node : Func->getNodes()) { |
| 200 for (Inst &Inst : Node->getInsts()) { | 203 for (Inst &Inst : Node->getInsts()) { |
| 201 if (Inst.isDeleted()) | 204 if (Inst.isDeleted()) |
| 202 continue; | 205 continue; |
| 203 FOREACH_VAR_IN_INST(Var, Inst) { | 206 FOREACH_VAR_IN_INST(Var, Inst) { |
| 207 if (Var->isRematerializable()) |
| 208 continue; |
| 204 if (Var->getIgnoreLiveness()) | 209 if (Var->getIgnoreLiveness()) |
| 205 continue; | 210 continue; |
| 206 if (Var->hasReg() || Var->mustHaveReg()) { | 211 if (Var->hasReg() || Var->mustHaveReg()) { |
| 207 SizeT VarNum = Var->getIndex(); | 212 SizeT VarNum = Var->getIndex(); |
| 208 LREnd[VarNum] = Inst.getNumber(); | 213 LREnd[VarNum] = Inst.getNumber(); |
| 209 if (!Var->getIsArg() && LRBegin[VarNum] == Inst::NumberSentinel) | 214 if (!Var->getIsArg() && LRBegin[VarNum] == Inst::NumberSentinel) |
| 210 UsesBeforeDefs.push_back(VarNum); | 215 UsesBeforeDefs.push_back(VarNum); |
| 211 } | 216 } |
| 212 } | 217 } |
| 213 if (const Variable *Var = Inst.getDest()) { | 218 if (const Variable *Var = Inst.getDest()) { |
| 214 if (!Var->getIgnoreLiveness() && | 219 if (!Var->isRematerializable() && !Var->getIgnoreLiveness() && |
| 215 (Var->hasReg() || Var->mustHaveReg())) { | 220 (Var->hasReg() || Var->mustHaveReg())) { |
| 216 if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) { | 221 if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) { |
| 217 LRBegin[Var->getIndex()] = Inst.getNumber(); | 222 LRBegin[Var->getIndex()] = Inst.getNumber(); |
| 218 ++NumVars; | 223 ++NumVars; |
| 219 } | 224 } |
| 220 } | 225 } |
| 221 } | 226 } |
| 222 } | 227 } |
| 223 } | 228 } |
| 224 | 229 |
| 225 Unhandled.reserve(NumVars); | 230 Unhandled.reserve(NumVars); |
| 226 UnhandledPrecolored.reserve(NumVars); | 231 UnhandledPrecolored.reserve(NumVars); |
| 227 for (SizeT i = 0; i < Vars.size(); ++i) { | 232 for (SizeT i = 0; i < Vars.size(); ++i) { |
| 228 Variable *Var = Vars[i]; | 233 Variable *Var = Vars[i]; |
| 234 if (Var->isRematerializable()) |
| 235 continue; |
| 229 if (LRBegin[i] != Inst::NumberSentinel) { | 236 if (LRBegin[i] != Inst::NumberSentinel) { |
| 230 if (LREnd[i] == Inst::NumberSentinel) { | 237 if (LREnd[i] == Inst::NumberSentinel) { |
| 231 DefsWithoutUses.push_back(i); | 238 DefsWithoutUses.push_back(i); |
| 232 continue; | 239 continue; |
| 233 } | 240 } |
| 234 Unhandled.push_back(Var); | 241 Unhandled.push_back(Var); |
| 235 Var->resetLiveRange(); | 242 Var->resetLiveRange(); |
| 236 Var->addLiveRange(LRBegin[i], LREnd[i]); | 243 Var->addLiveRange(LRBegin[i], LREnd[i]); |
| 237 Var->untrimLiveRange(); | 244 Var->untrimLiveRange(); |
| 238 if (Var->hasReg()) { | 245 if (Var->hasReg()) { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 } | 284 } |
| 278 | 285 |
| 279 void LinearScan::initForSecondChance() { | 286 void LinearScan::initForSecondChance() { |
| 280 TimerMarker T(TimerStack::TT_initUnhandled, Func); | 287 TimerMarker T(TimerStack::TT_initUnhandled, Func); |
| 281 FindPreference = true; | 288 FindPreference = true; |
| 282 FindOverlap = true; | 289 FindOverlap = true; |
| 283 const VarList &Vars = Func->getVariables(); | 290 const VarList &Vars = Func->getVariables(); |
| 284 Unhandled.reserve(Vars.size()); | 291 Unhandled.reserve(Vars.size()); |
| 285 UnhandledPrecolored.reserve(Vars.size()); | 292 UnhandledPrecolored.reserve(Vars.size()); |
| 286 for (Variable *Var : Vars) { | 293 for (Variable *Var : Vars) { |
| 294 if (Var->isRematerializable()) |
| 295 continue; |
| 287 if (Var->hasReg()) { | 296 if (Var->hasReg()) { |
| 288 Var->untrimLiveRange(); | 297 Var->untrimLiveRange(); |
| 289 Var->setRegNumTmp(Var->getRegNum()); | 298 Var->setRegNumTmp(Var->getRegNum()); |
| 290 Var->setMustHaveReg(); | 299 Var->setMustHaveReg(); |
| 291 UnhandledPrecolored.push_back(Var); | 300 UnhandledPrecolored.push_back(Var); |
| 292 Unhandled.push_back(Var); | 301 Unhandled.push_back(Var); |
| 293 } | 302 } |
| 294 } | 303 } |
| 295 for (Variable *Var : Evicted) { | 304 for (Variable *Var : Evicted) { |
| 296 Var->untrimLiveRange(); | 305 Var->untrimLiveRange(); |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 } | 569 } |
| 561 } | 570 } |
| 562 } | 571 } |
| 563 | 572 |
| 564 // Remove registers from the Free[] list where an Unhandled pre-colored range | 573 // Remove registers from the Free[] list where an Unhandled pre-colored range |
| 565 // overlaps with the current range, and set those registers to infinite weight | 574 // overlaps with the current range, and set those registers to infinite weight |
| 566 // so that they aren't candidates for eviction. Cur->rangeEndsBefore(Item) is an | 575 // so that they aren't candidates for eviction. Cur->rangeEndsBefore(Item) is an |
| 567 // early exit check that turns a guaranteed O(N^2) algorithm into expected | 576 // early exit check that turns a guaranteed O(N^2) algorithm into expected |
| 568 // linear complexity. | 577 // linear complexity. |
| 569 void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) { | 578 void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) { |
| 579 // TODO(stichnot): Partition UnhandledPrecolored according to register class, |
| 580 // to restrict the number of overlap comparisons needed. |
| 570 for (Variable *Item : reverse_range(UnhandledPrecolored)) { | 581 for (Variable *Item : reverse_range(UnhandledPrecolored)) { |
| 571 assert(Item->hasReg()); | 582 assert(Item->hasReg()); |
| 572 if (Iter.Cur->rangeEndsBefore(Item)) | 583 if (Iter.Cur->rangeEndsBefore(Item)) |
| 573 break; | 584 break; |
| 574 if (!Item->rangeOverlaps(Iter.Cur)) | 585 if (!Item->rangeOverlaps(Iter.Cur)) |
| 575 continue; | 586 continue; |
| 576 const llvm::SmallBitVector &Aliases = | 587 const llvm::SmallBitVector &Aliases = |
| 577 *RegAliases[Item->getRegNum()]; // Note: not getRegNumTmp() | 588 *RegAliases[Item->getRegNum()]; // Note: not getRegNumTmp() |
| 578 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; | 589 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 579 RegAlias = Aliases.find_next(RegAlias)) { | 590 RegAlias = Aliases.find_next(RegAlias)) { |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 966 Str << "\n"; | 977 Str << "\n"; |
| 967 } | 978 } |
| 968 Str << "++++++ Inactive:\n"; | 979 Str << "++++++ Inactive:\n"; |
| 969 for (const Variable *Item : Inactive) { | 980 for (const Variable *Item : Inactive) { |
| 970 dumpLiveRange(Item, Func); | 981 dumpLiveRange(Item, Func); |
| 971 Str << "\n"; | 982 Str << "\n"; |
| 972 } | 983 } |
| 973 } | 984 } |
| 974 | 985 |
| 975 } // end of namespace Ice | 986 } // end of namespace Ice |
| OLD | NEW |