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 |
11 // linear-scan register allocation after liveness analysis has been | 11 // linear-scan register allocation after liveness analysis has been |
12 // performed. | 12 // performed. |
13 // | 13 // |
14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
15 | 15 |
16 #include "IceCfg.h" | 16 #include "IceCfg.h" |
17 #include "IceInst.h" | 17 #include "IceInst.h" |
18 #include "IceOperand.h" | 18 #include "IceOperand.h" |
19 #include "IceRegAlloc.h" | 19 #include "IceRegAlloc.h" |
20 #include "IceTargetLowering.h" | 20 #include "IceTargetLowering.h" |
21 | 21 |
22 namespace Ice { | 22 namespace Ice { |
23 | 23 |
24 namespace { | 24 namespace { |
25 | 25 |
26 // Returns true if Var has any definitions within Item's live range. | 26 // Returns true if Var has any definitions within Item's live range. |
| 27 // TODO(stichnot): Consider trimming the Definitions list similar to |
| 28 // how the live ranges are trimmed, since all the overlapsDefs() tests |
| 29 // are whether some variable's definitions overlap Cur, and trimming |
| 30 // is with respect Cur.start. Initial tests show no measurable |
| 31 // performance difference, so we'll keep the code simple for now. |
27 bool overlapsDefs(const Cfg *Func, const LiveRangeWrapper &Item, | 32 bool overlapsDefs(const Cfg *Func, const LiveRangeWrapper &Item, |
28 const Variable *Var) { | 33 const Variable *Var) { |
29 const InstDefList &Defs = Func->getVMetadata()->getDefinitions(Var); | 34 const bool UseTrimmed = true; |
| 35 VariablesMetadata *VMetadata = Func->getVMetadata(); |
| 36 const InstDefList &Defs = VMetadata->getDefinitions(Var); |
30 for (size_t i = 0; i < Defs.size(); ++i) { | 37 for (size_t i = 0; i < Defs.size(); ++i) { |
31 if (Item.range().overlaps(Defs[i]->getNumber())) | 38 if (Item.range().overlapsInst(Defs[i]->getNumber(), UseTrimmed)) |
32 return true; | 39 return true; |
33 } | 40 } |
34 return false; | 41 return false; |
35 } | 42 } |
36 | 43 |
37 void dumpDisableOverlap(const Cfg *Func, const Variable *Var, | 44 void dumpDisableOverlap(const Cfg *Func, const Variable *Var, |
38 const char *Reason) { | 45 const char *Reason) { |
39 if (Func->getContext()->isVerbose(IceV_LinearScan)) { | 46 if (Func->getContext()->isVerbose(IceV_LinearScan)) { |
| 47 VariablesMetadata *VMetadata = Func->getVMetadata(); |
40 Ostream &Str = Func->getContext()->getStrDump(); | 48 Ostream &Str = Func->getContext()->getStrDump(); |
41 Str << "Disabling Overlap due to " << Reason << " " << *Var | 49 Str << "Disabling Overlap due to " << Reason << " " << *Var |
42 << " LIVE=" << Var->getLiveRange() << " Defs="; | 50 << " LIVE=" << Var->getLiveRange() << " Defs="; |
43 const InstDefList &Defs = Func->getVMetadata()->getDefinitions(Var); | 51 const InstDefList &Defs = VMetadata->getDefinitions(Var); |
44 for (size_t i = 0; i < Defs.size(); ++i) { | 52 for (size_t i = 0; i < Defs.size(); ++i) { |
45 if (i > 0) | 53 if (i > 0) |
46 Str << ","; | 54 Str << ","; |
47 Str << Defs[i]->getNumber(); | 55 Str << Defs[i]->getNumber(); |
48 } | 56 } |
49 Str << "\n"; | 57 Str << "\n"; |
50 } | 58 } |
51 } | 59 } |
52 | 60 |
53 } // end of anonymous namespace | 61 } // end of anonymous namespace |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 TimerMarker T(IDinitUnhandled, Func->getContext()); | 99 TimerMarker T(IDinitUnhandled, Func->getContext()); |
92 for (Variable *Var : Vars) { | 100 for (Variable *Var : Vars) { |
93 // Explicitly don't consider zero-weight variables, which are | 101 // Explicitly don't consider zero-weight variables, which are |
94 // meant to be spill slots. | 102 // meant to be spill slots. |
95 if (Var->getWeight() == RegWeight::Zero) | 103 if (Var->getWeight() == RegWeight::Zero) |
96 continue; | 104 continue; |
97 // Don't bother if the variable has a null live range, which means | 105 // Don't bother if the variable has a null live range, which means |
98 // it was never referenced. | 106 // it was never referenced. |
99 if (Var->getLiveRange().isEmpty()) | 107 if (Var->getLiveRange().isEmpty()) |
100 continue; | 108 continue; |
| 109 Var->untrimLiveRange(); |
101 LiveRangeWrapper R(Var); | 110 LiveRangeWrapper R(Var); |
102 Unhandled.insert(R); | 111 Unhandled.insert(R); |
103 if (Var->hasReg()) { | 112 if (Var->hasReg()) { |
104 Var->setRegNumTmp(Var->getRegNum()); | 113 Var->setRegNumTmp(Var->getRegNum()); |
105 Var->setLiveRangeInfiniteWeight(); | 114 Var->setLiveRangeInfiniteWeight(); |
106 UnhandledPrecolored.insert(R); | 115 UnhandledPrecolored.insert(R); |
107 } | 116 } |
108 } | 117 } |
109 } | 118 } |
110 | 119 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 assert(UnhandledPrecolored.begin()->Var == Cur.Var); | 161 assert(UnhandledPrecolored.begin()->Var == Cur.Var); |
153 UnhandledPrecolored.erase(UnhandledPrecolored.begin()); | 162 UnhandledPrecolored.erase(UnhandledPrecolored.begin()); |
154 continue; | 163 continue; |
155 } | 164 } |
156 | 165 |
157 // Check for active ranges that have expired or become inactive. | 166 // Check for active ranges that have expired or become inactive. |
158 for (auto I = Active.begin(), E = Active.end(); I != E; I = Next) { | 167 for (auto I = Active.begin(), E = Active.end(); I != E; I = Next) { |
159 Next = I; | 168 Next = I; |
160 ++Next; | 169 ++Next; |
161 LiveRangeWrapper Item = *I; | 170 LiveRangeWrapper Item = *I; |
| 171 Item.Var->trimLiveRange(Cur.range().getStart()); |
162 bool Moved = false; | 172 bool Moved = false; |
163 if (Item.endsBefore(Cur)) { | 173 if (Item.endsBefore(Cur)) { |
164 // Move Item from Active to Handled list. | 174 // Move Item from Active to Handled list. |
165 if (Verbose) { | 175 if (Verbose) { |
166 Str << "Expiring "; | 176 Str << "Expiring "; |
167 Item.dump(Func); | 177 Item.dump(Func); |
168 Str << "\n"; | 178 Str << "\n"; |
169 } | 179 } |
170 Active.erase(I); | 180 Active.erase(I); |
171 Handled.push_back(Item); | 181 Handled.push_back(Item); |
(...skipping 16 matching lines...) Expand all Loading... |
188 --RegUses[RegNum]; | 198 --RegUses[RegNum]; |
189 assert(RegUses[RegNum] >= 0); | 199 assert(RegUses[RegNum] >= 0); |
190 } | 200 } |
191 } | 201 } |
192 | 202 |
193 // Check for inactive ranges that have expired or reactivated. | 203 // Check for inactive ranges that have expired or reactivated. |
194 for (auto I = Inactive.begin(), E = Inactive.end(); I != E; I = Next) { | 204 for (auto I = Inactive.begin(), E = Inactive.end(); I != E; I = Next) { |
195 Next = I; | 205 Next = I; |
196 ++Next; | 206 ++Next; |
197 LiveRangeWrapper Item = *I; | 207 LiveRangeWrapper Item = *I; |
| 208 Item.Var->trimLiveRange(Cur.range().getStart()); |
| 209 // As an optimization, don't bother checking pure point-valued |
| 210 // Inactive ranges, because the overlapsStart() test will never |
| 211 // succeed, and the endsBefore() test will generally only |
| 212 // succeed after the last call instruction, which statistically |
| 213 // happens near the end. TODO(stichnot): Consider suppressing |
| 214 // this check every N iterations in case calls are only at the |
| 215 // beginning of the function. |
| 216 if (!Item.range().isNonpoints()) |
| 217 continue; |
198 if (Item.endsBefore(Cur)) { | 218 if (Item.endsBefore(Cur)) { |
199 // Move Item from Inactive to Handled list. | 219 // Move Item from Inactive to Handled list. |
200 if (Verbose) { | 220 if (Verbose) { |
201 Str << "Expiring "; | 221 Str << "Expiring "; |
202 Item.dump(Func); | 222 Item.dump(Func); |
203 Str << "\n"; | 223 Str << "\n"; |
204 } | 224 } |
205 Inactive.erase(I); | 225 Inactive.erase(I); |
206 Handled.push_back(Item); | 226 Handled.push_back(Item); |
207 } else if (Item.overlapsStart(Cur)) { | 227 } else if (Item.overlapsStart(Cur)) { |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 Str << "\n"; | 570 Str << "\n"; |
551 } | 571 } |
552 Str << "++++++ Inactive:\n"; | 572 Str << "++++++ Inactive:\n"; |
553 for (const LiveRangeWrapper &Item : Inactive) { | 573 for (const LiveRangeWrapper &Item : Inactive) { |
554 Item.dump(Func); | 574 Item.dump(Func); |
555 Str << "\n"; | 575 Str << "\n"; |
556 } | 576 } |
557 } | 577 } |
558 | 578 |
559 } // end of namespace Ice | 579 } // end of namespace Ice |
OLD | NEW |