Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(582)

Side by Side Diff: src/IceRegAlloc.cpp

Issue 610813002: Subzero: Rewrite the pass timing infrastructure. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Make the optimized overlaps() implementation actually correct Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 // Constraints" by Hanspeter Mössenböck and Michael Pfeiffer, 57 // Constraints" by Hanspeter Mössenböck and Michael Pfeiffer,
58 // ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF . This 58 // ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF . This
59 // implementation is modified to take affinity into account and allow 59 // implementation is modified to take affinity into account and allow
60 // two interfering variables to share the same register in certain 60 // two interfering variables to share the same register in certain
61 // cases. 61 // cases.
62 // 62 //
63 // Requires running Cfg::liveness(Liveness_Intervals) in 63 // Requires running Cfg::liveness(Liveness_Intervals) in
64 // preparation. Results are assigned to Variable::RegNum for each 64 // preparation. Results are assigned to Variable::RegNum for each
65 // Variable. 65 // Variable.
66 void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { 66 void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) {
67 static TimerIdT IDscan = GlobalContext::getTimerID("linearScan");
68 TimerMarker T(IDscan, Func->getContext());
67 assert(RegMaskFull.any()); // Sanity check 69 assert(RegMaskFull.any()); // Sanity check
68 Unhandled.clear(); 70 Unhandled.clear();
69 Handled.clear(); 71 Handled.clear();
70 Inactive.clear(); 72 Inactive.clear();
71 Active.clear(); 73 Active.clear();
72 Ostream &Str = Func->getContext()->getStrDump(); 74 Ostream &Str = Func->getContext()->getStrDump();
75 bool Verbose = Func->getContext()->isVerbose(IceV_LinearScan);
73 Func->resetCurrentNode(); 76 Func->resetCurrentNode();
74 VariablesMetadata *VMetadata = Func->getVMetadata(); 77 VariablesMetadata *VMetadata = Func->getVMetadata();
75 78
76 // Gather the live ranges of all variables and add them to the 79 // Gather the live ranges of all variables and add them to the
77 // Unhandled set. TODO: Unhandled is a set<> which is based on a 80 // Unhandled set. TODO: Unhandled is a set<> which is based on a
78 // balanced binary tree, so inserting live ranges for N variables is 81 // balanced binary tree, so inserting live ranges for N variables is
79 // 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
80 // instructions, thanks to temporary generation during lowering. As 83 // instructions, thanks to temporary generation during lowering. As
81 // 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
82 // storing Func->getVariables(). 85 // storing Func->getVariables().
83 const VarList &Vars = Func->getVariables(); 86 const VarList &Vars = Func->getVariables();
84 for (VarList::const_iterator I = Vars.begin(), E = Vars.end(); I != E; ++I) { 87 {
85 Variable *Var = *I; 88 static TimerIdT IDinitUnhandled =
86 // Explicitly don't consider zero-weight variables, which are 89 GlobalContext::getTimerID("initUnhandled");
87 // meant to be spill slots. 90 TimerMarker T(IDinitUnhandled, Func->getContext());
88 if (Var->getWeight() == RegWeight::Zero) 91 for (VarList::const_iterator I = Vars.begin(), E = Vars.end(); I != E;
89 continue; 92 ++I) {
90 // Don't bother if the variable has a null live range, which means 93 Variable *Var = *I;
91 // it was never referenced. 94 // Explicitly don't consider zero-weight variables, which are
92 if (Var->getLiveRange().isEmpty()) 95 // meant to be spill slots.
93 continue; 96 if (Var->getWeight() == RegWeight::Zero)
94 Unhandled.insert(LiveRangeWrapper(Var)); 97 continue;
95 if (Var->hasReg()) { 98 // Don't bother if the variable has a null live range, which means
96 Var->setRegNumTmp(Var->getRegNum()); 99 // it was never referenced.
97 Var->setLiveRangeInfiniteWeight(); 100 if (Var->getLiveRange().isEmpty())
101 continue;
102 Unhandled.insert(LiveRangeWrapper(Var));
103 if (Var->hasReg()) {
104 Var->setRegNumTmp(Var->getRegNum());
105 Var->setLiveRangeInfiniteWeight();
106 }
98 } 107 }
99 } 108 }
100 109
101 // RegUses[I] is the number of live ranges (variables) that register 110 // RegUses[I] is the number of live ranges (variables) that register
102 // I is currently assigned to. It can be greater than 1 as a result 111 // I is currently assigned to. It can be greater than 1 as a result
103 // of Variable::AllowRegisterOverlap. 112 // of AllowOverlap inference below.
104 std::vector<int> RegUses(RegMaskFull.size()); 113 std::vector<int> RegUses(RegMaskFull.size());
105 // Unhandled is already set to all ranges in increasing order of 114 // Unhandled is already set to all ranges in increasing order of
106 // start points. 115 // start points.
107 assert(Active.empty()); 116 assert(Active.empty());
108 assert(Inactive.empty()); 117 assert(Inactive.empty());
109 assert(Handled.empty()); 118 assert(Handled.empty());
110 UnorderedRanges::iterator Next; 119 UnorderedRanges::iterator Next;
111 120
112 while (!Unhandled.empty()) { 121 while (!Unhandled.empty()) {
113 LiveRangeWrapper Cur = *Unhandled.begin(); 122 LiveRangeWrapper Cur = *Unhandled.begin();
114 Unhandled.erase(Unhandled.begin()); 123 Unhandled.erase(Unhandled.begin());
115 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 124 if (Verbose) {
116 Str << "\nConsidering "; 125 Str << "\nConsidering ";
117 Cur.dump(Func); 126 Cur.dump(Func);
118 Str << "\n"; 127 Str << "\n";
119 } 128 }
120 const llvm::SmallBitVector RegMask = 129 const llvm::SmallBitVector RegMask =
121 RegMaskFull & 130 RegMaskFull &
122 Func->getTarget()->getRegisterSetForType(Cur.Var->getType()); 131 Func->getTarget()->getRegisterSetForType(Cur.Var->getType());
123 132
124 // Check for precolored ranges. If Cur is precolored, it 133 // Check for precolored ranges. If Cur is precolored, it
125 // definitely gets that register. Previously processed live 134 // definitely gets that register. Previously processed live
126 // ranges would have avoided that register due to it being 135 // ranges would have avoided that register due to it being
127 // precolored. Future processed live ranges won't evict that 136 // precolored. Future processed live ranges won't evict that
128 // register because the live range has infinite weight. 137 // register because the live range has infinite weight.
129 if (Cur.Var->hasReg()) { 138 if (Cur.Var->hasReg()) {
130 int32_t RegNum = Cur.Var->getRegNum(); 139 int32_t RegNum = Cur.Var->getRegNum();
131 // RegNumTmp should have already been set above. 140 // RegNumTmp should have already been set above.
132 assert(Cur.Var->getRegNumTmp() == RegNum); 141 assert(Cur.Var->getRegNumTmp() == RegNum);
133 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 142 if (Verbose) {
134 Str << "Precoloring "; 143 Str << "Precoloring ";
135 Cur.dump(Func); 144 Cur.dump(Func);
136 Str << "\n"; 145 Str << "\n";
137 } 146 }
138 Active.push_back(Cur); 147 Active.push_back(Cur);
139 assert(RegUses[RegNum] >= 0); 148 assert(RegUses[RegNum] >= 0);
140 ++RegUses[RegNum]; 149 ++RegUses[RegNum];
141 continue; 150 continue;
142 } 151 }
143 152
144 // Check for active ranges that have expired or become inactive. 153 // Check for active ranges that have expired or become inactive.
145 for (UnorderedRanges::iterator I = Active.begin(), E = Active.end(); I != E; 154 for (UnorderedRanges::iterator I = Active.begin(), E = Active.end(); I != E;
146 I = Next) { 155 I = Next) {
147 Next = I; 156 Next = I;
148 ++Next; 157 ++Next;
149 LiveRangeWrapper Item = *I; 158 LiveRangeWrapper Item = *I;
150 bool Moved = false; 159 bool Moved = false;
151 if (Item.endsBefore(Cur)) { 160 if (Item.endsBefore(Cur)) {
152 // Move Item from Active to Handled list. 161 // Move Item from Active to Handled list.
153 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 162 if (Verbose) {
154 Str << "Expiring "; 163 Str << "Expiring ";
155 Item.dump(Func); 164 Item.dump(Func);
156 Str << "\n"; 165 Str << "\n";
157 } 166 }
158 Active.erase(I); 167 Active.erase(I);
159 Handled.push_back(Item); 168 Handled.push_back(Item);
160 Moved = true; 169 Moved = true;
161 } else if (!Item.overlapsStart(Cur)) { 170 } else if (!Item.overlapsStart(Cur)) {
162 // Move Item from Active to Inactive list. 171 // Move Item from Active to Inactive list.
163 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 172 if (Verbose) {
164 Str << "Inactivating "; 173 Str << "Inactivating ";
165 Item.dump(Func); 174 Item.dump(Func);
166 Str << "\n"; 175 Str << "\n";
167 } 176 }
168 Active.erase(I); 177 Active.erase(I);
169 Inactive.push_back(Item); 178 Inactive.push_back(Item);
170 Moved = true; 179 Moved = true;
171 } 180 }
172 if (Moved) { 181 if (Moved) {
173 // Decrement Item from RegUses[]. 182 // Decrement Item from RegUses[].
174 assert(Item.Var->hasRegTmp()); 183 assert(Item.Var->hasRegTmp());
175 int32_t RegNum = Item.Var->getRegNumTmp(); 184 int32_t RegNum = Item.Var->getRegNumTmp();
176 --RegUses[RegNum]; 185 --RegUses[RegNum];
177 assert(RegUses[RegNum] >= 0); 186 assert(RegUses[RegNum] >= 0);
178 } 187 }
179 } 188 }
180 189
181 // Check for inactive ranges that have expired or reactivated. 190 // Check for inactive ranges that have expired or reactivated.
182 for (UnorderedRanges::iterator I = Inactive.begin(), E = Inactive.end(); 191 for (UnorderedRanges::iterator I = Inactive.begin(), E = Inactive.end();
183 I != E; I = Next) { 192 I != E; I = Next) {
184 Next = I; 193 Next = I;
185 ++Next; 194 ++Next;
186 LiveRangeWrapper Item = *I; 195 LiveRangeWrapper Item = *I;
187 if (Item.endsBefore(Cur)) { 196 if (Item.endsBefore(Cur)) {
188 // Move Item from Inactive to Handled list. 197 // Move Item from Inactive to Handled list.
189 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 198 if (Verbose) {
190 Str << "Expiring "; 199 Str << "Expiring ";
191 Item.dump(Func); 200 Item.dump(Func);
192 Str << "\n"; 201 Str << "\n";
193 } 202 }
194 Inactive.erase(I); 203 Inactive.erase(I);
195 Handled.push_back(Item); 204 Handled.push_back(Item);
196 } else if (Item.overlapsStart(Cur)) { 205 } else if (Item.overlapsStart(Cur)) {
197 // Move Item from Inactive to Active list. 206 // Move Item from Inactive to Active list.
198 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 207 if (Verbose) {
199 Str << "Reactivating "; 208 Str << "Reactivating ";
200 Item.dump(Func); 209 Item.dump(Func);
201 Str << "\n"; 210 Str << "\n";
202 } 211 }
203 Inactive.erase(I); 212 Inactive.erase(I);
204 Active.push_back(Item); 213 Active.push_back(Item);
205 // Increment Item in RegUses[]. 214 // Increment Item in RegUses[].
206 assert(Item.Var->hasRegTmp()); 215 assert(Item.Var->hasRegTmp());
207 int32_t RegNum = Item.Var->getRegNumTmp(); 216 int32_t RegNum = Item.Var->getRegNumTmp();
208 assert(RegUses[RegNum] >= 0); 217 assert(RegUses[RegNum] >= 0);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 IsSingleDef && IsAssign && !overlapsDefs(Func, Cur, SrcVar); 263 IsSingleDef && IsAssign && !overlapsDefs(Func, Cur, SrcVar);
255 } 264 }
256 if (AllowOverlap || Free[SrcReg]) { 265 if (AllowOverlap || Free[SrcReg]) {
257 Prefer = SrcVar; 266 Prefer = SrcVar;
258 PreferReg = SrcReg; 267 PreferReg = SrcReg;
259 } 268 }
260 } 269 }
261 } 270 }
262 } 271 }
263 } 272 }
264 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 273 if (Verbose) {
265 if (Prefer) { 274 if (Prefer) {
266 Str << "Initial Prefer=" << *Prefer << " R=" << PreferReg 275 Str << "Initial Prefer=" << *Prefer << " R=" << PreferReg
267 << " LIVE=" << Prefer->getLiveRange() << " Overlap=" << AllowOverlap 276 << " LIVE=" << Prefer->getLiveRange() << " Overlap=" << AllowOverlap
268 << "\n"; 277 << "\n";
269 } 278 }
270 } 279 }
271 280
272 // Remove registers from the Free[] list where an Inactive range 281 // Remove registers from the Free[] list where an Inactive range
273 // overlaps with the current range. 282 // overlaps with the current range.
274 for (UnorderedRanges::const_iterator I = Inactive.begin(), 283 for (UnorderedRanges::const_iterator I = Inactive.begin(),
275 E = Inactive.end(); 284 E = Inactive.end();
276 I != E; ++I) { 285 I != E; ++I) {
277 LiveRangeWrapper Item = *I; 286 LiveRangeWrapper Item = *I;
278 if (Item.overlaps(Cur)) { 287 if (Item.overlaps(Cur)) {
279 int32_t RegNum = Item.Var->getRegNumTmp(); 288 int32_t RegNum = Item.Var->getRegNumTmp();
280 // Don't assert(Free[RegNum]) because in theory (though 289 // Don't assert(Free[RegNum]) because in theory (though
281 // probably never in practice) there could be two inactive 290 // probably never in practice) there could be two inactive
282 // variables that were allowed marked with 291 // variables that were marked with AllowOverlap.
283 // AllowRegisterOverlap.
284 Free[RegNum] = false; 292 Free[RegNum] = false;
285 // Disable AllowOverlap if an Inactive variable, which is not 293 // Disable AllowOverlap if an Inactive variable, which is not
286 // Prefer, shares Prefer's register, and has a definition 294 // Prefer, shares Prefer's register, and has a definition
287 // within Cur's live range. 295 // within Cur's live range.
288 if (AllowOverlap && Item.Var != Prefer && RegNum == PreferReg && 296 if (AllowOverlap && Item.Var != Prefer && RegNum == PreferReg &&
289 overlapsDefs(Func, Cur, Item.Var)) { 297 overlapsDefs(Func, Cur, Item.Var)) {
290 AllowOverlap = false; 298 AllowOverlap = false;
291 dumpDisableOverlap(Func, Item.Var, "Inactive"); 299 dumpDisableOverlap(Func, Item.Var, "Inactive");
292 } 300 }
293 } 301 }
(...skipping 30 matching lines...) Expand all
324 // Disable AllowOverlap if the preferred register is one of 332 // Disable AllowOverlap if the preferred register is one of
325 // these precolored unhandled overlapping ranges. 333 // these precolored unhandled overlapping ranges.
326 if (AllowOverlap && ItemReg == PreferReg) { 334 if (AllowOverlap && ItemReg == PreferReg) {
327 AllowOverlap = false; 335 AllowOverlap = false;
328 dumpDisableOverlap(Func, Item.Var, "PrecoloredUnhandled"); 336 dumpDisableOverlap(Func, Item.Var, "PrecoloredUnhandled");
329 } 337 }
330 } 338 }
331 } 339 }
332 340
333 // Print info about physical register availability. 341 // Print info about physical register availability.
334 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 342 if (Verbose) {
335 for (SizeT i = 0; i < RegMask.size(); ++i) { 343 for (SizeT i = 0; i < RegMask.size(); ++i) {
336 if (RegMask[i]) { 344 if (RegMask[i]) {
337 Str << Func->getTarget()->getRegName(i, IceType_i32) 345 Str << Func->getTarget()->getRegName(i, IceType_i32)
338 << "(U=" << RegUses[i] << ",F=" << Free[i] 346 << "(U=" << RegUses[i] << ",F=" << Free[i]
339 << ",P=" << PrecoloredUnhandled[i] << ") "; 347 << ",P=" << PrecoloredUnhandled[i] << ") ";
340 } 348 }
341 } 349 }
342 Str << "\n"; 350 Str << "\n";
343 } 351 }
344 352
345 if (Prefer && (AllowOverlap || Free[PreferReg])) { 353 if (Prefer && (AllowOverlap || Free[PreferReg])) {
346 // First choice: a preferred register that is either free or is 354 // First choice: a preferred register that is either free or is
347 // allowed to overlap with its linked variable. 355 // allowed to overlap with its linked variable.
348 Cur.Var->setRegNumTmp(PreferReg); 356 Cur.Var->setRegNumTmp(PreferReg);
349 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 357 if (Verbose) {
350 Str << "Preferring "; 358 Str << "Preferring ";
351 Cur.dump(Func); 359 Cur.dump(Func);
352 Str << "\n"; 360 Str << "\n";
353 } 361 }
354 assert(RegUses[PreferReg] >= 0); 362 assert(RegUses[PreferReg] >= 0);
355 ++RegUses[PreferReg]; 363 ++RegUses[PreferReg];
356 Active.push_back(Cur); 364 Active.push_back(Cur);
357 } else if (Free.any()) { 365 } else if (Free.any()) {
358 // Second choice: any free register. TODO: After explicit 366 // Second choice: any free register. TODO: After explicit
359 // affinity is considered, is there a strategy better than just 367 // affinity is considered, is there a strategy better than just
360 // picking the lowest-numbered available register? 368 // picking the lowest-numbered available register?
361 int32_t RegNum = Free.find_first(); 369 int32_t RegNum = Free.find_first();
362 Cur.Var->setRegNumTmp(RegNum); 370 Cur.Var->setRegNumTmp(RegNum);
363 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 371 if (Verbose) {
364 Str << "Allocating "; 372 Str << "Allocating ";
365 Cur.dump(Func); 373 Cur.dump(Func);
366 Str << "\n"; 374 Str << "\n";
367 } 375 }
368 assert(RegUses[RegNum] >= 0); 376 assert(RegUses[RegNum] >= 0);
369 ++RegUses[RegNum]; 377 ++RegUses[RegNum];
370 Active.push_back(Cur); 378 Active.push_back(Cur);
371 } else { 379 } else {
372 // Fallback: there are no free registers, so we look for the 380 // Fallback: there are no free registers, so we look for the
373 // lowest-weight register and see if Cur has higher weight. 381 // lowest-weight register and see if Cur has higher weight.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 } 435 }
428 } else { 436 } else {
429 // Evict all live ranges in Active that register number 437 // Evict all live ranges in Active that register number
430 // MinWeightIndex is assigned to. 438 // MinWeightIndex is assigned to.
431 for (UnorderedRanges::iterator I = Active.begin(), E = Active.end(); 439 for (UnorderedRanges::iterator I = Active.begin(), E = Active.end();
432 I != E; I = Next) { 440 I != E; I = Next) {
433 Next = I; 441 Next = I;
434 ++Next; 442 ++Next;
435 LiveRangeWrapper Item = *I; 443 LiveRangeWrapper Item = *I;
436 if (Item.Var->getRegNumTmp() == MinWeightIndex) { 444 if (Item.Var->getRegNumTmp() == MinWeightIndex) {
437 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 445 if (Verbose) {
438 Str << "Evicting "; 446 Str << "Evicting ";
439 Item.dump(Func); 447 Item.dump(Func);
440 Str << "\n"; 448 Str << "\n";
441 } 449 }
442 --RegUses[MinWeightIndex]; 450 --RegUses[MinWeightIndex];
443 assert(RegUses[MinWeightIndex] >= 0); 451 assert(RegUses[MinWeightIndex] >= 0);
444 Item.Var->setRegNumTmp(Variable::NoRegister); 452 Item.Var->setRegNumTmp(Variable::NoRegister);
445 Active.erase(I); 453 Active.erase(I);
446 Handled.push_back(Item); 454 Handled.push_back(Item);
447 } 455 }
448 } 456 }
449 // Do the same for Inactive. 457 // Do the same for Inactive.
450 for (UnorderedRanges::iterator I = Inactive.begin(), E = Inactive.end(); 458 for (UnorderedRanges::iterator I = Inactive.begin(), E = Inactive.end();
451 I != E; I = Next) { 459 I != E; I = Next) {
452 Next = I; 460 Next = I;
453 ++Next; 461 ++Next;
454 LiveRangeWrapper Item = *I; 462 LiveRangeWrapper Item = *I;
455 // Note: The Item.overlaps(Cur) clause is not part of the 463 // Note: The Item.overlaps(Cur) clause is not part of the
456 // description of AssignMemLoc() in the original paper. But 464 // description of AssignMemLoc() in the original paper. But
457 // there doesn't seem to be any need to evict an inactive 465 // there doesn't seem to be any need to evict an inactive
458 // live range that doesn't overlap with the live range 466 // live range that doesn't overlap with the live range
459 // currently being considered. It's especially bad if we 467 // currently being considered. It's especially bad if we
460 // would end up evicting an infinite-weight but 468 // would end up evicting an infinite-weight but
461 // currently-inactive live range. The most common situation 469 // currently-inactive live range. The most common situation
462 // for this would be a scratch register kill set for call 470 // for this would be a scratch register kill set for call
463 // instructions. 471 // instructions.
464 if (Item.Var->getRegNumTmp() == MinWeightIndex && 472 if (Item.Var->getRegNumTmp() == MinWeightIndex &&
465 Item.overlaps(Cur)) { 473 Item.overlaps(Cur)) {
466 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 474 if (Verbose) {
467 Str << "Evicting "; 475 Str << "Evicting ";
468 Item.dump(Func); 476 Item.dump(Func);
469 Str << "\n"; 477 Str << "\n";
470 } 478 }
471 Item.Var->setRegNumTmp(Variable::NoRegister); 479 Item.Var->setRegNumTmp(Variable::NoRegister);
472 Inactive.erase(I); 480 Inactive.erase(I);
473 Handled.push_back(Item); 481 Handled.push_back(Item);
474 } 482 }
475 } 483 }
476 // Assign the register to Cur. 484 // Assign the register to Cur.
477 Cur.Var->setRegNumTmp(MinWeightIndex); 485 Cur.Var->setRegNumTmp(MinWeightIndex);
478 assert(RegUses[MinWeightIndex] >= 0); 486 assert(RegUses[MinWeightIndex] >= 0);
479 ++RegUses[MinWeightIndex]; 487 ++RegUses[MinWeightIndex];
480 Active.push_back(Cur); 488 Active.push_back(Cur);
481 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 489 if (Verbose) {
482 Str << "Allocating "; 490 Str << "Allocating ";
483 Cur.dump(Func); 491 Cur.dump(Func);
484 Str << "\n"; 492 Str << "\n";
485 } 493 }
486 } 494 }
487 } 495 }
488 dump(Func); 496 dump(Func);
489 } 497 }
490 // Move anything Active or Inactive to Handled for easier handling. 498 // Move anything Active or Inactive to Handled for easier handling.
491 for (UnorderedRanges::iterator I = Active.begin(), E = Active.end(); I != E; 499 for (UnorderedRanges::iterator I = Active.begin(), E = Active.end(); I != E;
(...skipping 10 matching lines...) Expand all
502 Handled.push_back(*I); 510 Handled.push_back(*I);
503 Inactive.erase(I); 511 Inactive.erase(I);
504 } 512 }
505 dump(Func); 513 dump(Func);
506 514
507 // Finish up by assigning RegNumTmp->RegNum for each Variable. 515 // Finish up by assigning RegNumTmp->RegNum for each Variable.
508 for (UnorderedRanges::const_iterator I = Handled.begin(), E = Handled.end(); 516 for (UnorderedRanges::const_iterator I = Handled.begin(), E = Handled.end();
509 I != E; ++I) { 517 I != E; ++I) {
510 LiveRangeWrapper Item = *I; 518 LiveRangeWrapper Item = *I;
511 int32_t RegNum = Item.Var->getRegNumTmp(); 519 int32_t RegNum = Item.Var->getRegNumTmp();
512 if (Func->getContext()->isVerbose(IceV_LinearScan)) { 520 if (Verbose) {
513 if (!Item.Var->hasRegTmp()) { 521 if (!Item.Var->hasRegTmp()) {
514 Str << "Not assigning "; 522 Str << "Not assigning ";
515 Item.Var->dump(Func); 523 Item.Var->dump(Func);
516 Str << "\n"; 524 Str << "\n";
517 } else { 525 } else {
518 Str << (RegNum == Item.Var->getRegNum() ? "Reassigning " : "Assigning ") 526 Str << (RegNum == Item.Var->getRegNum() ? "Reassigning " : "Assigning ")
519 << Func->getTarget()->getRegName(RegNum, IceType_i32) << "(r" 527 << Func->getTarget()->getRegName(RegNum, IceType_i32) << "(r"
520 << RegNum << ") to "; 528 << RegNum << ") to ";
521 Item.Var->dump(Func); 529 Item.Var->dump(Func);
522 Str << "\n"; 530 Str << "\n";
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 } 583 }
576 Str << "++++++ Inactive:\n"; 584 Str << "++++++ Inactive:\n";
577 for (UnorderedRanges::const_iterator I = Inactive.begin(), E = Inactive.end(); 585 for (UnorderedRanges::const_iterator I = Inactive.begin(), E = Inactive.end();
578 I != E; ++I) { 586 I != E; ++I) {
579 I->dump(Func); 587 I->dump(Func);
580 Str << "\n"; 588 Str << "\n";
581 } 589 }
582 } 590 }
583 591
584 } // end of namespace Ice 592 } // end of namespace Ice
OLDNEW
« src/IceOperand.cpp ('K') | « src/IceOperand.cpp ('k') | src/IceTargetLowering.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698