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 28 matching lines...) Expand all Loading... |
39 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var); | 39 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var); |
40 for (size_t i = 0; i < Defs.size(); ++i) { | 40 for (size_t i = 0; i < Defs.size(); ++i) { |
41 if (Item->getLiveRange().overlapsInst(Defs[i]->getNumber(), UseTrimmed)) | 41 if (Item->getLiveRange().overlapsInst(Defs[i]->getNumber(), UseTrimmed)) |
42 return true; | 42 return true; |
43 } | 43 } |
44 return false; | 44 return false; |
45 } | 45 } |
46 | 46 |
47 void dumpDisableOverlap(const Cfg *Func, const Variable *Var, | 47 void dumpDisableOverlap(const Cfg *Func, const Variable *Var, |
48 const char *Reason) { | 48 const char *Reason) { |
| 49 if (!ALLOW_DUMP) |
| 50 return; |
49 if (Func->getContext()->isVerbose(IceV_LinearScan)) { | 51 if (Func->getContext()->isVerbose(IceV_LinearScan)) { |
50 VariablesMetadata *VMetadata = Func->getVMetadata(); | 52 VariablesMetadata *VMetadata = Func->getVMetadata(); |
51 Ostream &Str = Func->getContext()->getStrDump(); | 53 Ostream &Str = Func->getContext()->getStrDump(); |
52 Str << "Disabling Overlap due to " << Reason << " " << *Var | 54 Str << "Disabling Overlap due to " << Reason << " " << *Var |
53 << " LIVE=" << Var->getLiveRange() << " Defs="; | 55 << " LIVE=" << Var->getLiveRange() << " Defs="; |
54 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var)) | 56 if (const Inst *FirstDef = VMetadata->getFirstDefinition(Var)) |
55 Str << FirstDef->getNumber(); | 57 Str << FirstDef->getNumber(); |
56 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var); | 58 const InstDefList &Defs = VMetadata->getLatterDefinitions(Var); |
57 for (size_t i = 0; i < Defs.size(); ++i) { | 59 for (size_t i = 0; i < Defs.size(); ++i) { |
58 Str << "," << Defs[i]->getNumber(); | 60 Str << "," << Defs[i]->getNumber(); |
59 } | 61 } |
60 Str << "\n"; | 62 Str << "\n"; |
61 } | 63 } |
62 } | 64 } |
63 | 65 |
64 void dumpLiveRange(const Variable *Var, const Cfg *Func) { | 66 void dumpLiveRange(const Variable *Var, const Cfg *Func) { |
| 67 if (!ALLOW_DUMP) |
| 68 return; |
65 Ostream &Str = Func->getContext()->getStrDump(); | 69 Ostream &Str = Func->getContext()->getStrDump(); |
66 const static size_t BufLen = 30; | 70 const static size_t BufLen = 30; |
67 char buf[BufLen]; | 71 char buf[BufLen]; |
68 snprintf(buf, BufLen, "%2d", Var->getRegNumTmp()); | 72 snprintf(buf, BufLen, "%2d", Var->getRegNumTmp()); |
69 Str << "R=" << buf << " V="; | 73 Str << "R=" << buf << " V="; |
70 Var->dump(Func); | 74 Var->dump(Func); |
71 Str << " Range=" << Var->getLiveRange(); | 75 Str << " Range=" << Var->getLiveRange(); |
72 } | 76 } |
73 | 77 |
74 } // end of anonymous namespace | 78 } // end of anonymous namespace |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
245 // two interfering variables to share the same register in certain | 249 // two interfering variables to share the same register in certain |
246 // cases. | 250 // cases. |
247 // | 251 // |
248 // Requires running Cfg::liveness(Liveness_Intervals) in | 252 // Requires running Cfg::liveness(Liveness_Intervals) in |
249 // preparation. Results are assigned to Variable::RegNum for each | 253 // preparation. Results are assigned to Variable::RegNum for each |
250 // Variable. | 254 // Variable. |
251 void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { | 255 void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { |
252 TimerMarker T(TimerStack::TT_linearScan, Func); | 256 TimerMarker T(TimerStack::TT_linearScan, Func); |
253 assert(RegMaskFull.any()); // Sanity check | 257 assert(RegMaskFull.any()); // Sanity check |
254 Ostream &Str = Func->getContext()->getStrDump(); | 258 Ostream &Str = Func->getContext()->getStrDump(); |
255 bool Verbose = Func->getContext()->isVerbose(IceV_LinearScan); | 259 const bool Verbose = |
| 260 ALLOW_DUMP && Func->getContext()->isVerbose(IceV_LinearScan); |
256 Func->resetCurrentNode(); | 261 Func->resetCurrentNode(); |
257 VariablesMetadata *VMetadata = Func->getVMetadata(); | 262 VariablesMetadata *VMetadata = Func->getVMetadata(); |
258 | 263 |
259 // Build a LiveRange representing the Kills list. | 264 // Build a LiveRange representing the Kills list. |
260 LiveRange KillsRange; | 265 LiveRange KillsRange; |
261 for (InstNumberT I : Kills) | 266 for (InstNumberT I : Kills) |
262 KillsRange.addSegment(I, I); | 267 KillsRange.addSegment(I, I); |
263 KillsRange.untrim(); | 268 KillsRange.untrim(); |
264 | 269 |
265 // RegUses[I] is the number of live ranges (variables) that register | 270 // RegUses[I] is the number of live ranges (variables) that register |
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
684 // own slot. | 689 // own slot. |
685 // | 690 // |
686 // Another idea for coalescing stack slots is to initialize the | 691 // Another idea for coalescing stack slots is to initialize the |
687 // Unhandled list with just the unallocated variables, saving time | 692 // Unhandled list with just the unallocated variables, saving time |
688 // but not offering second-chance opportunities. | 693 // but not offering second-chance opportunities. |
689 } | 694 } |
690 | 695 |
691 // ======================== Dump routines ======================== // | 696 // ======================== Dump routines ======================== // |
692 | 697 |
693 void LinearScan::dump(Cfg *Func) const { | 698 void LinearScan::dump(Cfg *Func) const { |
| 699 if (!ALLOW_DUMP) |
| 700 return; |
694 Ostream &Str = Func->getContext()->getStrDump(); | 701 Ostream &Str = Func->getContext()->getStrDump(); |
695 if (!Func->getContext()->isVerbose(IceV_LinearScan)) | 702 if (!Func->getContext()->isVerbose(IceV_LinearScan)) |
696 return; | 703 return; |
697 Func->resetCurrentNode(); | 704 Func->resetCurrentNode(); |
698 Str << "**** Current regalloc state:\n"; | 705 Str << "**** Current regalloc state:\n"; |
699 Str << "++++++ Handled:\n"; | 706 Str << "++++++ Handled:\n"; |
700 for (const Variable *Item : Handled) { | 707 for (const Variable *Item : Handled) { |
701 dumpLiveRange(Item, Func); | 708 dumpLiveRange(Item, Func); |
702 Str << "\n"; | 709 Str << "\n"; |
703 } | 710 } |
704 Str << "++++++ Unhandled:\n"; | 711 Str << "++++++ Unhandled:\n"; |
705 for (auto I = Unhandled.rbegin(), E = Unhandled.rend(); I != E; ++I) { | 712 for (auto I = Unhandled.rbegin(), E = Unhandled.rend(); I != E; ++I) { |
706 dumpLiveRange(*I, Func); | 713 dumpLiveRange(*I, Func); |
707 Str << "\n"; | 714 Str << "\n"; |
708 } | 715 } |
709 Str << "++++++ Active:\n"; | 716 Str << "++++++ Active:\n"; |
710 for (const Variable *Item : Active) { | 717 for (const Variable *Item : Active) { |
711 dumpLiveRange(Item, Func); | 718 dumpLiveRange(Item, Func); |
712 Str << "\n"; | 719 Str << "\n"; |
713 } | 720 } |
714 Str << "++++++ Inactive:\n"; | 721 Str << "++++++ Inactive:\n"; |
715 for (const Variable *Item : Inactive) { | 722 for (const Variable *Item : Inactive) { |
716 dumpLiveRange(Item, Func); | 723 dumpLiveRange(Item, Func); |
717 Str << "\n"; | 724 Str << "\n"; |
718 } | 725 } |
719 } | 726 } |
720 | 727 |
721 } // end of namespace Ice | 728 } // end of namespace Ice |
OLD | NEW |