| 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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 // balanced binary tree, so inserting live ranges for N variables is | 81 // balanced binary tree, so inserting live ranges for N variables is |
| 82 // O(N log N) complexity. N may be proportional to the number of | 82 // O(N log N) complexity. N may be proportional to the number of |
| 83 // instructions, thanks to temporary generation during lowering. As | 83 // instructions, thanks to temporary generation during lowering. As |
| 84 // a result, it may be useful to design a better data structure for | 84 // a result, it may be useful to design a better data structure for |
| 85 // storing Func->getVariables(). | 85 // storing Func->getVariables(). |
| 86 const VarList &Vars = Func->getVariables(); | 86 const VarList &Vars = Func->getVariables(); |
| 87 { | 87 { |
| 88 static TimerIdT IDinitUnhandled = | 88 static TimerIdT IDinitUnhandled = |
| 89 GlobalContext::getTimerID("initUnhandled"); | 89 GlobalContext::getTimerID("initUnhandled"); |
| 90 TimerMarker T(IDinitUnhandled, Func->getContext()); | 90 TimerMarker T(IDinitUnhandled, Func->getContext()); |
| 91 for (VarList::const_iterator I = Vars.begin(), E = Vars.end(); I != E; | 91 for (Variable *Var : Vars) { |
| 92 ++I) { | |
| 93 Variable *Var = *I; | |
| 94 // Explicitly don't consider zero-weight variables, which are | 92 // Explicitly don't consider zero-weight variables, which are |
| 95 // meant to be spill slots. | 93 // meant to be spill slots. |
| 96 if (Var->getWeight() == RegWeight::Zero) | 94 if (Var->getWeight() == RegWeight::Zero) |
| 97 continue; | 95 continue; |
| 98 // Don't bother if the variable has a null live range, which means | 96 // Don't bother if the variable has a null live range, which means |
| 99 // it was never referenced. | 97 // it was never referenced. |
| 100 if (Var->getLiveRange().isEmpty()) | 98 if (Var->getLiveRange().isEmpty()) |
| 101 continue; | 99 continue; |
| 102 Unhandled.insert(LiveRangeWrapper(Var)); | 100 Unhandled.insert(LiveRangeWrapper(Var)); |
| 103 if (Var->hasReg()) { | 101 if (Var->hasReg()) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 Cur.dump(Func); | 142 Cur.dump(Func); |
| 145 Str << "\n"; | 143 Str << "\n"; |
| 146 } | 144 } |
| 147 Active.push_back(Cur); | 145 Active.push_back(Cur); |
| 148 assert(RegUses[RegNum] >= 0); | 146 assert(RegUses[RegNum] >= 0); |
| 149 ++RegUses[RegNum]; | 147 ++RegUses[RegNum]; |
| 150 continue; | 148 continue; |
| 151 } | 149 } |
| 152 | 150 |
| 153 // Check for active ranges that have expired or become inactive. | 151 // Check for active ranges that have expired or become inactive. |
| 154 for (UnorderedRanges::iterator I = Active.begin(), E = Active.end(); I != E; | 152 for (auto I = Active.begin(), E = Active.end(); I != E; I = Next) { |
| 155 I = Next) { | |
| 156 Next = I; | 153 Next = I; |
| 157 ++Next; | 154 ++Next; |
| 158 LiveRangeWrapper Item = *I; | 155 LiveRangeWrapper Item = *I; |
| 159 bool Moved = false; | 156 bool Moved = false; |
| 160 if (Item.endsBefore(Cur)) { | 157 if (Item.endsBefore(Cur)) { |
| 161 // Move Item from Active to Handled list. | 158 // Move Item from Active to Handled list. |
| 162 if (Verbose) { | 159 if (Verbose) { |
| 163 Str << "Expiring "; | 160 Str << "Expiring "; |
| 164 Item.dump(Func); | 161 Item.dump(Func); |
| 165 Str << "\n"; | 162 Str << "\n"; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 181 if (Moved) { | 178 if (Moved) { |
| 182 // Decrement Item from RegUses[]. | 179 // Decrement Item from RegUses[]. |
| 183 assert(Item.Var->hasRegTmp()); | 180 assert(Item.Var->hasRegTmp()); |
| 184 int32_t RegNum = Item.Var->getRegNumTmp(); | 181 int32_t RegNum = Item.Var->getRegNumTmp(); |
| 185 --RegUses[RegNum]; | 182 --RegUses[RegNum]; |
| 186 assert(RegUses[RegNum] >= 0); | 183 assert(RegUses[RegNum] >= 0); |
| 187 } | 184 } |
| 188 } | 185 } |
| 189 | 186 |
| 190 // Check for inactive ranges that have expired or reactivated. | 187 // Check for inactive ranges that have expired or reactivated. |
| 191 for (UnorderedRanges::iterator I = Inactive.begin(), E = Inactive.end(); | 188 for (auto I = Inactive.begin(), E = Inactive.end(); I != E; I = Next) { |
| 192 I != E; I = Next) { | |
| 193 Next = I; | 189 Next = I; |
| 194 ++Next; | 190 ++Next; |
| 195 LiveRangeWrapper Item = *I; | 191 LiveRangeWrapper Item = *I; |
| 196 if (Item.endsBefore(Cur)) { | 192 if (Item.endsBefore(Cur)) { |
| 197 // Move Item from Inactive to Handled list. | 193 // Move Item from Inactive to Handled list. |
| 198 if (Verbose) { | 194 if (Verbose) { |
| 199 Str << "Expiring "; | 195 Str << "Expiring "; |
| 200 Item.dump(Func); | 196 Item.dump(Func); |
| 201 Str << "\n"; | 197 Str << "\n"; |
| 202 } | 198 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 if (Verbose) { | 269 if (Verbose) { |
| 274 if (Prefer) { | 270 if (Prefer) { |
| 275 Str << "Initial Prefer=" << *Prefer << " R=" << PreferReg | 271 Str << "Initial Prefer=" << *Prefer << " R=" << PreferReg |
| 276 << " LIVE=" << Prefer->getLiveRange() << " Overlap=" << AllowOverlap | 272 << " LIVE=" << Prefer->getLiveRange() << " Overlap=" << AllowOverlap |
| 277 << "\n"; | 273 << "\n"; |
| 278 } | 274 } |
| 279 } | 275 } |
| 280 | 276 |
| 281 // Remove registers from the Free[] list where an Inactive range | 277 // Remove registers from the Free[] list where an Inactive range |
| 282 // overlaps with the current range. | 278 // overlaps with the current range. |
| 283 for (UnorderedRanges::const_iterator I = Inactive.begin(), | 279 for (const LiveRangeWrapper &Item : Inactive) { |
| 284 E = Inactive.end(); | |
| 285 I != E; ++I) { | |
| 286 LiveRangeWrapper Item = *I; | |
| 287 if (Item.overlaps(Cur)) { | 280 if (Item.overlaps(Cur)) { |
| 288 int32_t RegNum = Item.Var->getRegNumTmp(); | 281 int32_t RegNum = Item.Var->getRegNumTmp(); |
| 289 // Don't assert(Free[RegNum]) because in theory (though | 282 // Don't assert(Free[RegNum]) because in theory (though |
| 290 // probably never in practice) there could be two inactive | 283 // probably never in practice) there could be two inactive |
| 291 // variables that were marked with AllowOverlap. | 284 // variables that were marked with AllowOverlap. |
| 292 Free[RegNum] = false; | 285 Free[RegNum] = false; |
| 293 // Disable AllowOverlap if an Inactive variable, which is not | 286 // Disable AllowOverlap if an Inactive variable, which is not |
| 294 // Prefer, shares Prefer's register, and has a definition | 287 // Prefer, shares Prefer's register, and has a definition |
| 295 // within Cur's live range. | 288 // within Cur's live range. |
| 296 if (AllowOverlap && Item.Var != Prefer && RegNum == PreferReg && | 289 if (AllowOverlap && Item.Var != Prefer && RegNum == PreferReg && |
| 297 overlapsDefs(Func, Cur, Item.Var)) { | 290 overlapsDefs(Func, Cur, Item.Var)) { |
| 298 AllowOverlap = false; | 291 AllowOverlap = false; |
| 299 dumpDisableOverlap(Func, Item.Var, "Inactive"); | 292 dumpDisableOverlap(Func, Item.Var, "Inactive"); |
| 300 } | 293 } |
| 301 } | 294 } |
| 302 } | 295 } |
| 303 | 296 |
| 304 // Disable AllowOverlap if an Active variable, which is not | 297 // Disable AllowOverlap if an Active variable, which is not |
| 305 // Prefer, shares Prefer's register, and has a definition within | 298 // Prefer, shares Prefer's register, and has a definition within |
| 306 // Cur's live range. | 299 // Cur's live range. |
| 307 for (UnorderedRanges::iterator I = Active.begin(), E = Active.end(); | 300 for (const LiveRangeWrapper &Item : Active) { |
| 308 AllowOverlap && I != E; ++I) { | |
| 309 LiveRangeWrapper Item = *I; | |
| 310 int32_t RegNum = Item.Var->getRegNumTmp(); | 301 int32_t RegNum = Item.Var->getRegNumTmp(); |
| 311 if (Item.Var != Prefer && RegNum == PreferReg && | 302 if (Item.Var != Prefer && RegNum == PreferReg && |
| 312 overlapsDefs(Func, Cur, Item.Var)) { | 303 overlapsDefs(Func, Cur, Item.Var)) { |
| 313 AllowOverlap = false; | 304 AllowOverlap = false; |
| 314 dumpDisableOverlap(Func, Item.Var, "Active"); | 305 dumpDisableOverlap(Func, Item.Var, "Active"); |
| 315 } | 306 } |
| 316 } | 307 } |
| 317 | 308 |
| 318 // Remove registers from the Free[] list where an Unhandled range | 309 // Remove registers from the Free[] list where an Unhandled range |
| 319 // overlaps with the current range and is precolored. | 310 // overlaps with the current range and is precolored. |
| 320 // Cur.endsBefore(*I) is an early exit check that turns a | 311 // Cur.endsBefore(Item) is an early exit check that turns a |
| 321 // guaranteed O(N^2) algorithm into expected linear complexity. | 312 // guaranteed O(N^2) algorithm into expected linear complexity. |
| 322 llvm::SmallBitVector PrecoloredUnhandled(RegMask.size()); | 313 llvm::SmallBitVector PrecoloredUnhandled(RegMask.size()); |
| 323 // Note: PrecoloredUnhandled is only used for dumping. | 314 // Note: PrecoloredUnhandled is only used for dumping. |
| 324 for (OrderedRanges::const_iterator I = Unhandled.begin(), | 315 for (const LiveRangeWrapper &Item : Unhandled) { |
| 325 E = Unhandled.end(); | 316 if (Cur.endsBefore(Item)) |
| 326 I != E && !Cur.endsBefore(*I); ++I) { | 317 break; |
| 327 LiveRangeWrapper Item = *I; | |
| 328 if (Item.Var->hasReg() && Item.overlaps(Cur)) { | 318 if (Item.Var->hasReg() && Item.overlaps(Cur)) { |
| 329 int32_t ItemReg = Item.Var->getRegNum(); // Note: not getRegNumTmp() | 319 int32_t ItemReg = Item.Var->getRegNum(); // Note: not getRegNumTmp() |
| 330 Free[ItemReg] = false; | 320 Free[ItemReg] = false; |
| 331 PrecoloredUnhandled[ItemReg] = true; | 321 PrecoloredUnhandled[ItemReg] = true; |
| 332 // Disable AllowOverlap if the preferred register is one of | 322 // Disable AllowOverlap if the preferred register is one of |
| 333 // these precolored unhandled overlapping ranges. | 323 // these precolored unhandled overlapping ranges. |
| 334 if (AllowOverlap && ItemReg == PreferReg) { | 324 if (AllowOverlap && ItemReg == PreferReg) { |
| 335 AllowOverlap = false; | 325 AllowOverlap = false; |
| 336 dumpDisableOverlap(Func, Item.Var, "PrecoloredUnhandled"); | 326 dumpDisableOverlap(Func, Item.Var, "PrecoloredUnhandled"); |
| 337 } | 327 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 Str << "\n"; | 364 Str << "\n"; |
| 375 } | 365 } |
| 376 assert(RegUses[RegNum] >= 0); | 366 assert(RegUses[RegNum] >= 0); |
| 377 ++RegUses[RegNum]; | 367 ++RegUses[RegNum]; |
| 378 Active.push_back(Cur); | 368 Active.push_back(Cur); |
| 379 } else { | 369 } else { |
| 380 // Fallback: there are no free registers, so we look for the | 370 // Fallback: there are no free registers, so we look for the |
| 381 // lowest-weight register and see if Cur has higher weight. | 371 // lowest-weight register and see if Cur has higher weight. |
| 382 std::vector<RegWeight> Weights(RegMask.size()); | 372 std::vector<RegWeight> Weights(RegMask.size()); |
| 383 // Check Active ranges. | 373 // Check Active ranges. |
| 384 for (UnorderedRanges::const_iterator I = Active.begin(), E = Active.end(); | 374 for (const LiveRangeWrapper &Item : Active) { |
| 385 I != E; ++I) { | |
| 386 LiveRangeWrapper Item = *I; | |
| 387 assert(Item.overlaps(Cur)); | 375 assert(Item.overlaps(Cur)); |
| 388 int32_t RegNum = Item.Var->getRegNumTmp(); | 376 int32_t RegNum = Item.Var->getRegNumTmp(); |
| 389 assert(Item.Var->hasRegTmp()); | 377 assert(Item.Var->hasRegTmp()); |
| 390 Weights[RegNum].addWeight(Item.range().getWeight()); | 378 Weights[RegNum].addWeight(Item.range().getWeight()); |
| 391 } | 379 } |
| 392 // Same as above, but check Inactive ranges instead of Active. | 380 // Same as above, but check Inactive ranges instead of Active. |
| 393 for (UnorderedRanges::const_iterator I = Inactive.begin(), | 381 for (const LiveRangeWrapper &Item : Inactive) { |
| 394 E = Inactive.end(); | |
| 395 I != E; ++I) { | |
| 396 LiveRangeWrapper Item = *I; | |
| 397 int32_t RegNum = Item.Var->getRegNumTmp(); | 382 int32_t RegNum = Item.Var->getRegNumTmp(); |
| 398 assert(Item.Var->hasRegTmp()); | 383 assert(Item.Var->hasRegTmp()); |
| 399 if (Item.overlaps(Cur)) | 384 if (Item.overlaps(Cur)) |
| 400 Weights[RegNum].addWeight(Item.range().getWeight()); | 385 Weights[RegNum].addWeight(Item.range().getWeight()); |
| 401 } | 386 } |
| 402 // Check Unhandled ranges that overlap Cur and are precolored. | 387 // Check Unhandled ranges that overlap Cur and are precolored. |
| 403 // Cur.endsBefore(*I) is an early exit check that turns a | 388 // Cur.endsBefore(*I) is an early exit check that turns a |
| 404 // guaranteed O(N^2) algorithm into expected linear complexity. | 389 // guaranteed O(N^2) algorithm into expected linear complexity. |
| 405 for (OrderedRanges::const_iterator I = Unhandled.begin(), | 390 for (const LiveRangeWrapper &Item : Unhandled) { |
| 406 E = Unhandled.end(); | 391 if (Cur.endsBefore(Item)) |
| 407 I != E && !Cur.endsBefore(*I); ++I) { | 392 break; |
| 408 LiveRangeWrapper Item = *I; | |
| 409 int32_t RegNum = Item.Var->getRegNumTmp(); | 393 int32_t RegNum = Item.Var->getRegNumTmp(); |
| 410 if (RegNum < 0) | 394 if (RegNum < 0) |
| 411 continue; | 395 continue; |
| 412 if (Item.overlaps(Cur)) | 396 if (Item.overlaps(Cur)) |
| 413 Weights[RegNum].setWeight(RegWeight::Inf); | 397 Weights[RegNum].setWeight(RegWeight::Inf); |
| 414 } | 398 } |
| 415 | 399 |
| 416 // All the weights are now calculated. Find the register with | 400 // All the weights are now calculated. Find the register with |
| 417 // smallest weight. | 401 // smallest weight. |
| 418 int32_t MinWeightIndex = RegMask.find_first(); | 402 int32_t MinWeightIndex = RegMask.find_first(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 429 // don't allocate any register to it, and move it to the | 413 // don't allocate any register to it, and move it to the |
| 430 // Handled state. | 414 // Handled state. |
| 431 Handled.push_back(Cur); | 415 Handled.push_back(Cur); |
| 432 if (Cur.range().getWeight().isInf()) { | 416 if (Cur.range().getWeight().isInf()) { |
| 433 Func->setError("Unable to find a physical register for an " | 417 Func->setError("Unable to find a physical register for an " |
| 434 "infinite-weight live range"); | 418 "infinite-weight live range"); |
| 435 } | 419 } |
| 436 } else { | 420 } else { |
| 437 // Evict all live ranges in Active that register number | 421 // Evict all live ranges in Active that register number |
| 438 // MinWeightIndex is assigned to. | 422 // MinWeightIndex is assigned to. |
| 439 for (UnorderedRanges::iterator I = Active.begin(), E = Active.end(); | 423 for (auto I = Active.begin(), E = Active.end(); I != E; I = Next) { |
| 440 I != E; I = Next) { | |
| 441 Next = I; | 424 Next = I; |
| 442 ++Next; | 425 ++Next; |
| 443 LiveRangeWrapper Item = *I; | 426 LiveRangeWrapper Item = *I; |
| 444 if (Item.Var->getRegNumTmp() == MinWeightIndex) { | 427 if (Item.Var->getRegNumTmp() == MinWeightIndex) { |
| 445 if (Verbose) { | 428 if (Verbose) { |
| 446 Str << "Evicting "; | 429 Str << "Evicting "; |
| 447 Item.dump(Func); | 430 Item.dump(Func); |
| 448 Str << "\n"; | 431 Str << "\n"; |
| 449 } | 432 } |
| 450 --RegUses[MinWeightIndex]; | 433 --RegUses[MinWeightIndex]; |
| 451 assert(RegUses[MinWeightIndex] >= 0); | 434 assert(RegUses[MinWeightIndex] >= 0); |
| 452 Item.Var->setRegNumTmp(Variable::NoRegister); | 435 Item.Var->setRegNumTmp(Variable::NoRegister); |
| 453 Active.erase(I); | 436 Active.erase(I); |
| 454 Handled.push_back(Item); | 437 Handled.push_back(Item); |
| 455 } | 438 } |
| 456 } | 439 } |
| 457 // Do the same for Inactive. | 440 // Do the same for Inactive. |
| 458 for (UnorderedRanges::iterator I = Inactive.begin(), E = Inactive.end(); | 441 for (auto I = Inactive.begin(), E = Inactive.end(); I != E; I = Next) { |
| 459 I != E; I = Next) { | |
| 460 Next = I; | 442 Next = I; |
| 461 ++Next; | 443 ++Next; |
| 462 LiveRangeWrapper Item = *I; | 444 LiveRangeWrapper Item = *I; |
| 463 // Note: The Item.overlaps(Cur) clause is not part of the | 445 // Note: The Item.overlaps(Cur) clause is not part of the |
| 464 // description of AssignMemLoc() in the original paper. But | 446 // description of AssignMemLoc() in the original paper. But |
| 465 // there doesn't seem to be any need to evict an inactive | 447 // there doesn't seem to be any need to evict an inactive |
| 466 // live range that doesn't overlap with the live range | 448 // live range that doesn't overlap with the live range |
| 467 // currently being considered. It's especially bad if we | 449 // currently being considered. It's especially bad if we |
| 468 // would end up evicting an infinite-weight but | 450 // would end up evicting an infinite-weight but |
| 469 // currently-inactive live range. The most common situation | 451 // currently-inactive live range. The most common situation |
| (...skipping 19 matching lines...) Expand all Loading... |
| 489 if (Verbose) { | 471 if (Verbose) { |
| 490 Str << "Allocating "; | 472 Str << "Allocating "; |
| 491 Cur.dump(Func); | 473 Cur.dump(Func); |
| 492 Str << "\n"; | 474 Str << "\n"; |
| 493 } | 475 } |
| 494 } | 476 } |
| 495 } | 477 } |
| 496 dump(Func); | 478 dump(Func); |
| 497 } | 479 } |
| 498 // Move anything Active or Inactive to Handled for easier handling. | 480 // Move anything Active or Inactive to Handled for easier handling. |
| 499 for (UnorderedRanges::iterator I = Active.begin(), E = Active.end(); I != E; | 481 for (const LiveRangeWrapper &I : Active) |
| 500 I = Next) { | 482 Handled.push_back(I); |
| 501 Next = I; | 483 Active.clear(); |
| 502 ++Next; | 484 for (const LiveRangeWrapper &I : Inactive) |
| 503 Handled.push_back(*I); | 485 Handled.push_back(I); |
| 504 Active.erase(I); | 486 Inactive.clear(); |
| 505 } | |
| 506 for (UnorderedRanges::iterator I = Inactive.begin(), E = Inactive.end(); | |
| 507 I != E; I = Next) { | |
| 508 Next = I; | |
| 509 ++Next; | |
| 510 Handled.push_back(*I); | |
| 511 Inactive.erase(I); | |
| 512 } | |
| 513 dump(Func); | 487 dump(Func); |
| 514 | 488 |
| 515 // Finish up by assigning RegNumTmp->RegNum for each Variable. | 489 // Finish up by assigning RegNumTmp->RegNum for each Variable. |
| 516 for (UnorderedRanges::const_iterator I = Handled.begin(), E = Handled.end(); | 490 for (const LiveRangeWrapper &Item : Handled) { |
| 517 I != E; ++I) { | |
| 518 LiveRangeWrapper Item = *I; | |
| 519 int32_t RegNum = Item.Var->getRegNumTmp(); | 491 int32_t RegNum = Item.Var->getRegNumTmp(); |
| 520 if (Verbose) { | 492 if (Verbose) { |
| 521 if (!Item.Var->hasRegTmp()) { | 493 if (!Item.Var->hasRegTmp()) { |
| 522 Str << "Not assigning "; | 494 Str << "Not assigning "; |
| 523 Item.Var->dump(Func); | 495 Item.Var->dump(Func); |
| 524 Str << "\n"; | 496 Str << "\n"; |
| 525 } else { | 497 } else { |
| 526 Str << (RegNum == Item.Var->getRegNum() ? "Reassigning " : "Assigning ") | 498 Str << (RegNum == Item.Var->getRegNum() ? "Reassigning " : "Assigning ") |
| 527 << Func->getTarget()->getRegName(RegNum, IceType_i32) << "(r" | 499 << Func->getTarget()->getRegName(RegNum, IceType_i32) << "(r" |
| 528 << RegNum << ") to "; | 500 << RegNum << ") to "; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 557 Str << " Range=" << range(); | 529 Str << " Range=" << range(); |
| 558 } | 530 } |
| 559 | 531 |
| 560 void LinearScan::dump(Cfg *Func) const { | 532 void LinearScan::dump(Cfg *Func) const { |
| 561 Ostream &Str = Func->getContext()->getStrDump(); | 533 Ostream &Str = Func->getContext()->getStrDump(); |
| 562 if (!Func->getContext()->isVerbose(IceV_LinearScan)) | 534 if (!Func->getContext()->isVerbose(IceV_LinearScan)) |
| 563 return; | 535 return; |
| 564 Func->resetCurrentNode(); | 536 Func->resetCurrentNode(); |
| 565 Str << "**** Current regalloc state:\n"; | 537 Str << "**** Current regalloc state:\n"; |
| 566 Str << "++++++ Handled:\n"; | 538 Str << "++++++ Handled:\n"; |
| 567 for (UnorderedRanges::const_iterator I = Handled.begin(), E = Handled.end(); | 539 for (const LiveRangeWrapper &Item : Handled) { |
| 568 I != E; ++I) { | 540 Item.dump(Func); |
| 569 I->dump(Func); | |
| 570 Str << "\n"; | 541 Str << "\n"; |
| 571 } | 542 } |
| 572 Str << "++++++ Unhandled:\n"; | 543 Str << "++++++ Unhandled:\n"; |
| 573 for (OrderedRanges::const_iterator I = Unhandled.begin(), E = Unhandled.end(); | 544 for (const LiveRangeWrapper &Item : Unhandled) { |
| 574 I != E; ++I) { | 545 Item.dump(Func); |
| 575 I->dump(Func); | |
| 576 Str << "\n"; | 546 Str << "\n"; |
| 577 } | 547 } |
| 578 Str << "++++++ Active:\n"; | 548 Str << "++++++ Active:\n"; |
| 579 for (UnorderedRanges::const_iterator I = Active.begin(), E = Active.end(); | 549 for (const LiveRangeWrapper &Item : Active) { |
| 580 I != E; ++I) { | 550 Item.dump(Func); |
| 581 I->dump(Func); | |
| 582 Str << "\n"; | 551 Str << "\n"; |
| 583 } | 552 } |
| 584 Str << "++++++ Inactive:\n"; | 553 Str << "++++++ Inactive:\n"; |
| 585 for (UnorderedRanges::const_iterator I = Inactive.begin(), E = Inactive.end(); | 554 for (const LiveRangeWrapper &Item : Inactive) { |
| 586 I != E; ++I) { | 555 Item.dump(Func); |
| 587 I->dump(Func); | |
| 588 Str << "\n"; | 556 Str << "\n"; |
| 589 } | 557 } |
| 590 } | 558 } |
| 591 | 559 |
| 592 } // end of namespace Ice | 560 } // end of namespace Ice |
| OLD | NEW |