Commit 9a04c076 by Jim Stichnoth

Subzero: Don't store std::string objects inside Variable.

Instead, extend 668a7a33 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
parent 639c9217
...@@ -62,14 +62,24 @@ public: ...@@ -62,14 +62,24 @@ public:
CfgNode *makeNode(); CfgNode *makeNode();
SizeT getNumNodes() const { return Nodes.size(); } SizeT getNumNodes() const { return Nodes.size(); }
const NodeList &getNodes() const { return Nodes; } const NodeList &getNodes() const { return Nodes; }
typedef int32_t IdentifierIndexType;
// Adds a name to the list and returns its index, suitable for the // Adds a name to the list and returns its index, suitable for the
// argument to getNodeName(). No checking for duplicates is done. // argument to getIdentifierName(). No checking for duplicates is
int32_t addNodeName(const IceString &Name) { // done. This is generally used for node names and variable names
int32_t Index = NodeNames.size(); // to avoid embedding a std::string inside an arena-allocated
NodeNames.push_back(Name); // object.
IdentifierIndexType addIdentifierName(const IceString &Name) {
IdentifierIndexType Index = IdentifierNames.size();
IdentifierNames.push_back(Name);
return Index; 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. // Manage instruction numbering.
InstNumberT newInstNumber() { return NextInstNumber++; } InstNumberT newInstNumber() { return NextInstNumber++; }
...@@ -78,10 +88,9 @@ public: ...@@ -78,10 +88,9 @@ public:
// Manage Variables. // Manage Variables.
// Create a new Variable with a particular type and an optional // Create a new Variable with a particular type and an optional
// name. The Node argument is the node where the variable is defined. // name. The Node argument is the node where the variable is defined.
template <typename T = Variable> template <typename T = Variable> T *makeVariable(Type Ty) {
T *makeVariable(Type Ty, const IceString &Name = "") {
SizeT Index = Variables.size(); SizeT Index = Variables.size();
T *Var = T::create(this, Ty, Index, Name); T *Var = T::create(this, Ty, Index);
Variables.push_back(Var); Variables.push_back(Var);
return Var; return Var;
} }
...@@ -183,7 +192,7 @@ private: ...@@ -183,7 +192,7 @@ private:
IceString ErrorMessage; IceString ErrorMessage;
CfgNode *Entry; // entry basic block CfgNode *Entry; // entry basic block
NodeList Nodes; // linearized node list; Entry should be first NodeList Nodes; // linearized node list; Entry should be first
std::vector<IceString> NodeNames; std::vector<IceString> IdentifierNames;
InstNumberT NextInstNumber; InstNumberT NextInstNumber;
VarList Variables; VarList Variables;
VarList Args; // subset of Variables, in argument order VarList Args; // subset of Variables, in argument order
......
...@@ -23,14 +23,14 @@ ...@@ -23,14 +23,14 @@
namespace Ice { namespace Ice {
CfgNode::CfgNode(Cfg *Func, SizeT LabelNumber) CfgNode::CfgNode(Cfg *Func, SizeT LabelNumber)
: Func(Func), Number(LabelNumber), NameIndex(-1), HasReturn(false), : Func(Func), Number(LabelNumber), NameIndex(Cfg::IdentifierIndexInvalid),
NeedsPlacement(false), InstCountEstimate(0) {} HasReturn(false), NeedsPlacement(false), InstCountEstimate(0) {}
// Returns the name the node was created with. If no name was given, // Returns the name the node was created with. If no name was given,
// it synthesizes a (hopefully) unique name. // it synthesizes a (hopefully) unique name.
IceString CfgNode::getName() const { IceString CfgNode::getName() const {
if (NameIndex >= 0) if (NameIndex >= 0)
return Func->getNodeName(NameIndex); return Func->getIdentifierName(NameIndex);
return "__" + std::to_string(getIndex()); return "__" + std::to_string(getIndex());
} }
...@@ -437,8 +437,9 @@ void CfgNode::advancedPhiLowering() { ...@@ -437,8 +437,9 @@ void CfgNode::advancedPhiLowering() {
Operand *OtherSrc = Desc[J].Src; Operand *OtherSrc = Desc[J].Src;
if (Desc[J].NumPred && sameVarOrReg(Dest, OtherSrc)) { if (Desc[J].NumPred && sameVarOrReg(Dest, OtherSrc)) {
SizeT VarNum = Func->getNumVariables(); SizeT VarNum = Func->getNumVariables();
Variable *Tmp = Func->makeVariable( Variable *Tmp = Func->makeVariable(OtherSrc->getType());
OtherSrc->getType(), "__split_" + std::to_string(VarNum)); if (ALLOW_DUMP)
Tmp->setName(Func, "__split_" + std::to_string(VarNum));
Assignments.push_back(InstAssign::create(Func, Tmp, OtherSrc)); Assignments.push_back(InstAssign::create(Func, Tmp, OtherSrc));
Desc[J].Src = Tmp; Desc[J].Src = Tmp;
Found = true; Found = true;
...@@ -970,7 +971,7 @@ void CfgNode::dump(Cfg *Func) const { ...@@ -970,7 +971,7 @@ void CfgNode::dump(Cfg *Func) const {
for (SizeT i = 0; i < LiveIn.size(); ++i) { for (SizeT i = 0; i < LiveIn.size(); ++i) {
if (LiveIn[i]) { if (LiveIn[i]) {
Variable *Var = Liveness->getVariable(i, this); Variable *Var = Liveness->getVariable(i, this);
Str << " %" << Var->getName(); Str << " %" << Var->getName(Func);
if (Func->getContext()->isVerbose(IceV_RegOrigins) && Var->hasReg()) { if (Func->getContext()->isVerbose(IceV_RegOrigins) && Var->hasReg()) {
Str << ":" << Func->getTarget()->getRegName(Var->getRegNum(), Str << ":" << Func->getTarget()->getRegName(Var->getRegNum(),
Var->getType()); Var->getType());
...@@ -995,7 +996,7 @@ void CfgNode::dump(Cfg *Func) const { ...@@ -995,7 +996,7 @@ void CfgNode::dump(Cfg *Func) const {
for (SizeT i = 0; i < LiveOut.size(); ++i) { for (SizeT i = 0; i < LiveOut.size(); ++i) {
if (LiveOut[i]) { if (LiveOut[i]) {
Variable *Var = Liveness->getVariable(i, this); Variable *Var = Liveness->getVariable(i, this);
Str << " %" << Var->getName(); Str << " %" << Var->getName(Func);
if (Func->getContext()->isVerbose(IceV_RegOrigins) && Var->hasReg()) { if (Func->getContext()->isVerbose(IceV_RegOrigins) && Var->hasReg()) {
Str << ":" << Func->getTarget()->getRegName(Var->getRegNum(), Str << ":" << Func->getTarget()->getRegName(Var->getRegNum(),
Var->getType()); Var->getType());
......
...@@ -35,9 +35,9 @@ public: ...@@ -35,9 +35,9 @@ public:
IceString getName() const; IceString getName() const;
void setName(const IceString &NewName) { void setName(const IceString &NewName) {
// Make sure that the name can only be set once. // Make sure that the name can only be set once.
assert(NameIndex < 0); assert(NameIndex == Cfg::IdentifierIndexInvalid);
if (!NewName.empty()) if (!NewName.empty())
NameIndex = Func->addNodeName(NewName); NameIndex = Func->addIdentifierName(NewName);
} }
IceString getAsmName() const { IceString getAsmName() const {
return ".L" + Func->getFunctionName() + "$" + getName(); return ".L" + Func->getFunctionName() + "$" + getName();
...@@ -91,7 +91,7 @@ private: ...@@ -91,7 +91,7 @@ private:
CfgNode(Cfg *Func, SizeT LabelIndex); CfgNode(Cfg *Func, SizeT LabelIndex);
Cfg *const Func; Cfg *const Func;
const SizeT Number; // label index 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 HasReturn; // does this block need an epilog?
bool NeedsPlacement; bool NeedsPlacement;
InstNumberT InstCountEstimate; // rough instruction count estimate InstNumberT InstCountEstimate; // rough instruction count estimate
......
...@@ -145,7 +145,9 @@ private: ...@@ -145,7 +145,9 @@ private:
if (IceTy == Ice::IceType_void) if (IceTy == Ice::IceType_void)
return nullptr; return nullptr;
if (VarMap.find(V) == VarMap.end()) { 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]; return VarMap[V];
} }
......
...@@ -361,8 +361,9 @@ void InstPhi::livenessPhiOperand(LivenessBV &Live, CfgNode *Target, ...@@ -361,8 +361,9 @@ void InstPhi::livenessPhiOperand(LivenessBV &Live, CfgNode *Target,
Inst *InstPhi::lower(Cfg *Func) { Inst *InstPhi::lower(Cfg *Func) {
Variable *Dest = getDest(); Variable *Dest = getDest();
assert(Dest); assert(Dest);
IceString PhiName = Dest->getName() + "_phi"; Variable *NewSrc = Func->makeVariable(Dest->getType());
Variable *NewSrc = Func->makeVariable(Dest->getType(), PhiName); if (ALLOW_DUMP)
NewSrc->setName(Func, Dest->getName(Func) + "_phi");
this->Dest = NewSrc; this->Dest = NewSrc;
return InstAssign::create(Func, Dest, NewSrc); return InstAssign::create(Func, Dest, NewSrc);
} }
......
...@@ -152,9 +152,8 @@ class SpillVariable : public Variable { ...@@ -152,9 +152,8 @@ class SpillVariable : public Variable {
SpillVariable &operator=(const SpillVariable &) = delete; SpillVariable &operator=(const SpillVariable &) = delete;
public: public:
static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index, static SpillVariable *create(Cfg *Func, Type Ty, SizeT Index) {
const IceString &Name) { return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index);
return new (Func->allocate<SpillVariable>()) SpillVariable(Ty, Index, Name);
} }
const static OperandKind SpillVariableKind = const static OperandKind SpillVariableKind =
static_cast<OperandKind>(kVariable_Target); static_cast<OperandKind>(kVariable_Target);
...@@ -165,8 +164,8 @@ public: ...@@ -165,8 +164,8 @@ public:
Variable *getLinkedTo() const { return LinkedTo; } Variable *getLinkedTo() const { return LinkedTo; }
// Inherit dump() and emit() from Variable. // Inherit dump() and emit() from Variable.
private: private:
SpillVariable(Type Ty, SizeT Index, const IceString &Name) SpillVariable(Type Ty, SizeT Index)
: Variable(SpillVariableKind, Ty, Index, Name), LinkedTo(NULL) {} : Variable(SpillVariableKind, Ty, Index), LinkedTo(NULL) {}
Variable *LinkedTo; Variable *LinkedTo;
}; };
......
...@@ -131,16 +131,17 @@ void LiveRange::trim(InstNumberT Lower) { ...@@ -131,16 +131,17 @@ void LiveRange::trim(InstNumberT Lower) {
++TrimmedBegin; ++TrimmedBegin;
} }
IceString Variable::getName() const { IceString Variable::getName(const Cfg *Func) const {
if (!Name.empty()) if (Func && NameIndex >= 0)
return Name; return Func->getIdentifierName(NameIndex);
return "__" + std::to_string(getIndex()); return "__" + std::to_string(getIndex());
} }
Variable Variable::asType(Type Ty) { Variable Variable::asType(Type Ty) {
// Note: This returns a Variable, even if the "this" object is a // Note: This returns a Variable, even if the "this" object is a
// subclass of Variable. // subclass of Variable.
Variable V(kVariable, Ty, Number, Name); Variable V(kVariable, Ty, Number);
V.NameIndex = NameIndex;
V.RegNum = RegNum; V.RegNum = RegNum;
V.StackOffset = StackOffset; V.StackOffset = StackOffset;
return V; return V;
...@@ -405,12 +406,12 @@ void Variable::dump(const Cfg *Func, Ostream &Str) const { ...@@ -405,12 +406,12 @@ void Variable::dump(const Cfg *Func, Ostream &Str) const {
if (!ALLOW_DUMP) if (!ALLOW_DUMP)
return; return;
if (Func == NULL) { if (Func == NULL) {
Str << "%" << getName(); Str << "%" << getName(Func);
return; return;
} }
if (Func->getContext()->isVerbose(IceV_RegOrigins) || if (Func->getContext()->isVerbose(IceV_RegOrigins) ||
(!hasReg() && !Func->getTarget()->hasComputedFrame())) (!hasReg() && !Func->getTarget()->hasComputedFrame()))
Str << "%" << getName(); Str << "%" << getName(Func);
if (hasReg()) { if (hasReg()) {
if (Func->getContext()->isVerbose(IceV_RegOrigins)) if (Func->getContext()->isVerbose(IceV_RegOrigins))
Str << ":"; Str << ":";
......
...@@ -388,18 +388,17 @@ class Variable : public Operand { ...@@ -388,18 +388,17 @@ class Variable : public Operand {
Variable(Variable &&V) = default; Variable(Variable &&V) = default;
public: public:
static Variable *create(Cfg *Func, Type Ty, SizeT Index, static Variable *create(Cfg *Func, Type Ty, SizeT Index) {
const IceString &Name) { return new (Func->allocate<Variable>()) Variable(kVariable, Ty, Index);
return new (Func->allocate<Variable>())
Variable(kVariable, Ty, Index, Name);
} }
SizeT getIndex() const { return Number; } SizeT getIndex() const { return Number; }
IceString getName() const; IceString getName(const Cfg *Func) const;
void setName(IceString &NewName) { void setName(Cfg *Func, const IceString &NewName) {
// Make sure that the name can only be set once. // Make sure that the name can only be set once.
assert(Name.empty()); assert(NameIndex == Cfg::IdentifierIndexInvalid);
Name = NewName; if (!NewName.empty())
NameIndex = Func->addIdentifierName(NewName);
} }
bool getIsArg() const { return IsArgument; } bool getIsArg() const { return IsArgument; }
...@@ -484,11 +483,11 @@ public: ...@@ -484,11 +483,11 @@ public:
~Variable() override {} ~Variable() override {}
protected: protected:
Variable(OperandKind K, Type Ty, SizeT Index, const IceString &Name) Variable(OperandKind K, Type Ty, SizeT Index)
: Operand(K, Ty), Number(Index), Name(Name), IsArgument(false), : Operand(K, Ty), Number(Index), NameIndex(Cfg::IdentifierIndexInvalid),
IsImplicitArgument(false), IgnoreLiveness(false), StackOffset(0), IsArgument(false), IsImplicitArgument(false), IgnoreLiveness(false),
RegNum(NoRegister), RegNumTmp(NoRegister), Weight(1), LoVar(NULL), StackOffset(0), RegNum(NoRegister), RegNumTmp(NoRegister), Weight(1),
HiVar(NULL) { LoVar(NULL), HiVar(NULL) {
Vars = VarsReal; Vars = VarsReal;
Vars[0] = this; Vars[0] = this;
NumVars = 1; NumVars = 1;
...@@ -496,8 +495,7 @@ protected: ...@@ -496,8 +495,7 @@ protected:
// Number is unique across all variables, and is used as a // Number is unique across all variables, and is used as a
// (bit)vector index for liveness analysis. // (bit)vector index for liveness analysis.
const SizeT Number; const SizeT Number;
// Name is optional. Cfg::IdentifierIndexType NameIndex;
IceString Name;
bool IsArgument; bool IsArgument;
bool IsImplicitArgument; bool IsImplicitArgument;
// IgnoreLiveness means that the variable should be ignored when // IgnoreLiveness means that the variable should be ignored when
......
...@@ -436,8 +436,9 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) { ...@@ -436,8 +436,9 @@ void LinearScan::scan(const llvm::SmallBitVector &RegMaskFull) {
} }
} }
if (Verbose && Prefer) { if (Verbose && Prefer) {
Str << "Initial Prefer=" << *Prefer << " R=" << PreferReg Str << "Initial Prefer=";
<< " LIVE=" << Prefer->getLiveRange() Prefer->dump(Func);
Str << " R=" << PreferReg << " LIVE=" << Prefer->getLiveRange()
<< " Overlap=" << AllowOverlap << "\n"; << " Overlap=" << AllowOverlap << "\n";
} }
} }
......
...@@ -555,8 +555,9 @@ void TargetX8632::lowerArguments() { ...@@ -555,8 +555,9 @@ void TargetX8632::lowerArguments() {
// to the assigned location of Arg. // to the assigned location of Arg.
int32_t RegNum = RegX8632::Reg_xmm0 + NumXmmArgs; int32_t RegNum = RegX8632::Reg_xmm0 + NumXmmArgs;
++NumXmmArgs; ++NumXmmArgs;
IceString Name = "home_reg:" + Arg->getName(); Variable *RegisterArg = Func->makeVariable(Ty);
Variable *RegisterArg = Func->makeVariable(Ty, Name); if (ALLOW_DUMP)
RegisterArg->setName(Func, "home_reg:" + Arg->getName(Func));
RegisterArg->setRegNum(RegNum); RegisterArg->setRegNum(RegNum);
RegisterArg->setIsArg(); RegisterArg->setIsArg();
Arg->setIsArg(false); Arg->setIsArg(false);
...@@ -1050,8 +1051,12 @@ void TargetX8632::split64(Variable *Var) { ...@@ -1050,8 +1051,12 @@ void TargetX8632::split64(Variable *Var) {
return; return;
} }
assert(Hi == NULL); assert(Hi == NULL);
Lo = Func->makeVariable(IceType_i32, Var->getName() + "__lo"); Lo = Func->makeVariable(IceType_i32);
Hi = Func->makeVariable(IceType_i32, Var->getName() + "__hi"); 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); Var->setLoHi(Lo, Hi);
if (Var->getIsArg()) { if (Var->getIsArg()) {
Lo->setIsArg(); Lo->setIsArg();
......
...@@ -1086,8 +1086,6 @@ void ValuesymtabParser::ProcessRecord() { ...@@ -1086,8 +1086,6 @@ void ValuesymtabParser::ProcessRecord() {
return; return;
} }
class FunctionValuesymtabParser;
/// Parses function blocks in the bitcode file. /// Parses function blocks in the bitcode file.
class FunctionParser : public BlockParserBaseClass { class FunctionParser : public BlockParserBaseClass {
FunctionParser(const FunctionParser &) = delete; FunctionParser(const FunctionParser &) = delete;
...@@ -2663,8 +2661,10 @@ void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) { ...@@ -2663,8 +2661,10 @@ void FunctionValuesymtabParser::setValueName(uint64_t Index, StringType &Name) {
return; return;
Ice::Operand *Op = getFunctionParser()->getOperand(Index); Ice::Operand *Op = getFunctionParser()->getOperand(Index);
if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) { if (Ice::Variable *V = dyn_cast<Ice::Variable>(Op)) {
if (ALLOW_DUMP) {
std::string Nm(Name.data(), Name.size()); std::string Nm(Name.data(), Name.size());
V->setName(Nm); V->setName(getFunctionParser()->getFunc(), Nm);
}
} else { } else {
reportUnableToAssign("variable", Index, Name); reportUnableToAssign("variable", Index, Name);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment