OLD | NEW |
---|---|
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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
178 | 178 |
179 Variable Variable::asType(Type Ty) { | 179 Variable Variable::asType(Type Ty) { |
180 // Note: This returns a Variable, even if the "this" object is a | 180 // Note: This returns a Variable, even if the "this" object is a |
181 // subclass of Variable. | 181 // subclass of Variable. |
182 Variable V(kVariable, Ty, Number, Name); | 182 Variable V(kVariable, Ty, Number, Name); |
183 V.RegNum = RegNum; | 183 V.RegNum = RegNum; |
184 V.StackOffset = StackOffset; | 184 V.StackOffset = StackOffset; |
185 return V; | 185 return V; |
186 } | 186 } |
187 | 187 |
188 void VariableTracking::markUse(const Inst *Instr, const CfgNode *Node, | 188 void VariableTracking::markUse(MetadataKind TrackingKind, const Inst *Instr, |
189 bool IsFromDef, bool IsImplicit) { | 189 const CfgNode *Node, bool IsFromDef, |
190 bool IsImplicit) { | |
191 (void)TrackingKind; | |
190 if (MultiBlock == MBS_MultiBlock) | 192 if (MultiBlock == MBS_MultiBlock) |
191 return; | 193 return; |
192 // TODO(stichnot): If the use occurs as a source operand in the | 194 // TODO(stichnot): If the use occurs as a source operand in the |
193 // first instruction of the block, and its definition is in this | 195 // first instruction of the block, and its definition is in this |
194 // block's only predecessor, we might consider not marking this as a | 196 // block's only predecessor, we might consider not marking this as a |
195 // separate use. This may also apply if it's the first instruction | 197 // separate use. This may also apply if it's the first instruction |
196 // of the block that actually uses a Variable. | 198 // of the block that actually uses a Variable. |
197 assert(Node); | 199 assert(Node); |
198 bool MakeMulti = false; | 200 bool MakeMulti = false; |
199 if (IsImplicit) | 201 if (IsImplicit) |
(...skipping 20 matching lines...) Expand all Loading... | |
220 break; | 222 break; |
221 } | 223 } |
222 } | 224 } |
223 | 225 |
224 if (MakeMulti) { | 226 if (MakeMulti) { |
225 MultiBlock = MBS_MultiBlock; | 227 MultiBlock = MBS_MultiBlock; |
226 SingleUseNode = NULL; | 228 SingleUseNode = NULL; |
227 } | 229 } |
228 } | 230 } |
229 | 231 |
230 void VariableTracking::markDef(const Inst *Instr, const CfgNode *Node) { | 232 void VariableTracking::markDef(MetadataKind TrackingKind, const Inst *Instr, |
233 const CfgNode *Node) { | |
231 // TODO(stichnot): If the definition occurs in the last instruction | 234 // TODO(stichnot): If the definition occurs in the last instruction |
232 // of the block, consider not marking this as a separate use. But | 235 // of the block, consider not marking this as a separate use. But |
233 // be careful not to omit all uses of the variable if markDef() and | 236 // be careful not to omit all uses of the variable if markDef() and |
234 // markUse() both use this optimization. | 237 // markUse() both use this optimization. |
235 assert(Node); | 238 assert(Node); |
236 // Verify that instructions are added in increasing order. | 239 // Verify that instructions are added in increasing order. |
237 assert(Definitions.empty() || | 240 if (TrackingKind == VMK_All) { |
238 Instr->getNumber() >= Definitions.back()->getNumber()); | 241 assert(Definitions.empty() || |
239 Definitions.push_back(Instr); | 242 Instr->getNumber() >= Definitions.back()->getNumber()); |
243 } | |
240 const bool IsFromDef = true; | 244 const bool IsFromDef = true; |
241 const bool IsImplicit = false; | 245 const bool IsImplicit = false; |
242 markUse(Instr, Node, IsFromDef, IsImplicit); | 246 markUse(TrackingKind, Instr, Node, IsFromDef, IsImplicit); |
247 if (TrackingKind == VMK_Uses) | |
248 return; | |
249 if (FirstDefinition == NULL) | |
jvoung (off chromium)
2014/10/15 17:44:54
Looks like this could be put under "if (TrackingKi
Jim Stichnoth
2014/10/15 21:29:43
Renamed the field to FirstOrSingleDefinition to cl
| |
250 FirstDefinition = Instr; | |
251 if (TrackingKind == VMK_All) | |
252 Definitions.push_back(Instr); | |
243 switch (MultiDef) { | 253 switch (MultiDef) { |
244 case MDS_Unknown: | 254 case MDS_Unknown: |
245 assert(SingleDefNode == NULL); | 255 assert(SingleDefNode == NULL); |
246 MultiDef = MDS_SingleDef; | 256 MultiDef = MDS_SingleDef; |
247 SingleDefNode = Node; | 257 SingleDefNode = Node; |
248 break; | 258 break; |
249 case MDS_SingleDef: | 259 case MDS_SingleDef: |
250 assert(SingleDefNode); | 260 assert(SingleDefNode); |
251 if (Node == SingleDefNode) { | 261 if (Node == SingleDefNode) { |
252 MultiDef = MDS_MultiDefSingleBlock; | 262 MultiDef = MDS_MultiDefSingleBlock; |
(...skipping 15 matching lines...) Expand all Loading... | |
268 } | 278 } |
269 } | 279 } |
270 | 280 |
271 const Inst *VariableTracking::getFirstDefinition() const { | 281 const Inst *VariableTracking::getFirstDefinition() const { |
272 switch (MultiDef) { | 282 switch (MultiDef) { |
273 case MDS_Unknown: | 283 case MDS_Unknown: |
274 case MDS_MultiDefMultiBlock: | 284 case MDS_MultiDefMultiBlock: |
275 return NULL; | 285 return NULL; |
276 case MDS_SingleDef: | 286 case MDS_SingleDef: |
277 case MDS_MultiDefSingleBlock: | 287 case MDS_MultiDefSingleBlock: |
278 assert(!Definitions.empty()); | 288 assert(FirstDefinition); |
279 return Definitions[0]; | 289 return FirstDefinition; |
280 } | 290 } |
281 } | 291 } |
282 | 292 |
283 const Inst *VariableTracking::getSingleDefinition() const { | 293 const Inst *VariableTracking::getSingleDefinition() const { |
284 switch (MultiDef) { | 294 switch (MultiDef) { |
285 case MDS_Unknown: | 295 case MDS_Unknown: |
286 case MDS_MultiDefMultiBlock: | 296 case MDS_MultiDefMultiBlock: |
287 case MDS_MultiDefSingleBlock: | 297 case MDS_MultiDefSingleBlock: |
288 return NULL; | 298 return NULL; |
289 case MDS_SingleDef: | 299 case MDS_SingleDef: |
290 assert(!Definitions.empty()); | 300 assert(FirstDefinition); |
291 return Definitions[0]; | 301 return FirstDefinition; |
292 } | 302 } |
293 } | 303 } |
294 | 304 |
295 void VariablesMetadata::init() { | 305 void VariablesMetadata::init(MetadataKind TrackingKind) { |
296 TimerMarker T(TimerStack::TT_vmetadata, Func); | 306 TimerMarker T(TimerStack::TT_vmetadata, Func); |
307 Kind = TrackingKind; | |
297 Metadata.clear(); | 308 Metadata.clear(); |
298 Metadata.resize(Func->getNumVariables()); | 309 Metadata.resize(Func->getNumVariables()); |
299 | 310 |
300 // Mark implicit args as being used in the entry node. | 311 // Mark implicit args as being used in the entry node. |
301 for (Variable *Var : Func->getImplicitArgs()) { | 312 for (Variable *Var : Func->getImplicitArgs()) { |
302 const Inst *NoInst = NULL; | 313 const Inst *NoInst = NULL; |
303 const CfgNode *EntryNode = Func->getEntryNode(); | 314 const CfgNode *EntryNode = Func->getEntryNode(); |
304 const bool IsFromDef = false; | 315 const bool IsFromDef = false; |
305 const bool IsImplicit = true; | 316 const bool IsImplicit = true; |
306 Metadata[Var->getIndex()].markUse(NoInst, EntryNode, IsFromDef, IsImplicit); | 317 Metadata[Var->getIndex()] |
318 .markUse(Kind, NoInst, EntryNode, IsFromDef, IsImplicit); | |
307 } | 319 } |
308 | 320 |
309 for (CfgNode *Node : Func->getNodes()) { | 321 for (CfgNode *Node : Func->getNodes()) { |
310 for (Inst *I : Node->getInsts()) { | 322 for (Inst *I : Node->getInsts()) { |
311 if (I->isDeleted()) | 323 if (I->isDeleted()) |
312 continue; | 324 continue; |
313 if (InstFakeKill *Kill = llvm::dyn_cast<InstFakeKill>(I)) { | 325 if (InstFakeKill *Kill = llvm::dyn_cast<InstFakeKill>(I)) { |
314 // A FakeKill instruction indicates certain Variables (usually | 326 // A FakeKill instruction indicates certain Variables (usually |
315 // physical scratch registers) are redefined, so we register | 327 // physical scratch registers) are redefined, so we register |
316 // them as defs. | 328 // them as defs. |
317 for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) { | 329 for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) { |
318 Variable *Var = llvm::cast<Variable>(I->getSrc(SrcNum)); | 330 Variable *Var = llvm::cast<Variable>(I->getSrc(SrcNum)); |
319 SizeT VarNum = Var->getIndex(); | 331 SizeT VarNum = Var->getIndex(); |
320 assert(VarNum < Metadata.size()); | 332 assert(VarNum < Metadata.size()); |
321 Metadata[VarNum].markDef(Kill, Node); | 333 Metadata[VarNum].markDef(Kind, Kill, Node); |
322 } | 334 } |
323 continue; // no point in executing the rest | 335 continue; // no point in executing the rest |
324 } | 336 } |
325 if (Variable *Dest = I->getDest()) { | 337 if (Variable *Dest = I->getDest()) { |
326 SizeT DestNum = Dest->getIndex(); | 338 SizeT DestNum = Dest->getIndex(); |
327 assert(DestNum < Metadata.size()); | 339 assert(DestNum < Metadata.size()); |
328 Metadata[DestNum].markDef(I, Node); | 340 Metadata[DestNum].markDef(Kind, I, Node); |
329 } | 341 } |
330 for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) { | 342 for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) { |
331 Operand *Src = I->getSrc(SrcNum); | 343 Operand *Src = I->getSrc(SrcNum); |
332 SizeT NumVars = Src->getNumVars(); | 344 SizeT NumVars = Src->getNumVars(); |
333 for (SizeT J = 0; J < NumVars; ++J) { | 345 for (SizeT J = 0; J < NumVars; ++J) { |
334 const Variable *Var = Src->getVar(J); | 346 const Variable *Var = Src->getVar(J); |
335 SizeT VarNum = Var->getIndex(); | 347 SizeT VarNum = Var->getIndex(); |
336 assert(VarNum < Metadata.size()); | 348 assert(VarNum < Metadata.size()); |
337 const bool IsFromDef = false; | 349 const bool IsFromDef = false; |
338 const bool IsImplicit = false; | 350 const bool IsImplicit = false; |
339 Metadata[VarNum].markUse(I, Node, IsFromDef, IsImplicit); | 351 Metadata[VarNum].markUse(Kind, I, Node, IsFromDef, IsImplicit); |
340 } | 352 } |
341 } | 353 } |
342 } | 354 } |
343 } | 355 } |
344 } | 356 } |
345 | 357 |
346 bool VariablesMetadata::isMultiDef(const Variable *Var) const { | 358 bool VariablesMetadata::isMultiDef(const Variable *Var) const { |
359 assert(Kind != VMK_Uses); | |
347 if (Var->getIsArg()) | 360 if (Var->getIsArg()) |
348 return false; | 361 return false; |
349 if (!isTracked(Var)) | 362 if (!isTracked(Var)) |
350 return true; // conservative answer | 363 return true; // conservative answer |
351 SizeT VarNum = Var->getIndex(); | 364 SizeT VarNum = Var->getIndex(); |
352 // Conservatively return true if the state is unknown. | 365 // Conservatively return true if the state is unknown. |
353 return Metadata[VarNum].getMultiDef() != VariableTracking::MDS_SingleDef; | 366 return Metadata[VarNum].getMultiDef() != VariableTracking::MDS_SingleDef; |
354 } | 367 } |
355 | 368 |
356 bool VariablesMetadata::isMultiBlock(const Variable *Var) const { | 369 bool VariablesMetadata::isMultiBlock(const Variable *Var) const { |
357 if (Var->getIsArg()) | 370 if (Var->getIsArg()) |
358 return true; | 371 return true; |
359 if (!isTracked(Var)) | 372 if (!isTracked(Var)) |
360 return true; // conservative answer | 373 return true; // conservative answer |
361 SizeT VarNum = Var->getIndex(); | 374 SizeT VarNum = Var->getIndex(); |
362 // Conservatively return true if the state is unknown. | 375 // Conservatively return true if the state is unknown. |
363 return Metadata[VarNum].getMultiBlock() != VariableTracking::MBS_SingleBlock; | 376 return Metadata[VarNum].getMultiBlock() != VariableTracking::MBS_SingleBlock; |
364 } | 377 } |
365 | 378 |
366 const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const { | 379 const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const { |
380 assert(Kind == VMK_All); | |
367 if (!isTracked(Var)) | 381 if (!isTracked(Var)) |
368 return NULL; // conservative answer | 382 return NULL; // conservative answer |
369 SizeT VarNum = Var->getIndex(); | 383 SizeT VarNum = Var->getIndex(); |
370 return Metadata[VarNum].getFirstDefinition(); | 384 return Metadata[VarNum].getFirstDefinition(); |
371 } | 385 } |
372 | 386 |
373 const Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const { | 387 const Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const { |
388 assert(Kind != VMK_Uses); | |
374 if (!isTracked(Var)) | 389 if (!isTracked(Var)) |
375 return NULL; // conservative answer | 390 return NULL; // conservative answer |
376 SizeT VarNum = Var->getIndex(); | 391 SizeT VarNum = Var->getIndex(); |
377 return Metadata[VarNum].getSingleDefinition(); | 392 return Metadata[VarNum].getSingleDefinition(); |
378 } | 393 } |
379 | 394 |
380 const InstDefList & | 395 const InstDefList & |
381 VariablesMetadata::getDefinitions(const Variable *Var) const { | 396 VariablesMetadata::getDefinitions(const Variable *Var) const { |
397 assert(Kind == VMK_All); | |
382 if (!isTracked(Var)) | 398 if (!isTracked(Var)) |
383 return NoDefinitions; | 399 return NoDefinitions; |
384 SizeT VarNum = Var->getIndex(); | 400 SizeT VarNum = Var->getIndex(); |
385 return Metadata[VarNum].getDefinitions(); | 401 return Metadata[VarNum].getDefinitions(); |
386 } | 402 } |
387 | 403 |
388 const CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const { | 404 const CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const { |
389 if (!isTracked(Var)) | 405 if (!isTracked(Var)) |
390 return NULL; // conservative answer | 406 return NULL; // conservative answer |
391 SizeT VarNum = Var->getIndex(); | 407 SizeT VarNum = Var->getIndex(); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
464 | 480 |
465 Ostream &operator<<(Ostream &Str, const RegWeight &W) { | 481 Ostream &operator<<(Ostream &Str, const RegWeight &W) { |
466 if (W.getWeight() == RegWeight::Inf) | 482 if (W.getWeight() == RegWeight::Inf) |
467 Str << "Inf"; | 483 Str << "Inf"; |
468 else | 484 else |
469 Str << W.getWeight(); | 485 Str << W.getWeight(); |
470 return Str; | 486 return Str; |
471 } | 487 } |
472 | 488 |
473 } // end of namespace Ice | 489 } // end of namespace Ice |
OLD | NEW |