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 187 matching lines...) Loading... |
198 // variables that were allowed marked with | 198 // variables that were allowed marked with |
199 // AllowRegisterOverlap. | 199 // AllowRegisterOverlap. |
200 Free[RegNum] = false; | 200 Free[RegNum] = false; |
201 } | 201 } |
202 } | 202 } |
203 | 203 |
204 // Remove registers from the Free[] list where an Unhandled range | 204 // Remove registers from the Free[] list where an Unhandled range |
205 // overlaps with the current range and is precolored. | 205 // overlaps with the current range and is precolored. |
206 // Cur.endsBefore(*I) is an early exit check that turns a | 206 // Cur.endsBefore(*I) is an early exit check that turns a |
207 // guaranteed O(N^2) algorithm into expected linear complexity. | 207 // guaranteed O(N^2) algorithm into expected linear complexity. |
| 208 llvm::SmallBitVector PrecoloredUnhandled(RegMask.size()); |
208 for (OrderedRanges::const_iterator I = Unhandled.begin(), | 209 for (OrderedRanges::const_iterator I = Unhandled.begin(), |
209 E = Unhandled.end(); | 210 E = Unhandled.end(); |
210 I != E && !Cur.endsBefore(*I); ++I) { | 211 I != E && !Cur.endsBefore(*I); ++I) { |
211 LiveRangeWrapper Item = *I; | 212 LiveRangeWrapper Item = *I; |
212 if (Item.Var->hasReg() && Item.overlaps(Cur)) { | 213 if (Item.Var->hasReg() && Item.overlaps(Cur)) { |
213 Free[Item.Var->getRegNum()] = false; // Note: getRegNum not getRegNumTmp | 214 Free[Item.Var->getRegNum()] = false; // Note: getRegNum not getRegNumTmp |
| 215 PrecoloredUnhandled[Item.Var->getRegNum()] = true; |
214 } | 216 } |
215 } | 217 } |
216 | 218 |
217 // Print info about physical register availability. | 219 // Print info about physical register availability. |
218 if (Func->getContext()->isVerbose(IceV_LinearScan)) { | 220 if (Func->getContext()->isVerbose(IceV_LinearScan)) { |
219 for (SizeT i = 0; i < RegMask.size(); ++i) { | 221 for (SizeT i = 0; i < RegMask.size(); ++i) { |
220 if (RegMask[i]) { | 222 if (RegMask[i]) { |
221 Str << Func->getTarget()->getRegName(i, IceType_i32) | 223 Str << Func->getTarget()->getRegName(i, IceType_i32) |
222 << "(U=" << RegUses[i] << ",F=" << Free[i] << ") "; | 224 << "(U=" << RegUses[i] << ",F=" << Free[i] |
| 225 << ",P=" << PrecoloredUnhandled[i] << ") "; |
223 } | 226 } |
224 } | 227 } |
225 Str << "\n"; | 228 Str << "\n"; |
226 } | 229 } |
227 | 230 |
228 Variable *Prefer = Cur.Var->getPreferredRegister(); | 231 Variable *Prefer = Cur.Var->getPreferredRegister(); |
229 int32_t PreferReg = Prefer && Prefer->hasRegTmp() ? Prefer->getRegNumTmp() | 232 int32_t PreferReg = Prefer && Prefer->hasRegTmp() ? Prefer->getRegNumTmp() |
230 : Variable::NoRegister; | 233 : Variable::NoRegister; |
| 234 bool AllowedToOverlap = Cur.Var->getRegisterOverlap() && |
| 235 PreferReg != Variable::NoRegister && |
| 236 !PrecoloredUnhandled[PreferReg]; |
231 if (PreferReg != Variable::NoRegister && | 237 if (PreferReg != Variable::NoRegister && |
232 (Cur.Var->getRegisterOverlap() || Free[PreferReg])) { | 238 (AllowedToOverlap || Free[PreferReg])) { |
233 // First choice: a preferred register that is either free or is | 239 // First choice: a preferred register that is either free or is |
234 // allowed to overlap with its linked variable. | 240 // allowed to overlap with its linked variable. |
235 Cur.Var->setRegNumTmp(PreferReg); | 241 Cur.Var->setRegNumTmp(PreferReg); |
236 if (Func->getContext()->isVerbose(IceV_LinearScan)) { | 242 if (Func->getContext()->isVerbose(IceV_LinearScan)) { |
237 Str << "Preferring "; | 243 Str << "Preferring "; |
238 Cur.dump(Func); | 244 Cur.dump(Func); |
239 Str << "\n"; | 245 Str << "\n"; |
240 } | 246 } |
241 assert(RegUses[PreferReg] >= 0); | 247 assert(RegUses[PreferReg] >= 0); |
242 ++RegUses[PreferReg]; | 248 ++RegUses[PreferReg]; |
(...skipping 209 matching lines...) Loading... |
452 } | 458 } |
453 Str << "++++++ Inactive:\n"; | 459 Str << "++++++ Inactive:\n"; |
454 for (UnorderedRanges::const_iterator I = Inactive.begin(), E = Inactive.end(); | 460 for (UnorderedRanges::const_iterator I = Inactive.begin(), E = Inactive.end(); |
455 I != E; ++I) { | 461 I != E; ++I) { |
456 I->dump(Func); | 462 I->dump(Func); |
457 Str << "\n"; | 463 Str << "\n"; |
458 } | 464 } |
459 } | 465 } |
460 | 466 |
461 } // end of namespace Ice | 467 } // end of namespace Ice |
OLD | NEW |