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);
   }