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 |