Chromium Code Reviews| 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 // This file implements the LinearScan class, which performs the | 10 // This file implements the LinearScan class, which performs the |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 TimerMarker T(IDinitUnhandled, Func->getContext()); | 91 TimerMarker T(IDinitUnhandled, Func->getContext()); |
| 92 for (Variable *Var : Vars) { | 92 for (Variable *Var : Vars) { |
| 93 // Explicitly don't consider zero-weight variables, which are | 93 // Explicitly don't consider zero-weight variables, which are |
| 94 // meant to be spill slots. | 94 // meant to be spill slots. |
| 95 if (Var->getWeight() == RegWeight::Zero) | 95 if (Var->getWeight() == RegWeight::Zero) |
| 96 continue; | 96 continue; |
| 97 // Don't bother if the variable has a null live range, which means | 97 // Don't bother if the variable has a null live range, which means |
| 98 // it was never referenced. | 98 // it was never referenced. |
| 99 if (Var->getLiveRange().isEmpty()) | 99 if (Var->getLiveRange().isEmpty()) |
| 100 continue; | 100 continue; |
| 101 Var->untrimLiveRange(); | |
| 101 LiveRangeWrapper R(Var); | 102 LiveRangeWrapper R(Var); |
| 102 Unhandled.insert(R); | 103 Unhandled.insert(R); |
| 103 if (Var->hasReg()) { | 104 if (Var->hasReg()) { |
| 104 Var->setRegNumTmp(Var->getRegNum()); | 105 Var->setRegNumTmp(Var->getRegNum()); |
| 105 Var->setLiveRangeInfiniteWeight(); | 106 Var->setLiveRangeInfiniteWeight(); |
| 106 UnhandledPrecolored.insert(R); | 107 UnhandledPrecolored.insert(R); |
| 107 } | 108 } |
| 108 } | 109 } |
| 109 } | 110 } |
| 110 | 111 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 assert(UnhandledPrecolored.begin()->Var == Cur.Var); | 153 assert(UnhandledPrecolored.begin()->Var == Cur.Var); |
| 153 UnhandledPrecolored.erase(UnhandledPrecolored.begin()); | 154 UnhandledPrecolored.erase(UnhandledPrecolored.begin()); |
| 154 continue; | 155 continue; |
| 155 } | 156 } |
| 156 | 157 |
| 157 // Check for active ranges that have expired or become inactive. | 158 // Check for active ranges that have expired or become inactive. |
| 158 for (auto I = Active.begin(), E = Active.end(); I != E; I = Next) { | 159 for (auto I = Active.begin(), E = Active.end(); I != E; I = Next) { |
| 159 Next = I; | 160 Next = I; |
| 160 ++Next; | 161 ++Next; |
| 161 LiveRangeWrapper Item = *I; | 162 LiveRangeWrapper Item = *I; |
| 163 Item.Var->trimLiveRange(Cur.range().getStart()); | |
| 162 bool Moved = false; | 164 bool Moved = false; |
| 163 if (Item.endsBefore(Cur)) { | 165 if (Item.endsBefore(Cur)) { |
| 164 // Move Item from Active to Handled list. | 166 // Move Item from Active to Handled list. |
| 165 if (Verbose) { | 167 if (Verbose) { |
| 166 Str << "Expiring "; | 168 Str << "Expiring "; |
| 167 Item.dump(Func); | 169 Item.dump(Func); |
| 168 Str << "\n"; | 170 Str << "\n"; |
| 169 } | 171 } |
| 170 Active.erase(I); | 172 Active.erase(I); |
| 171 Handled.push_back(Item); | 173 Handled.push_back(Item); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 188 --RegUses[RegNum]; | 190 --RegUses[RegNum]; |
| 189 assert(RegUses[RegNum] >= 0); | 191 assert(RegUses[RegNum] >= 0); |
| 190 } | 192 } |
| 191 } | 193 } |
| 192 | 194 |
| 193 // Check for inactive ranges that have expired or reactivated. | 195 // Check for inactive ranges that have expired or reactivated. |
| 194 for (auto I = Inactive.begin(), E = Inactive.end(); I != E; I = Next) { | 196 for (auto I = Inactive.begin(), E = Inactive.end(); I != E; I = Next) { |
| 195 Next = I; | 197 Next = I; |
| 196 ++Next; | 198 ++Next; |
| 197 LiveRangeWrapper Item = *I; | 199 LiveRangeWrapper Item = *I; |
| 200 Item.Var->trimLiveRange(Cur.range().getStart()); | |
| 201 // As an optimization, don't bother checking pure point-valued | |
| 202 // Inactive ranges, because the overlapsStart() test will never | |
| 203 // succeed, and the endsBefore() test will generally only | |
| 204 // succeed after the last call instruction, which statistically | |
| 205 // happens near the end. TODO(stichnot): Consider suppressing | |
| 206 // this check every N iterations in case calls are only at the | |
| 207 // beginning of the function. | |
| 208 if (!Item.range().isNonpoints()) | |
| 209 continue; | |
| 198 if (Item.endsBefore(Cur)) { | 210 if (Item.endsBefore(Cur)) { |
| 199 // Move Item from Inactive to Handled list. | 211 // Move Item from Inactive to Handled list. |
| 200 if (Verbose) { | 212 if (Verbose) { |
| 201 Str << "Expiring "; | 213 Str << "Expiring "; |
| 202 Item.dump(Func); | 214 Item.dump(Func); |
| 203 Str << "\n"; | 215 Str << "\n"; |
| 204 } | 216 } |
| 205 Inactive.erase(I); | 217 Inactive.erase(I); |
| 206 Handled.push_back(Item); | 218 Handled.push_back(Item); |
| 207 } else if (Item.overlapsStart(Cur)) { | 219 } else if (Item.overlapsStart(Cur)) { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 316 | 328 |
| 317 // Remove registers from the Free[] list where an Unhandled | 329 // Remove registers from the Free[] list where an Unhandled |
| 318 // precolored range overlaps with the current range, and set those | 330 // precolored range overlaps with the current range, and set those |
| 319 // registers to infinite weight so that they aren't candidates for | 331 // registers to infinite weight so that they aren't candidates for |
| 320 // eviction. Cur.endsBefore(Item) is an early exit check that | 332 // eviction. Cur.endsBefore(Item) is an early exit check that |
| 321 // turns a guaranteed O(N^2) algorithm into expected linear | 333 // turns a guaranteed O(N^2) algorithm into expected linear |
| 322 // complexity. | 334 // complexity. |
| 323 llvm::SmallBitVector PrecoloredUnhandledMask(RegMask.size()); | 335 llvm::SmallBitVector PrecoloredUnhandledMask(RegMask.size()); |
| 324 // Note: PrecoloredUnhandledMask is only used for dumping. | 336 // Note: PrecoloredUnhandledMask is only used for dumping. |
| 325 for (const LiveRangeWrapper &Item : UnhandledPrecolored) { | 337 for (const LiveRangeWrapper &Item : UnhandledPrecolored) { |
| 326 assert(Item.Var->hasReg()); | 338 assert(Item.Var->hasReg()); |
|
jvoung (off chromium)
2014/10/05 20:34:14
Is there any benefit to trimming the UnhandledPrec
Jim Stichnoth
2014/10/06 13:38:01
It shouldn't have any benefit. By definition, the
| |
| 327 if (Cur.endsBefore(Item)) | 339 if (Cur.endsBefore(Item)) |
| 328 break; | 340 break; |
| 329 if (Item.overlaps(Cur)) { | 341 if (Item.overlaps(Cur)) { |
| 330 int32_t ItemReg = Item.Var->getRegNum(); // Note: not getRegNumTmp() | 342 int32_t ItemReg = Item.Var->getRegNum(); // Note: not getRegNumTmp() |
| 331 Weights[ItemReg].setWeight(RegWeight::Inf); | 343 Weights[ItemReg].setWeight(RegWeight::Inf); |
| 332 Free[ItemReg] = false; | 344 Free[ItemReg] = false; |
| 333 PrecoloredUnhandledMask[ItemReg] = true; | 345 PrecoloredUnhandledMask[ItemReg] = true; |
| 334 // Disable AllowOverlap if the preferred register is one of | 346 // Disable AllowOverlap if the preferred register is one of |
| 335 // these precolored unhandled overlapping ranges. | 347 // these precolored unhandled overlapping ranges. |
| 336 if (AllowOverlap && ItemReg == PreferReg) { | 348 if (AllowOverlap && ItemReg == PreferReg) { |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 550 Str << "\n"; | 562 Str << "\n"; |
| 551 } | 563 } |
| 552 Str << "++++++ Inactive:\n"; | 564 Str << "++++++ Inactive:\n"; |
| 553 for (const LiveRangeWrapper &Item : Inactive) { | 565 for (const LiveRangeWrapper &Item : Inactive) { |
| 554 Item.dump(Func); | 566 Item.dump(Func); |
| 555 Str << "\n"; | 567 Str << "\n"; |
| 556 } | 568 } |
| 557 } | 569 } |
| 558 | 570 |
| 559 } // end of namespace Ice | 571 } // end of namespace Ice |
| OLD | NEW |