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

Side by Side Diff: src/IceRegAlloc.cpp

Issue 1368993004: Subzero: Improve usability of liveness-related tools. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Code review changes Created 5 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
« no previous file with comments | « src/IceRegAlloc.h ('k') | src/IceTargetLowering.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 for (CfgNode *Node : Func->getNodes()) { 125 for (CfgNode *Node : Func->getNodes()) {
126 for (Inst &I : Node->getInsts()) { 126 for (Inst &I : Node->getInsts()) {
127 if (auto Kill = llvm::dyn_cast<InstFakeKill>(&I)) { 127 if (auto Kill = llvm::dyn_cast<InstFakeKill>(&I)) {
128 if (!Kill->isDeleted() && !Kill->getLinked()->isDeleted()) 128 if (!Kill->isDeleted() && !Kill->getLinked()->isDeleted())
129 Kills.push_back(I.getNumber()); 129 Kills.push_back(I.getNumber());
130 } 130 }
131 } 131 }
132 } 132 }
133 } 133 }
134 134
135 // Validate the integrity of the live ranges. If there are any errors, it
136 // prints details and returns false. On success, it returns true.
137 bool LinearScan::livenessValidateIntervals(
138 const DefUseErrorList &DefsWithoutUses,
139 const DefUseErrorList &UsesBeforeDefs,
140 const CfgVector<InstNumberT> &LRBegin,
141 const CfgVector<InstNumberT> &LREnd) {
142 if (DefsWithoutUses.empty() && UsesBeforeDefs.empty())
143 return true;
144
145 if (!BuildDefs::dump())
146 return false;
147
148 const VarList &Vars = Func->getVariables();
149 OstreamLocker L(Ctx);
150 Ostream &Str = Ctx->getStrDump();
151 for (SizeT VarNum : DefsWithoutUses) {
152 Variable *Var = Vars[VarNum];
153 Str << "LR def without use, instruction " << LRBegin[VarNum]
154 << ", variable " << Var->getName(Func) << "\n";
155 }
156 for (SizeT VarNum : UsesBeforeDefs) {
157 Variable *Var = Vars[VarNum];
158 Str << "LR use before def, instruction " << LREnd[VarNum] << ", variable "
159 << Var->getName(Func) << "\n";
160 }
161 return false;
162 }
163
135 // Prepare for very simple register allocation of only infinite-weight 164 // Prepare for very simple register allocation of only infinite-weight
136 // Variables while respecting pre-colored Variables. Some properties we take 165 // Variables while respecting pre-colored Variables. Some properties we take
137 // advantage of: 166 // advantage of:
138 // 167 //
139 // * Live ranges of interest consist of a single segment. 168 // * Live ranges of interest consist of a single segment.
140 // 169 //
141 // * Live ranges of interest never span a call instruction. 170 // * Live ranges of interest never span a call instruction.
142 // 171 //
143 // * Phi instructions are not considered because either phis have already been 172 // * Phi instructions are not considered because either phis have already been
144 // lowered, or they don't contain any pre-colored or infinite-weight 173 // lowered, or they don't contain any pre-colored or infinite-weight
(...skipping 16 matching lines...) Expand all
161 TimerMarker T(TimerStack::TT_initUnhandled, Func); 190 TimerMarker T(TimerStack::TT_initUnhandled, Func);
162 FindPreference = false; 191 FindPreference = false;
163 FindOverlap = false; 192 FindOverlap = false;
164 SizeT NumVars = 0; 193 SizeT NumVars = 0;
165 const VarList &Vars = Func->getVariables(); 194 const VarList &Vars = Func->getVariables();
166 195
167 // Iterate across all instructions and record the begin and end of the live 196 // Iterate across all instructions and record the begin and end of the live
168 // range for each variable that is pre-colored or infinite weight. 197 // range for each variable that is pre-colored or infinite weight.
169 CfgVector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel); 198 CfgVector<InstNumberT> LRBegin(Vars.size(), Inst::NumberSentinel);
170 CfgVector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel); 199 CfgVector<InstNumberT> LREnd(Vars.size(), Inst::NumberSentinel);
200 DefUseErrorList DefsWithoutUses, UsesBeforeDefs;
171 for (CfgNode *Node : Func->getNodes()) { 201 for (CfgNode *Node : Func->getNodes()) {
172 for (Inst &Inst : Node->getInsts()) { 202 for (Inst &Inst : Node->getInsts()) {
173 if (Inst.isDeleted()) 203 if (Inst.isDeleted())
174 continue; 204 continue;
205 FOREACH_VAR_IN_INST(Var, Inst) {
206 if (Var->getIgnoreLiveness())
207 continue;
208 if (Var->hasReg() || Var->mustHaveReg()) {
209 SizeT VarNum = Var->getIndex();
210 LREnd[VarNum] = Inst.getNumber();
211 if (!Var->getIsArg() && LRBegin[VarNum] == Inst::NumberSentinel)
212 UsesBeforeDefs.push_back(VarNum);
213 }
214 }
175 if (const Variable *Var = Inst.getDest()) { 215 if (const Variable *Var = Inst.getDest()) {
176 if (!Var->getIgnoreLiveness() && 216 if (!Var->getIgnoreLiveness() &&
177 (Var->hasReg() || Var->mustHaveReg())) { 217 (Var->hasReg() || Var->mustHaveReg())) {
178 if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) { 218 if (LRBegin[Var->getIndex()] == Inst::NumberSentinel) {
179 LRBegin[Var->getIndex()] = Inst.getNumber(); 219 LRBegin[Var->getIndex()] = Inst.getNumber();
180 ++NumVars; 220 ++NumVars;
181 } 221 }
182 } 222 }
183 } 223 }
184 FOREACH_VAR_IN_INST(Var, Inst) {
185 if (Var->getIgnoreLiveness())
186 continue;
187 if (Var->hasReg() || Var->mustHaveReg())
188 LREnd[Var->getIndex()] = Inst.getNumber();
189 }
190 } 224 }
191 } 225 }
192 226
193 Unhandled.reserve(NumVars); 227 Unhandled.reserve(NumVars);
194 UnhandledPrecolored.reserve(NumVars); 228 UnhandledPrecolored.reserve(NumVars);
195 for (SizeT i = 0; i < Vars.size(); ++i) { 229 for (SizeT i = 0; i < Vars.size(); ++i) {
196 Variable *Var = Vars[i]; 230 Variable *Var = Vars[i];
197 if (LRBegin[i] != Inst::NumberSentinel) { 231 if (LRBegin[i] != Inst::NumberSentinel) {
198 assert(LREnd[i] != Inst::NumberSentinel); 232 if (LREnd[i] == Inst::NumberSentinel) {
233 DefsWithoutUses.push_back(i);
234 continue;
235 }
199 Unhandled.push_back(Var); 236 Unhandled.push_back(Var);
200 Var->resetLiveRange(); 237 Var->resetLiveRange();
201 Var->addLiveRange(LRBegin[i], LREnd[i]); 238 Var->addLiveRange(LRBegin[i], LREnd[i]);
202 Var->untrimLiveRange(); 239 Var->untrimLiveRange();
203 if (Var->hasReg()) { 240 if (Var->hasReg()) {
204 Var->setRegNumTmp(Var->getRegNum()); 241 Var->setRegNumTmp(Var->getRegNum());
205 Var->setMustHaveReg(); 242 Var->setMustHaveReg();
206 UnhandledPrecolored.push_back(Var); 243 UnhandledPrecolored.push_back(Var);
207 } 244 }
208 --NumVars; 245 --NumVars;
209 } 246 }
210 } 247 }
248
249 if (!livenessValidateIntervals(DefsWithoutUses, UsesBeforeDefs, LRBegin,
250 LREnd)) {
251 llvm::report_fatal_error("initForInfOnly: Liveness error");
252 return;
253 }
254
255 if (!DefsWithoutUses.empty() || !UsesBeforeDefs.empty()) {
256 if (BuildDefs::dump()) {
257 OstreamLocker L(Ctx);
258 Ostream &Str = Ctx->getStrDump();
259 for (SizeT VarNum : DefsWithoutUses) {
260 Variable *Var = Vars[VarNum];
261 Str << "LR def without use, instruction " << LRBegin[VarNum]
262 << ", variable " << Var->getName(Func) << "\n";
263 }
264 for (SizeT VarNum : UsesBeforeDefs) {
265 Variable *Var = Vars[VarNum];
266 Str << "LR use before def, instruction " << LREnd[VarNum]
267 << ", variable " << Var->getName(Func) << "\n";
268 }
269 }
270 llvm::report_fatal_error("initForInfOnly: Liveness error");
271 }
211 // This isn't actually a fatal condition, but it would be nice to know if we 272 // This isn't actually a fatal condition, but it would be nice to know if we
212 // somehow pre-calculated Unhandled's size wrong. 273 // somehow pre-calculated Unhandled's size wrong.
213 assert(NumVars == 0); 274 assert(NumVars == 0);
214 275
215 // Don't build up the list of Kills because we know that no infinite-weight 276 // Don't build up the list of Kills because we know that no infinite-weight
216 // Variable has a live range spanning a call. 277 // Variable has a live range spanning a call.
217 Kills.clear(); 278 Kills.clear();
218 } 279 }
219 280
220 void LinearScan::init(RegAllocKind Kind) { 281 void LinearScan::init(RegAllocKind Kind) {
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 Str << "\n"; 944 Str << "\n";
884 } 945 }
885 Str << "++++++ Inactive:\n"; 946 Str << "++++++ Inactive:\n";
886 for (const Variable *Item : Inactive) { 947 for (const Variable *Item : Inactive) {
887 dumpLiveRange(Item, Func); 948 dumpLiveRange(Item, Func);
888 Str << "\n"; 949 Str << "\n";
889 } 950 }
890 } 951 }
891 952
892 } // end of namespace Ice 953 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceRegAlloc.h ('k') | src/IceTargetLowering.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698