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

Side by Side Diff: src/IceRegAlloc.cpp

Issue 1312433004: Weight variables by their number of uses for register allocation. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Tidy up lose ends. Created 5 years, 3 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 /// \file 10 /// \file
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 // register allocation since no overlap opportunities should be available and 92 // register allocation since no overlap opportunities should be available and
93 // it's more expensive to look for opportunities. 93 // it's more expensive to look for opportunities.
94 FindOverlap = (Kind != RAK_Phi); 94 FindOverlap = (Kind != RAK_Phi);
95 const VarList &Vars = Func->getVariables(); 95 const VarList &Vars = Func->getVariables();
96 Unhandled.reserve(Vars.size()); 96 Unhandled.reserve(Vars.size());
97 UnhandledPrecolored.reserve(Vars.size()); 97 UnhandledPrecolored.reserve(Vars.size());
98 // Gather the live ranges of all variables and add them to the Unhandled set. 98 // Gather the live ranges of all variables and add them to the Unhandled set.
99 for (Variable *Var : Vars) { 99 for (Variable *Var : Vars) {
100 // Explicitly don't consider zero-weight variables, which are meant to be 100 // Explicitly don't consider zero-weight variables, which are meant to be
101 // spill slots. 101 // spill slots.
102 if (Var->getWeight().isZero()) 102 if (Var->mustNotHaveReg())
103 continue; 103 continue;
104 // Don't bother if the variable has a null live range, which means it was 104 // Don't bother if the variable has a null live range, which means it was
105 // never referenced. 105 // never referenced.
106 if (Var->getLiveRange().isEmpty()) 106 if (Var->getLiveRange().isEmpty())
107 continue; 107 continue;
108 Var->untrimLiveRange(); 108 Var->untrimLiveRange();
109 Unhandled.push_back(Var); 109 Unhandled.push_back(Var);
110 if (Var->hasReg()) { 110 if (Var->hasReg()) {
111 Var->setRegNumTmp(Var->getRegNum()); 111 Var->setRegNumTmp(Var->getRegNum());
112 Var->setLiveRangeInfiniteWeight(); 112 Var->setMustHaveReg();
113 UnhandledPrecolored.push_back(Var); 113 UnhandledPrecolored.push_back(Var);
114 } 114 }
115 } 115 }
116 116
117 // Build the (ordered) list of FakeKill instruction numbers. 117 // Build the (ordered) list of FakeKill instruction numbers.
118 Kills.clear(); 118 Kills.clear();
119 // Phi lowering should not be creating new call instructions, so there should 119 // Phi lowering should not be creating new call instructions, so there should
120 // be no infinite-weight not-yet-colored live ranges that span a call 120 // be no infinite-weight not-yet-colored live ranges that span a call
121 // instruction, hence no need to construct the Kills list. 121 // instruction, hence no need to construct the Kills list.
122 if (Kind == RAK_Phi) 122 if (Kind == RAK_Phi)
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 // Iterate across all instructions and record the begin and end of the live 166 // Iterate across all instructions and record the begin and end of the live
167 // range for each variable that is pre-colored or infinite weight. 167 // range for each variable that is pre-colored or infinite weight.
168 std::vector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel); 168 std::vector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel);
169 std::vector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel); 169 std::vector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel);
170 for (CfgNode *Node : Func->getNodes()) { 170 for (CfgNode *Node : Func->getNodes()) {
171 for (Inst &Inst : Node->getInsts()) { 171 for (Inst &Inst : Node->getInsts()) {
172 if (Inst.isDeleted()) 172 if (Inst.isDeleted())
173 continue; 173 continue;
174 if (const Variable *Var = Inst.getDest()) { 174 if (const Variable *Var = Inst.getDest()) {
175 if (!Var->getIgnoreLiveness() && 175 if (!Var->getIgnoreLiveness() &&
176 (Var->hasReg() || Var->getWeight().isInf())) { 176 (Var->hasReg() || Var->mustHaveReg())) {
177 if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) { 177 if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) {
178 LRBegin[Var->getIndex()] = Inst.getNumber(); 178 LRBegin[Var->getIndex()] = Inst.getNumber();
179 ++NumVars; 179 ++NumVars;
180 } 180 }
181 } 181 }
182 } 182 }
183 for (SizeT I = 0; I < Inst.getSrcSize(); ++I) { 183 for (SizeT I = 0; I < Inst.getSrcSize(); ++I) {
184 Operand *Src = Inst.getSrc(I); 184 Operand *Src = Inst.getSrc(I);
185 SizeT NumVars = Src->getNumVars(); 185 SizeT NumVars = Src->getNumVars();
186 for (SizeT J = 0; J < NumVars; ++J) { 186 for (SizeT J = 0; J < NumVars; ++J) {
187 const Variable *Var = Src->getVar(J); 187 const Variable *Var = Src->getVar(J);
188 if (Var->getIgnoreLiveness()) 188 if (Var->getIgnoreLiveness())
189 continue; 189 continue;
190 if (Var->hasReg() || Var->getWeight().isInf()) 190 if (Var->hasReg() || Var->mustHaveReg())
191 LREnd[Var->getIndex()] = Inst.getNumber(); 191 LREnd[Var->getIndex()] = Inst.getNumber();
192 } 192 }
193 } 193 }
194 } 194 }
195 } 195 }
196 196
197 Unhandled.reserve(NumVars); 197 Unhandled.reserve(NumVars);
198 UnhandledPrecolored.reserve(NumVars); 198 UnhandledPrecolored.reserve(NumVars);
199 for (SizeT i = 0; i < Vars.size(); ++i) { 199 for (SizeT i = 0; i < Vars.size(); ++i) {
200 Variable *Var = Vars[i]; 200 Variable *Var = Vars[i];
201 if (LRBegin[i] != Inst::NumberSentinel) { 201 if (LRBegin[i] != Inst::NumberSentinel) {
202 assert(LREnd[i] != Inst::NumberSentinel); 202 assert(LREnd[i] != Inst::NumberSentinel);
203 Unhandled.push_back(Var); 203 Unhandled.push_back(Var);
204 Var->resetLiveRange(); 204 Var->resetLiveRange();
205 constexpr uint32_t WeightDelta = 1; 205 Var->addLiveRange(LRBegin[i], LREnd[i]);
206 Var->addLiveRange(LRBegin[i], LREnd[i], WeightDelta);
207 Var->untrimLiveRange(); 206 Var->untrimLiveRange();
208 if (Var->hasReg()) { 207 if (Var->hasReg()) {
209 Var->setRegNumTmp(Var->getRegNum()); 208 Var->setRegNumTmp(Var->getRegNum());
210 Var->setLiveRangeInfiniteWeight(); 209 Var->setMustHaveReg();
211 UnhandledPrecolored.push_back(Var); 210 UnhandledPrecolored.push_back(Var);
212 } 211 }
213 --NumVars; 212 --NumVars;
214 } 213 }
215 } 214 }
216 // This isn't actually a fatal condition, but it would be nice to know if we 215 // This isn't actually a fatal condition, but it would be nice to know if we
217 // somehow pre-calculated Unhandled's size wrong. 216 // somehow pre-calculated Unhandled's size wrong.
218 assert(NumVars == 0); 217 assert(NumVars == 0);
219 218
220 // Don't build up the list of Kills because we know that no infinite-weight 219 // Don't build up the list of Kills because we know that no infinite-weight
(...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 ++RegUses[RegNum]; 511 ++RegUses[RegNum];
513 Active.push_back(Iter.Cur); 512 Active.push_back(Iter.Cur);
514 } 513 }
515 514
516 void LinearScan::handleNoFreeRegisters(IterationState &Iter) { 515 void LinearScan::handleNoFreeRegisters(IterationState &Iter) {
517 // Check Active ranges. 516 // Check Active ranges.
518 for (const Variable *Item : Active) { 517 for (const Variable *Item : Active) {
519 assert(Item->rangeOverlaps(Iter.Cur)); 518 assert(Item->rangeOverlaps(Iter.Cur));
520 int32_t RegNum = Item->getRegNumTmp(); 519 int32_t RegNum = Item->getRegNumTmp();
521 assert(Item->hasRegTmp()); 520 assert(Item->hasRegTmp());
522 Iter.Weights[RegNum].addWeight(Item->getLiveRange().getWeight()); 521 Iter.Weights[RegNum].addWeight(Item->getWeight());
523 } 522 }
524 // Same as above, but check Inactive ranges instead of Active. 523 // Same as above, but check Inactive ranges instead of Active.
525 for (const Variable *Item : Inactive) { 524 for (const Variable *Item : Inactive) {
526 int32_t RegNum = Item->getRegNumTmp(); 525 int32_t RegNum = Item->getRegNumTmp();
527 assert(Item->hasRegTmp()); 526 assert(Item->hasRegTmp());
528 if (Item->rangeOverlaps(Iter.Cur)) 527 if (Item->rangeOverlaps(Iter.Cur))
529 Iter.Weights[RegNum].addWeight(Item->getLiveRange().getWeight()); 528 Iter.Weights[RegNum].addWeight(Item->getWeight());
530 } 529 }
531 530
532 // All the weights are now calculated. Find the register with smallest 531 // All the weights are now calculated. Find the register with smallest
533 // weight. 532 // weight.
534 int32_t MinWeightIndex = Iter.RegMask.find_first(); 533 int32_t MinWeightIndex = Iter.RegMask.find_first();
535 // MinWeightIndex must be valid because of the initial RegMask.any() test. 534 // MinWeightIndex must be valid because of the initial RegMask.any() test.
536 assert(MinWeightIndex >= 0); 535 assert(MinWeightIndex >= 0);
537 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) { 536 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) {
538 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex]) 537 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex])
539 MinWeightIndex = i; 538 MinWeightIndex = i;
540 } 539 }
541 540
542 if (Iter.Cur->getLiveRange().getWeight() <= Iter.Weights[MinWeightIndex]) { 541 if (Iter.Cur->getWeight() <= Iter.Weights[MinWeightIndex]) {
543 // Cur doesn't have priority over any other live ranges, so don't allocate 542 // Cur doesn't have priority over any other live ranges, so don't allocate
544 // any register to it, and move it to the Handled state. 543 // any register to it, and move it to the Handled state.
545 Handled.push_back(Iter.Cur); 544 Handled.push_back(Iter.Cur);
546 if (Iter.Cur->getLiveRange().getWeight().isInf()) { 545 if (Iter.Cur->mustHaveReg()) {
547 if (Kind == RAK_Phi) 546 if (Kind == RAK_Phi)
548 addSpillFill(Iter); 547 addSpillFill(Iter);
549 else 548 else
550 Func->setError("Unable to find a physical register for an " 549 Func->setError("Unable to find a physical register for an "
551 "infinite-weight live range"); 550 "infinite-weight live range");
552 } 551 }
553 } else { 552 } else {
554 // Evict all live ranges in Active that register number MinWeightIndex is 553 // Evict all live ranges in Active that register number MinWeightIndex is
555 // assigned to. 554 // assigned to.
556 for (SizeT I = Active.size(); I > 0; --I) { 555 for (SizeT I = Active.size(); I > 0; --I) {
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 Str << "\n"; 837 Str << "\n";
839 } 838 }
840 Str << "++++++ Inactive:\n"; 839 Str << "++++++ Inactive:\n";
841 for (const Variable *Item : Inactive) { 840 for (const Variable *Item : Inactive) {
842 dumpLiveRange(Item, Func); 841 dumpLiveRange(Item, Func);
843 Str << "\n"; 842 Str << "\n";
844 } 843 }
845 } 844 }
846 845
847 } // end of namespace Ice 846 } // end of namespace Ice
OLDNEW
« src/IceOperand.h ('K') | « src/IceOperand.cpp ('k') | src/IceTargetLoweringARM32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698