Subzero: Don't store std::string objects inside Variable.
Instead, extend 668a7a333d6ddc3102b5b7c7c07448f6d259113c to include both CfgNode and Variable, keeping a pool of strings in the Cfg.
BUG= none
R=jvoung@chromium.org
Review URL: https://codereview.chromium.org/798693003
diff --git a/src/IceCfg.h b/src/IceCfg.h
index c313a89..1768761 100644
--- a/src/IceCfg.h
+++ b/src/IceCfg.h
@@ -62,14 +62,24 @@
CfgNode *makeNode();
SizeT getNumNodes() const { return Nodes.size(); }
const NodeList &getNodes() const { return Nodes; }
+
+ typedef int32_t IdentifierIndexType;
// Adds a name to the list and returns its index, suitable for the
- // argument to getNodeName(). No checking for duplicates is done.
- int32_t addNodeName(const IceString &Name) {
- int32_t Index = NodeNames.size();
- NodeNames.push_back(Name);
+ // argument to getIdentifierName(). No checking for duplicates is
+ // done. This is generally used for node names and variable names
+ // to avoid embedding a std::string inside an arena-allocated
+ // object.
+ IdentifierIndexType addIdentifierName(const IceString &Name) {
+ IdentifierIndexType Index = IdentifierNames.size();
+ IdentifierNames.push_back(Name);
return Index;
}
- const IceString &getNodeName(int32_t Index) const { return NodeNames[Index]; }
+ const IceString &getIdentifierName(IdentifierIndexType Index) const {
+ return IdentifierNames[Index];
+ }
+ enum {
+ IdentifierIndexInvalid = -1
+ };
// Manage instruction numbering.
InstNumberT newInstNumber() { return NextInstNumber++; }
@@ -78,10 +88,9 @@
// Manage Variables.
// Create a new Variable with a particular type and an optional
// name. The Node argument is the node where the variable is defined.
- template <typename T = Variable>
- T *makeVariable(Type Ty, const IceString &Name = "") {
+ template <typename T = Variable> T *makeVariable(Type Ty) {
SizeT Index = Variables.size();
- T *Var = T::create(this, Ty, Index, Name);
+ T *Var = T::create(this, Ty, Index);
Variables.push_back(Var);
return Var;
}
@@ -183,7 +192,7 @@
IceString ErrorMessage;
CfgNode *Entry; // entry basic block
NodeList Nodes; // linearized node list; Entry should be first
- std::vector<IceString> NodeNames;
+ std::vector<IceString> IdentifierNames;
InstNumberT NextInstNumber;
VarList Variables;
VarList Args; // subset of Variables, in argument order
diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp
index aa8ba7a..1623731 100644
--- a/src/IceCfgNode.cpp
+++ b/src/IceCfgNode.cpp
@@ -23,14 +23,14 @@
namespace Ice {
CfgNode::CfgNode(Cfg *Func, SizeT LabelNumber)
- : Func(Func), Number(LabelNumber), NameIndex(-1), HasReturn(false),
- NeedsPlacement(false), InstCountEstimate(0) {}
+ : Func(Func), Number(LabelNumber), NameIndex(Cfg::IdentifierIndexInvalid),
+ HasReturn(false), NeedsPlacement(false), InstCountEstimate(0) {}
// Returns the name the node was created with. If no name was given,
// it synthesizes a (hopefully) unique name.
IceString CfgNode::getName() const {
if (NameIndex >= 0)
- return Func->getNodeName(NameIndex);
+ return Func->getIdentifierName(NameIndex);
return "__" + std::to_string(getIndex());
}
@@ -437,8 +437,9 @@
Operand *OtherSrc = Desc[J].Src;
if (Desc[J].NumPred && sameVarOrReg(Dest, OtherSrc)) {
SizeT VarNum = Func->getNumVariables();
- Variable *Tmp = Func->makeVariable(
- OtherSrc->getType(), "__split_" + std::to_string(VarNum));
+ Variable *Tmp = Func->makeVariable(OtherSrc->getType());
+ if (ALLOW_DUMP)
+ Tmp->setName(Func, "__split_" + std::to_string(VarNum));
Assignments.push_back(InstAssign::create(Func, Tmp, OtherSrc));
Desc[J].Src = Tmp;
Found = true;
@@ -970,7 +971,7 @@
for (SizeT i = 0; i < LiveIn.size(); ++i) {
if (LiveIn[i]) {
Variable *Var = Liveness->getVariable(i, this);
- Str << " %" << Var->getName();
+ Str << " %" << Var->getName(Func);
if (Func->getContext()->isVerbose(IceV_RegOrigins) && Var->hasReg()) {
Str << ":" << Func->getTarget()->getRegName(Var->getRegNum(),
Var->getType());
@@ -995,7 +996,7 @@
for (SizeT i = 0; i < LiveOut.size(); ++i) {
if (LiveOut[i]) {
Variable *Var = Liveness->getVariable(i, this);
- Str << " %" << Var->getName();
+ Str << " %" << Var->getName(Func);
if (Func->getContext()->isVerbose(IceV_RegOrigins) && Var->hasReg()) {
Str << ":" << Func->getTarget()->getRegName(Var->getRegNum(),
Var->getType());
diff --git a/src/IceCfgNode.h b/src/IceCfgNode.h
index d60b0f0..0d6e911 100644
--- a/src/IceCfgNode.h
+++ b/src/IceCfgNode.h
@@ -35,9 +35,9 @@
IceString getName() const;
void setName(const IceString &NewName) {
// Make sure that the name can only be set once.
- assert(NameIndex < 0);
+ assert(NameIndex == Cfg::IdentifierIndexInvalid);
if (!NewName.empty())
- NameIndex = Func->addNodeName(NewName);
+ NameIndex = Func->addIdentifierName(NewName);
}
IceString getAsmName() const {
return ".L" + Func->getFunctionName() + "$" + getName();
@@ -91,7 +91,7 @@
CfgNode(Cfg *Func, SizeT LabelIndex);
Cfg *const Func;
const SizeT Number; // label index
- int32_t NameIndex; // index into Cfg::NodeNames table
+ Cfg::IdentifierIndexType NameIndex; // index into Cfg::NodeNames table
bool HasReturn; // does this block need an epilog?
bool NeedsPlacement;
InstNumberT InstCountEstimate; // rough instruction count estimate
diff --git a/src/IceConverter.cpp b/src/IceConverter.cpp
index a8148f9..9e003ef 100644
--- a/src/IceConverter.cpp
+++ b/src/IceConverter.cpp
@@ -145,7 +145,9 @@
if (IceTy == Ice::IceType_void)
return nullptr;
if (VarMap.find(V) == VarMap.end()) {
- VarMap[V] = Func->makeVariable(IceTy, V->getName());
+ VarMap[V] = Func->makeVariable(IceTy);
+ if (ALLOW_DUMP)
+ VarMap[V]->setName(Func, V->getName());
}
return VarMap[V];
}
diff --git a/src/IceInst.cpp b/src/IceInst.cpp
index e1b5f43..3e1ecf7 100644
--- a/src/IceInst.cpp
+++ b/src/IceInst.cpp
@@ -361,8 +361,9 @@
Inst *InstPhi::lower(Cfg *Func) {
Variable *Dest = getDest();
assert(Dest);
- IceString PhiName = Dest->getName() + "_phi";
- Variable *NewSrc = Func->makeVariable(Dest->getType(), PhiName);
+ Variable *NewSrc = Func->makeVariable(Dest->getType());
+ if (ALLOW_DUMP)
+ NewSrc->setName(Func, Dest->getName(Func) + "_phi");
this->Dest = NewSrc;
return InstAssign::create(Func, Dest, NewSrc);
}
diff --git a/src/IceInstX8632.h b/src/IceInstX8632.h
index 5d10a54..cc44a1a 100644
--- a/src/IceInstX8632.h
+++ b/src/IceInstX8632.h
@@ -152,9 +152,8 @@
SpillVariable &operator=(const SpillVariable &) = delete;
public:
- static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index,
- const IceString &Name) {
- return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index, Name);
+ static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index) {
+ return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index);
}
const static OperandKind SpillVariableKind =
static_cast<OperandKind>(kVariable_Target);
@@ -165,8 +164,8 @@
Variable *getLinkedTo() const { return LinkedTo; }
// Inherit dump() and emit() from Variable.
private:
- SpillVariable(Type Ty, SizeT Index, const IceString &Name)
- : Variable(SpillVariableKind, Ty, Index, Name), LinkedTo(NULL) {}
+ SpillVariable(Type Ty, SizeT Index)
+ : Variable(SpillVariableKind, Ty, Index), LinkedTo(NULL) {}
Variable *LinkedTo;
};
diff --git a/src/IceOperand.cpp b/src/IceOperand.cpp
index 6357129..615c81c 100644
--- a/src/IceOperand.cpp
+++ b/src/IceOperand.cpp
@@ -131,16 +131,17 @@
++TrimmedBegin;
}
-IceString Variable::getName() const {
- if (!Name.empty())
- return Name;
+IceString Variable::getName(const Cfg *Func) const {
+ if (Func && NameIndex >= 0)
+ return Func->getIdentifierName(NameIndex);
return "__" + std::to_string(getIndex());
}
Variable Variable::asType(Type Ty) {
// Note: This returns a Variable, even if the "this" object is a
// subclass of Variable.
- Variable V(kVariable, Ty, Number, Name);
+ Variable V(kVariable, Ty, Number);
+ V.NameIndex = NameIndex;
V.RegNum = RegNum;
V.StackOffset = StackOffset;
return V;
@@ -405,12 +406,12 @@
if (!ALLOW_DUMP)
return;
if (Func == NULL) {
- Str << "%" << getName();
+ Str << "%" << getName(Func);
return;
}
if (Func->getContext()->isVerbose(IceV_RegOrigins) ||
(!hasReg() && !Func->getTarget()->hasComputedFrame()))
- Str << "%" << getName();
+ Str << "%" << getName(Func);
if (hasReg()) {
if (Func->getContext()->isVerbose(IceV_RegOrigins))
Str << ":";
diff --git a/src/IceOperand.h b/src/IceOperand.h
index 99bbd39..3b92dfb 100644
--- a/src/IceOperand.h
+++ b/src/IceOperand.h
@@ -388,18 +388,17 @@
Variable(Variable &&V) = default;
public:
- static Variable *create(Cfg *Func, Type Ty, SizeT Index,
- const IceString &Name) {
- return new (Func->allocate<Variable>())
- Variable(kVariable, Ty, Index, Name);
+ static Variable *create(Cfg *Func, Type Ty, SizeT Index) {
+ return new (Func->allocate<Variable>()) Variable(kVariable, Ty, Index);
}
SizeT getIndex() const { return Number; }
- IceString getName() const;
- void setName(IceString &NewName) {
+ IceString getName(const Cfg *Func) const;
+ void setName(Cfg *Func, const IceString &NewName) {
// Make sure that the name can only be set once.
- assert(Name.empty());
- Name = NewName;
+ assert(NameIndex == Cfg::IdentifierIndexInvalid);
+ if (!NewName.empty())
+ NameIndex = Func->addIdentifierName(NewName);
}
bool getIsArg() const { return IsArgument; }
@@ -484,11 +483,11 @@
~Variable() override {}
protected:
- Variable(OperandKind K, Type Ty, SizeT Index, const IceString &Name)
- : Operand(K, Ty), Number(Index), Name(Name), IsArgument(false),
- IsImplicitArgument(false), IgnoreLiveness(false), StackOffset(0),
- RegNum(NoRegister), RegNumTmp(NoRegister), Weight(1), LoVar(NULL),
- HiVar(NULL) {
+ Variable(OperandKind K, Type Ty, SizeT Index)
+ : Operand(K, Ty), Number(Index), NameIndex(Cfg::IdentifierIndexInvalid),
+ IsArgument(false), IsImplicitArgument(false), IgnoreLiveness(false),
+ StackOffset(0), RegNum(NoRegister), RegNumTmp(NoRegister), Weight(1),
+ LoVar(NULL), HiVar(NULL) {
Vars = VarsReal;
Vars[0] = this;
NumVars = 1;
@@ -496,8 +495,7 @@
// Number is unique across all variables, and is used as a
// (bit)vector index for liveness analysis.
const SizeT Number;
- // Name is optional.
- IceString Name;
+ Cfg::IdentifierIndexType NameIndex;
bool IsArgument;
bool IsImplicitArgument;
// IgnoreLiveness means that the variable should be ignored when
diff --git a/src/IceRegAlloc.cpp b/src/IceRegAlloc.cpp
index bd4ca05..2d5ff9b 100644
--- a/src/IceRegAlloc.cpp
+++ b/src/IceRegAlloc.cpp
@@ -436,8 +436,9 @@
}
}
if (Verbose && Prefer) {
- Str << "Initial Prefer=" << *Prefer << " R=" << PreferReg
- << " LIVE=" << Prefer->getLiveRange()
+ Str << "Initial Prefer=";
+ Prefer->dump(Func);
+ Str << " R=" << PreferReg << " LIVE=" << Prefer->getLiveRange()
<< " Overlap=" << AllowOverlap << "\n";
}
}
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 1288c20..d049cbd 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -555,8 +555,9 @@
// to the assigned location of Arg.
int32_t RegNum = RegX8632::Reg_xmm0 + NumXmmArgs;
++NumXmmArgs;
- IceString Name = "home_reg:" + Arg->getName();
- Variable *RegisterArg = Func->makeVariable(Ty, Name);
+ Variable *RegisterArg = Func->makeVariable(Ty);
+ if (ALLOW_DUMP)
+ RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func));
RegisterArg->setRegNum(RegNum);
RegisterArg->setIsArg();
Arg->setIsArg(false);
@@ -1050,8 +1051,12 @@
return;
}
assert(Hi == NULL);
- Lo = Func->makeVariable(IceType_i32, Var->getName() + "__lo");
- Hi = Func->makeVariable(IceType_i32, Var->getName() + "__hi");
+ Lo = Func->makeVariable(IceType_i32);
+ Hi = Func->makeVariable(IceType_i32);
+ if (ALLOW_DUMP) {
+ Lo->setName(Func, Var->getName(Func) + "__lo");
+ Hi->setName(Func, Var->getName(Func) + "__hi");
+ }
Var->setLoHi(Lo, Hi);
if (Var->getIsArg()) {
Lo->setIsArg();
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index 8f1f99d..639c062 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -1086,8 +1086,6 @@
return;
}
-class FunctionValuesymtabParser;
-
/// Parses function blocks in the bitcode file.
class FunctionParser : public BlockParserBaseClass {
FunctionParser(const FunctionParser &) = delete;
@@ -2663,8 +2661,10 @@
return;
Ice::Operand *Op = getFunctionParser()->getOperand(Index);
if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) {
- std::string Nm(Name.data(), Name.size());
- V->setName(Nm);
+ if (ALLOW_DUMP) {
+ std::string Nm(Name.data(), Name.size());
+ V->setName(getFunctionParser()->getFunc(), Nm);
+ }
} else {
reportUnableToAssign("variable", Index, Name);
}