Chromium Code Reviews| Index: src/IceOperand.cpp |
| diff --git a/src/IceOperand.cpp b/src/IceOperand.cpp |
| index e4aaf2475671163390b6b86e03d292df27e44091..ca310774205f30101a45c7fafdcf113a64b173f5 100644 |
| --- a/src/IceOperand.cpp |
| +++ b/src/IceOperand.cpp |
| @@ -13,6 +13,7 @@ |
| //===----------------------------------------------------------------------===// |
| #include "IceCfg.h" |
| +#include "IceCfgNode.h" |
| #include "IceInst.h" |
| #include "IceOperand.h" |
| #include "IceTargetLowering.h" // dumping stack/frame pointer register |
| @@ -138,48 +139,6 @@ bool LiveRange::containsValue(InstNumberT Value) const { |
| return false; |
| } |
| -void Variable::setUse(const Inst *Inst, const CfgNode *Node) { |
| - if (DefNode == NULL) |
| - return; |
| - if (llvm::isa<InstPhi>(Inst) || Node != DefNode) |
| - DefNode = NULL; |
| -} |
| - |
| -void Variable::setDefinition(Inst *Inst, const CfgNode *Node) { |
| - if (DefInst && !DefInst->isDeleted() && DefInst != Inst) { |
| - // Detect when a variable is being defined multiple times, |
| - // particularly for Phi instruction lowering. If this happens, we |
| - // need to lock DefInst to NULL. |
| - DefInst = NULL; |
| - DefNode = NULL; |
| - return; |
| - } |
| - if (DefNode == NULL) |
| - return; |
| - DefInst = Inst; |
| - if (Node != DefNode) |
| - DefNode = NULL; |
| -} |
| - |
| -void Variable::replaceDefinition(Inst *Inst, const CfgNode *Node) { |
| - DefInst = NULL; |
| - setDefinition(Inst, Node); |
| -} |
| - |
| -void Variable::setIsArg(Cfg *Func, bool IsArg) { |
| - if (IsArg) { |
| - IsArgument = true; |
| - if (DefNode == NULL) |
| - return; |
| - CfgNode *Entry = Func->getEntryNode(); |
| - if (DefNode == Entry) |
| - return; |
| - DefNode = NULL; |
| - } else { |
| - IsArgument = false; |
| - } |
| -} |
| - |
| IceString Variable::getName() const { |
| if (!Name.empty()) |
| return Name; |
| @@ -191,16 +150,90 @@ IceString Variable::getName() const { |
| Variable Variable::asType(Type Ty) { |
| // Note: This returns a Variable, even if the "this" object is a |
| // subclass of Variable. |
| - Variable V(kVariable, Ty, DefNode, Number, Name); |
| + Variable V(kVariable, Ty, Number, Name); |
| V.RegNum = RegNum; |
| V.StackOffset = StackOffset; |
| return V; |
| } |
| +void VariablesMetadata::init() { |
| + Metadata.clear(); |
| + Metadata.resize(Func->getNumVariables()); |
| + // Mark args as being used in the entry node. |
| + const CfgNode *Entry = Func->getEntryNode(); |
| + Entry = NULL; |
| + for (SizeT i = 0; i < Func->getNumVariables(); ++i) { |
| + const Variable *Var = Func->getVariables()[i]; |
| + if (Var->getIsArg()) { |
|
jvoung (off chromium)
2014/09/22 17:07:29
Why not use the Func->getArgs() list, which will h
Jim Stichnoth
2014/09/22 21:00:46
The only problem with using Func->getArgs() is the
|
| + const Inst *NoInst = NULL; |
| + const bool IsFromDef = false; |
| + Metadata[Var->getIndex()].markUse(NoInst, Entry, IsFromDef); |
| + } |
| + } |
| + SizeT NumNodes = Func->getNumNodes(); |
| + for (SizeT N = 0; N < NumNodes; ++N) { |
| + CfgNode *Node = Func->getNodes()[N]; |
| + const InstList &Insts = Node->getInsts(); |
| + for (InstList::const_iterator I = Insts.begin(), E = Insts.end(); I != E; |
| + ++I) { |
| + if ((*I)->isDeleted()) |
| + continue; |
| + if (Variable *Dest = (*I)->getDest()) { |
| + SizeT DestNum = Dest->getIndex(); |
| + assert(DestNum < Metadata.size()); |
| + Metadata[DestNum].markDef(*I, Node); |
| + } |
| + for (SizeT SrcNum = 0; SrcNum < (*I)->getSrcSize(); ++SrcNum) { |
| + Operand *Src = (*I)->getSrc(SrcNum); |
| + SizeT NumVars = Src->getNumVars(); |
| + for (SizeT J = 0; J < NumVars; ++J) { |
| + const Variable *Var = Src->getVar(J); |
| + SizeT VarNum = Var->getIndex(); |
| + assert(VarNum < Metadata.size()); |
| + const bool IsFromDef = false; |
| + Metadata[VarNum].markUse(*I, Node, IsFromDef); |
| + } |
| + } |
| + } |
| + } |
| +} |
| + |
| +bool VariablesMetadata::isMultiDef(const Variable *Var) const { |
| + if (Var->getIsArg()) |
| + return false; |
| + if (!isTracked(Var)) |
| + return true; // conservative answer |
| + SizeT VarNum = Var->getIndex(); |
| + // Conservatively return true if the state is unknown. |
| + return Metadata[VarNum].getMultiDef() != VariableTracking::MDS_SingleDef; |
| +} |
| + |
| +bool VariablesMetadata::isMultiBlock(const Variable *Var) const { |
| + if (getDefinition(Var) == NULL) |
| + return true; |
| + SizeT VarNum = Var->getIndex(); |
| + // Conservatively return true if the state is unknown. |
| + return Metadata[VarNum].getMultiBlock() != VariableTracking::MBS_SingleBlock; |
| +} |
| + |
| +const Inst *VariablesMetadata::getDefinition(const Variable *Var) const { |
| + if (!isTracked(Var)) |
| + return NULL; // conservative answer |
| + SizeT VarNum = Var->getIndex(); |
| + return Metadata[VarNum].getDefinition(); |
| +} |
| + |
| +const CfgNode *VariablesMetadata::getLocalUseNode(const Variable *Var) const { |
| + if (!isTracked(Var)) |
| + return NULL; // conservative answer |
| + SizeT VarNum = Var->getIndex(); |
| + return Metadata[VarNum].getNode(); |
| +} |
| + |
| // ======================== dump routines ======================== // |
| void Variable::emit(const Cfg *Func) const { |
| - Func->getTarget()->emitVariable(this, Func); |
| + Func->getTarget()->emitVariable(this); |
| } |
| void Variable::dump(const Cfg *Func, Ostream &Str) const { |
| @@ -208,9 +241,6 @@ void Variable::dump(const Cfg *Func, Ostream &Str) const { |
| Str << "%" << getName(); |
| return; |
| } |
| - const CfgNode *CurrentNode = Func->getCurrentNode(); |
| - (void)CurrentNode; // used only in assert() |
| - assert(CurrentNode == NULL || DefNode == NULL || DefNode == CurrentNode); |
| if (Func->getContext()->isVerbose(IceV_RegOrigins) || |
| (!hasReg() && !Func->getTarget()->hasComputedFrame())) |
| Str << "%" << getName(); |