Index: src/IceOperand.cpp |
diff --git a/src/IceOperand.cpp b/src/IceOperand.cpp |
index 3f7d0bff8d05027e7607a4e4817a167dbd3b1159..3285e6d78a06b97614d71769ce5d3fdd21c992ec 100644 |
--- a/src/IceOperand.cpp |
+++ b/src/IceOperand.cpp |
@@ -185,8 +185,10 @@ Variable Variable::asType(Type Ty) { |
return V; |
} |
-void VariableTracking::markUse(const Inst *Instr, const CfgNode *Node, |
- bool IsFromDef, bool IsImplicit) { |
+void VariableTracking::markUse(MetadataKind TrackingKind, const Inst *Instr, |
+ const CfgNode *Node, bool IsFromDef, |
+ bool IsImplicit) { |
+ (void)TrackingKind; |
if (MultiBlock == MBS_MultiBlock) |
return; |
// TODO(stichnot): If the use occurs as a source operand in the |
@@ -227,19 +229,31 @@ void VariableTracking::markUse(const Inst *Instr, const CfgNode *Node, |
} |
} |
-void VariableTracking::markDef(const Inst *Instr, const CfgNode *Node) { |
+void VariableTracking::markDef(MetadataKind TrackingKind, const Inst *Instr, |
+ const CfgNode *Node) { |
// TODO(stichnot): If the definition occurs in the last instruction |
// of the block, consider not marking this as a separate use. But |
// be careful not to omit all uses of the variable if markDef() and |
// markUse() both use this optimization. |
assert(Node); |
// Verify that instructions are added in increasing order. |
- assert(Definitions.empty() || |
- Instr->getNumber() >= Definitions.back()->getNumber()); |
- Definitions.push_back(Instr); |
+#ifndef NDEBUG |
+ if (TrackingKind == VMK_All) { |
+ const Inst *LastInstruction = |
+ Definitions.empty() ? FirstOrSingleDefinition : Definitions.back(); |
+ assert(LastInstruction == NULL || |
+ Instr->getNumber() >= LastInstruction->getNumber()); |
+ } |
+#endif |
const bool IsFromDef = true; |
const bool IsImplicit = false; |
- markUse(Instr, Node, IsFromDef, IsImplicit); |
+ markUse(TrackingKind, Instr, Node, IsFromDef, IsImplicit); |
+ if (TrackingKind == VMK_Uses) |
+ return; |
+ if (FirstOrSingleDefinition == NULL) |
+ FirstOrSingleDefinition = Instr; |
+ else if (TrackingKind == VMK_All) |
+ Definitions.push_back(Instr); |
switch (MultiDef) { |
case MDS_Unknown: |
assert(SingleDefNode == NULL); |
@@ -275,8 +289,8 @@ const Inst *VariableTracking::getFirstDefinition() const { |
return NULL; |
case MDS_SingleDef: |
case MDS_MultiDefSingleBlock: |
- assert(!Definitions.empty()); |
- return Definitions[0]; |
+ assert(FirstOrSingleDefinition); |
+ return FirstOrSingleDefinition; |
} |
} |
@@ -287,13 +301,14 @@ const Inst *VariableTracking::getSingleDefinition() const { |
case MDS_MultiDefSingleBlock: |
return NULL; |
case MDS_SingleDef: |
- assert(!Definitions.empty()); |
- return Definitions[0]; |
+ assert(FirstOrSingleDefinition); |
+ return FirstOrSingleDefinition; |
} |
} |
-void VariablesMetadata::init() { |
+void VariablesMetadata::init(MetadataKind TrackingKind) { |
TimerMarker T(TimerStack::TT_vmetadata, Func); |
+ Kind = TrackingKind; |
Metadata.clear(); |
Metadata.resize(Func->getNumVariables()); |
@@ -303,7 +318,8 @@ void VariablesMetadata::init() { |
const CfgNode *EntryNode = Func->getEntryNode(); |
const bool IsFromDef = false; |
const bool IsImplicit = true; |
- Metadata[Var->getIndex()].markUse(NoInst, EntryNode, IsFromDef, IsImplicit); |
+ Metadata[Var->getIndex()] |
+ .markUse(Kind, NoInst, EntryNode, IsFromDef, IsImplicit); |
} |
for (CfgNode *Node : Func->getNodes()) { |
@@ -318,14 +334,14 @@ void VariablesMetadata::init() { |
Variable *Var = llvm::cast<Variable>(I->getSrc(SrcNum)); |
SizeT VarNum = Var->getIndex(); |
assert(VarNum < Metadata.size()); |
- Metadata[VarNum].markDef(Kill, Node); |
+ Metadata[VarNum].markDef(Kind, Kill, Node); |
} |
continue; // no point in executing the rest |
} |
if (Variable *Dest = I->getDest()) { |
SizeT DestNum = Dest->getIndex(); |
assert(DestNum < Metadata.size()); |
- Metadata[DestNum].markDef(I, Node); |
+ Metadata[DestNum].markDef(Kind, I, Node); |
} |
for (SizeT SrcNum = 0; SrcNum < I->getSrcSize(); ++SrcNum) { |
Operand *Src = I->getSrc(SrcNum); |
@@ -336,7 +352,7 @@ void VariablesMetadata::init() { |
assert(VarNum < Metadata.size()); |
const bool IsFromDef = false; |
const bool IsImplicit = false; |
- Metadata[VarNum].markUse(I, Node, IsFromDef, IsImplicit); |
+ Metadata[VarNum].markUse(Kind, I, Node, IsFromDef, IsImplicit); |
} |
} |
} |
@@ -344,6 +360,7 @@ void VariablesMetadata::init() { |
} |
bool VariablesMetadata::isMultiDef(const Variable *Var) const { |
+ assert(Kind != VMK_Uses); |
if (Var->getIsArg()) |
return false; |
if (!isTracked(Var)) |
@@ -364,6 +381,7 @@ bool VariablesMetadata::isMultiBlock(const Variable *Var) const { |
} |
const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const { |
+ assert(Kind != VMK_Uses); |
if (!isTracked(Var)) |
return NULL; // conservative answer |
SizeT VarNum = Var->getIndex(); |
@@ -371,6 +389,7 @@ const Inst *VariablesMetadata::getFirstDefinition(const Variable *Var) const { |
} |
const Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const { |
+ assert(Kind != VMK_Uses); |
if (!isTracked(Var)) |
return NULL; // conservative answer |
SizeT VarNum = Var->getIndex(); |
@@ -378,11 +397,12 @@ const Inst *VariablesMetadata::getSingleDefinition(const Variable *Var) const { |
} |
const InstDefList & |
-VariablesMetadata::getDefinitions(const Variable *Var) const { |
+VariablesMetadata::getLatterDefinitions(const Variable *Var) const { |
+ assert(Kind == VMK_All); |
if (!isTracked(Var)) |
return NoDefinitions; |
SizeT VarNum = Var->getIndex(); |
- return Metadata[VarNum].getDefinitions(); |
+ return Metadata[VarNum].getLatterDefinitions(); |
} |
const CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const { |