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

Side by Side Diff: src/IceOperand.cpp

Issue 597003004: Subzero: Automatically infer regalloc preferences and overlap. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Code review changes 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
« no previous file with comments | « src/IceOperand.h ('k') | src/IceRegAlloc.cpp » ('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/IceOperand.cpp - High-level operand implementation -----===// 1 //===- subzero/src/IceOperand.cpp - High-level operand 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 Operand class and its target-independent 10 // This file implements the Operand class and its target-independent
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 158
159 void VariableTracking::markUse(const Inst *Instr, const CfgNode *Node, 159 void VariableTracking::markUse(const Inst *Instr, const CfgNode *Node,
160 bool IsFromDef, bool IsImplicit) { 160 bool IsFromDef, bool IsImplicit) {
161 // TODO(stichnot): If the use occurs as a source operand in the 161 // TODO(stichnot): If the use occurs as a source operand in the
162 // first instruction of the block, and its definition is in this 162 // first instruction of the block, and its definition is in this
163 // block's only predecessor, we might consider not marking this as a 163 // block's only predecessor, we might consider not marking this as a
164 // separate use. This may also apply if it's the first instruction 164 // separate use. This may also apply if it's the first instruction
165 // of the block that actually uses a Variable. 165 // of the block that actually uses a Variable.
166 assert(Node); 166 assert(Node);
167 bool MakeMulti = false; 167 bool MakeMulti = false;
168 if (IsImplicit)
169 MakeMulti = true;
168 // A phi source variable conservatively needs to be marked as 170 // A phi source variable conservatively needs to be marked as
169 // multi-block, even if its definition is in the same block. This 171 // multi-block, even if its definition is in the same block. This
170 // is because there can be additional control flow before branching 172 // is because there can be additional control flow before branching
171 // back to this node, and the variable is live throughout those 173 // back to this node, and the variable is live throughout those
172 // nodes. 174 // nodes.
173 if (IsImplicit)
174 MakeMulti = true;
175 if (!IsFromDef && Instr && llvm::isa<InstPhi>(Instr)) 175 if (!IsFromDef && Instr && llvm::isa<InstPhi>(Instr))
176 MakeMulti = true; 176 MakeMulti = true;
177 177
178 if (!MakeMulti) { 178 if (!MakeMulti) {
179 switch (MultiBlock) { 179 switch (MultiBlock) {
180 case MBS_Unknown: 180 case MBS_Unknown:
181 MultiBlock = MBS_SingleBlock; 181 MultiBlock = MBS_SingleBlock;
182 SingleUseNode = Node; 182 SingleUseNode = Node;
183 break; 183 break;
184 case MBS_SingleBlock: 184 case MBS_SingleBlock:
185 if (SingleUseNode != Node) 185 if (SingleUseNode != Node)
186 MakeMulti = true; 186 MakeMulti = true;
187 break; 187 break;
188 case MBS_MultiBlock: 188 case MBS_MultiBlock:
189 break; 189 break;
190 } 190 }
191 } 191 }
192 192
193 if (MakeMulti) { 193 if (MakeMulti) {
194 MultiBlock = MBS_MultiBlock; 194 MultiBlock = MBS_MultiBlock;
195 SingleUseNode = NULL; 195 SingleUseNode = NULL;
196 } 196 }
197 } 197 }
198 198
199 void VariableTracking::markDef(const Inst *Instr, const CfgNode *Node) { 199 void VariableTracking::markDef(const Inst *Instr, const CfgNode *Node) {
200 // TODO(stichnot): If the definition occurs in the last instruction 200 // TODO(stichnot): If the definition occurs in the last instruction
201 // of the block, consider not marking this as a separate use. But 201 // of the block, consider not marking this as a separate use. But
202 // be careful not to omit all uses of the variable if markDef() and 202 // be careful not to omit all uses of the variable if markDef() and
203 // markUse() both use this optimization. 203 // markUse() both use this optimization.
204 assert(Node);
205 Definitions.push_back(Instr);
204 const bool IsFromDef = true; 206 const bool IsFromDef = true;
205 const bool IsImplicit = false; 207 const bool IsImplicit = false;
206 markUse(Instr, Node, IsFromDef, IsImplicit); 208 markUse(Instr, Node, IsFromDef, IsImplicit);
207 switch (MultiDef) { 209 switch (MultiDef) {
208 case MDS_Unknown: 210 case MDS_Unknown:
211 assert(SingleDefNode == NULL);
209 MultiDef = MDS_SingleDef; 212 MultiDef = MDS_SingleDef;
210 SingleDefInst = Instr; 213 SingleDefNode = Node;
211 break; 214 break;
212 case MDS_SingleDef: 215 case MDS_SingleDef:
213 MultiDef = MDS_MultiDef; 216 assert(SingleDefNode);
214 SingleDefInst = NULL; 217 if (Node == SingleDefNode) {
218 MultiDef = MDS_MultiDefSingleBlock;
219 } else {
220 MultiDef = MDS_MultiDefMultiBlock;
221 SingleDefNode = NULL;
222 }
215 break; 223 break;
216 case MDS_MultiDef: 224 case MDS_MultiDefSingleBlock:
225 assert(SingleDefNode);
226 if (Node != SingleDefNode) {
227 MultiDef = MDS_MultiDefMultiBlock;
228 SingleDefNode = NULL;
229 }
217 break; 230 break;
231 case MDS_MultiDefMultiBlock:
232 assert(SingleDefNode == NULL);
233 break;
234 }
235 }
236
237 const Inst *VariableTracking::getFirstDefinition() const {
238 switch (MultiDef) {
239 case MDS_Unknown:
240 case MDS_MultiDefMultiBlock:
241 return NULL;
242 case MDS_SingleDef:
243 case MDS_MultiDefSingleBlock:
244 assert(!Definitions.empty());
245 return Definitions[0];
246 }
247 }
248
249 const Inst *VariableTracking::getSingleDefinition() const {
250 switch (MultiDef) {
251 case MDS_Unknown:
252 case MDS_MultiDefMultiBlock:
253 case MDS_MultiDefSingleBlock:
254 return NULL;
255 case MDS_SingleDef:
256 assert(!Definitions.empty());
257 return Definitions[0];
218 } 258 }
219 } 259 }
220 260
221 void VariablesMetadata::init() { 261 void VariablesMetadata::init() {
222 Metadata.clear(); 262 Metadata.clear();
223 Metadata.resize(Func->getNumVariables()); 263 Metadata.resize(Func->getNumVariables());
224 264
225 // Mark implicit args as being used in the entry node. 265 // Mark implicit args as being used in the entry node.
226 const VarList &ImplicitArgList = Func->getImplicitArgs(); 266 const VarList &ImplicitArgList = Func->getImplicitArgs();
227 for (VarList::const_iterator I = ImplicitArgList.begin(), 267 for (VarList::const_iterator I = ImplicitArgList.begin(),
228 E = ImplicitArgList.end(); 268 E = ImplicitArgList.end();
229 I != E; ++I) { 269 I != E; ++I) {
230 const Variable *Var = *I; 270 const Variable *Var = *I;
231 const Inst *NoInst = NULL; 271 const Inst *NoInst = NULL;
232 const CfgNode *EntryNode = Func->getEntryNode(); 272 const CfgNode *EntryNode = Func->getEntryNode();
233 const bool IsFromDef = false; 273 const bool IsFromDef = false;
234 const bool IsImplicit = true; 274 const bool IsImplicit = true;
235 Metadata[Var->getIndex()].markUse(NoInst, EntryNode, IsFromDef, IsImplicit); 275 Metadata[Var->getIndex()].markUse(NoInst, EntryNode, IsFromDef, IsImplicit);
236 } 276 }
237 277
238 SizeT NumNodes = Func->getNumNodes(); 278 SizeT NumNodes = Func->getNumNodes();
239 for (SizeT N = 0; N < NumNodes; ++N) { 279 for (SizeT N = 0; N < NumNodes; ++N) {
240 CfgNode *Node = Func->getNodes()[N]; 280 CfgNode *Node = Func->getNodes()[N];
241 const InstList &Insts = Node->getInsts(); 281 const InstList &Insts = Node->getInsts();
242 for (InstList::const_iterator I = Insts.begin(), E = Insts.end(); I != E; 282 for (InstList::const_iterator I = Insts.begin(), E = Insts.end(); I != E;
243 ++I) { 283 ++I) {
244 if ((*I)->isDeleted()) 284 if ((*I)->isDeleted())
245 continue; 285 continue;
286 if (InstFakeKill *Kill = llvm::dyn_cast<InstFakeKill>(*I)) {
287 // A FakeKill instruction indicates certain Variables (usually
288 // physical scratch registers) are redefined, so we register
289 // them as defs.
290 for (SizeT SrcNum = 0; SrcNum < (*I)->getSrcSize(); ++SrcNum) {
291 Variable *Var = llvm::cast<Variable>((*I)->getSrc(SrcNum));
292 SizeT VarNum = Var->getIndex();
293 assert(VarNum < Metadata.size());
294 Metadata[VarNum].markDef(Kill, Node);
295 }
296 continue; // no point in executing the rest
297 }
246 if (Variable *Dest = (*I)->getDest()) { 298 if (Variable *Dest = (*I)->getDest()) {
247 SizeT DestNum = Dest->getIndex(); 299 SizeT DestNum = Dest->getIndex();
248 assert(DestNum < Metadata.size()); 300 assert(DestNum < Metadata.size());
249 Metadata[DestNum].markDef(*I, Node); 301 Metadata[DestNum].markDef(*I, Node);
250 } 302 }
251 for (SizeT SrcNum = 0; SrcNum < (*I)->getSrcSize(); ++SrcNum) { 303 for (SizeT SrcNum = 0; SrcNum < (*I)->getSrcSize(); ++SrcNum) {
252 Operand *Src = (*I)->getSrc(SrcNum); 304 Operand *Src = (*I)->getSrc(SrcNum);
253 SizeT NumVars = Src->getNumVars(); 305 SizeT NumVars = Src->getNumVars();
254 for (SizeT J = 0; J < NumVars; ++J) { 306 for (SizeT J = 0; J < NumVars; ++J) {
255 const Variable *Var = Src->getVar(J); 307 const Variable *Var = Src->getVar(J);
(...skipping 12 matching lines...) Expand all
268 if (Var->getIsArg()) 320 if (Var->getIsArg())
269 return false; 321 return false;
270 if (!isTracked(Var)) 322 if (!isTracked(Var))
271 return true; // conservative answer 323 return true; // conservative answer
272 SizeT VarNum = Var->getIndex(); 324 SizeT VarNum = Var->getIndex();
273 // Conservatively return true if the state is unknown. 325 // Conservatively return true if the state is unknown.
274 return Metadata[VarNum].getMultiDef() != VariableTracking::MDS_SingleDef; 326 return Metadata[VarNum].getMultiDef() != VariableTracking::MDS_SingleDef;
275 } 327 }
276 328
277 bool VariablesMetadata::isMultiBlock(const Variable *Var) const { 329 bool VariablesMetadata::isMultiBlock(const Variable *Var) const {
278 if (getDefinition(Var) == NULL) 330 if (Var->getIsArg())
279 return true; 331 return true;
332 if (!isTracked(Var))
333 return true; // conservative answer
280 SizeT VarNum = Var->getIndex(); 334 SizeT VarNum = Var->getIndex();
281 // Conservatively return true if the state is unknown. 335 // Conservatively return true if the state is unknown.
282 return Metadata[VarNum].getMultiBlock() != VariableTracking::MBS_SingleBlock; 336 return Metadata[VarNum].getMultiBlock() != VariableTracking::MBS_SingleBlock;
283 } 337 }
284 338
285 const Inst *VariablesMetadata::getDefinition(const Variable *Var) const { 339 const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const {
286 if (!isTracked(Var)) 340 if (!isTracked(Var))
287 return NULL; // conservative answer 341 return NULL; // conservative answer
288 SizeT VarNum = Var->getIndex(); 342 SizeT VarNum = Var->getIndex();
289 return Metadata[VarNum].getDefinition(); 343 return Metadata[VarNum].getFirstDefinition();
344 }
345
346 const Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const {
347 if (!isTracked(Var))
348 return NULL; // conservative answer
349 SizeT VarNum = Var->getIndex();
350 return Metadata[VarNum].getSingleDefinition();
351 }
352
353 const InstDefList &
354 VariablesMetadata::getDefinitions(const Variable *Var) const {
355 if (!isTracked(Var))
356 return NoDefinitions;
357 SizeT VarNum = Var->getIndex();
358 return Metadata[VarNum].getDefinitions();
290 } 359 }
291 360
292 const CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const { 361 const CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const {
293 if (!isTracked(Var)) 362 if (!isTracked(Var))
294 return NULL; // conservative answer 363 return NULL; // conservative answer
295 SizeT VarNum = Var->getIndex(); 364 SizeT VarNum = Var->getIndex();
296 return Metadata[VarNum].getNode(); 365 return Metadata[VarNum].getNode();
297 } 366 }
298 367
368 const InstDefList VariablesMetadata::NoDefinitions;
369
299 // ======================== dump routines ======================== // 370 // ======================== dump routines ======================== //
300 371
301 void Variable::emit(const Cfg *Func) const { 372 void Variable::emit(const Cfg *Func) const {
302 Func->getTarget()->emitVariable(this); 373 Func->getTarget()->emitVariable(this);
303 } 374 }
304 375
305 void Variable::dump(const Cfg *Func, Ostream &Str) const { 376 void Variable::dump(const Cfg *Func, Ostream &Str) const {
306 if (Func == NULL) { 377 if (Func == NULL) {
307 Str << "%" << getName(); 378 Str << "%" << getName();
308 return; 379 return;
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 436
366 Ostream &operator<<(Ostream &Str, const RegWeight &W) { 437 Ostream &operator<<(Ostream &Str, const RegWeight &W) {
367 if (W.getWeight() == RegWeight::Inf) 438 if (W.getWeight() == RegWeight::Inf)
368 Str << "Inf"; 439 Str << "Inf";
369 else 440 else
370 Str << W.getWeight(); 441 Str << W.getWeight();
371 return Str; 442 return Str;
372 } 443 }
373 444
374 } // end of namespace Ice 445 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceOperand.h ('k') | src/IceRegAlloc.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698