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 |