Subzero: Pull the node name out of the node structure.
Instead, non-empty node names are kept in a single vector in the Cfg
object.
This is toward the goal of pulling non-POD fields out of the CfgNode
class so that CfgNode can be arena-allocated and not leak memory.
Also, actual setting of the node name is now guarded by ALLOW_DUMP.
BUG= none
R=jvoung@chromium.org, kschimpf@google.com
Review URL: https://codereview.chromium.org/787333005
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index d8e3b24..0bd6b36 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -44,9 +44,9 @@
Ctx->getStrDump() << "ICE translation error: " << ErrorMessage << "\n";
}
-CfgNode *Cfg::makeNode(const IceString &Name) {
+CfgNode *Cfg::makeNode() {
SizeT LabelIndex = Nodes.size();
- CfgNode *Node = CfgNode::create(this, LabelIndex, Name);
+ CfgNode *Node = CfgNode::create(this, LabelIndex);
Nodes.push_back(Node);
return Node;
}
diff --git a/src/IceCfg.h b/src/IceCfg.h
index 970b838..c313a89 100644
--- a/src/IceCfg.h
+++ b/src/IceCfg.h
@@ -59,9 +59,17 @@
void setEntryNode(CfgNode *EntryNode) { Entry = EntryNode; }
CfgNode *getEntryNode() const { return Entry; }
// Create a node and append it to the end of the linearized list.
- CfgNode *makeNode(const IceString &Name = "");
+ CfgNode *makeNode();
SizeT getNumNodes() const { return Nodes.size(); }
const NodeList &getNodes() const { return Nodes; }
+ // 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);
+ return Index;
+ }
+ const IceString &getNodeName(int32_t Index) const { return NodeNames[Index]; }
// Manage instruction numbering.
InstNumberT newInstNumber() { return NextInstNumber++; }
@@ -175,6 +183,7 @@
IceString ErrorMessage;
CfgNode *Entry; // entry basic block
NodeList Nodes; // linearized node list; Entry should be first
+ std::vector<IceString> NodeNames;
InstNumberT NextInstNumber;
VarList Variables;
VarList Args; // subset of Variables, in argument order
diff --git a/src/IceCfgNode.cpp b/src/IceCfgNode.cpp
index 59035f8..920f373 100644
--- a/src/IceCfgNode.cpp
+++ b/src/IceCfgNode.cpp
@@ -22,15 +22,15 @@
namespace Ice {
-CfgNode::CfgNode(Cfg *Func, SizeT LabelNumber, IceString Name)
- : Func(Func), Number(LabelNumber), Name(Name), HasReturn(false),
+CfgNode::CfgNode(Cfg *Func, SizeT LabelNumber)
+ : Func(Func), Number(LabelNumber), NameIndex(-1), 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 (!Name.empty())
- return Name;
+ if (NameIndex >= 0)
+ return Func->getNodeName(NameIndex);
return "__" + std::to_string(getIndex());
}
@@ -219,8 +219,9 @@
// out-edge list, this node's in-edge list, and the Phi instruction's
// operand list.
CfgNode *CfgNode::splitIncomingEdge(CfgNode *Pred, SizeT EdgeIndex) {
- CfgNode *NewNode =
- Func->makeNode("split_" + Pred->getName() + "_" + getName() + "_" +
+ CfgNode *NewNode = Func->makeNode();
+ if (ALLOW_DUMP)
+ NewNode->setName("split_" + Pred->getName() + "_" + getName() + "_" +
std::to_string(EdgeIndex));
// The new node is added to the end of the node list, and will later
// need to be sorted into a reasonable topological order.
diff --git a/src/IceCfgNode.h b/src/IceCfgNode.h
index 279b07f..d60b0f0 100644
--- a/src/IceCfgNode.h
+++ b/src/IceCfgNode.h
@@ -26,17 +26,18 @@
CfgNode &operator=(const CfgNode &) = delete;
public:
- static CfgNode *create(Cfg *Func, SizeT LabelIndex, IceString Name = "") {
- return new (Func->allocate<CfgNode>()) CfgNode(Func, LabelIndex, Name);
+ static CfgNode *create(Cfg *Func, SizeT LabelIndex) {
+ return new (Func->allocate<CfgNode>()) CfgNode(Func, LabelIndex);
}
// Access the label number and name for this node.
SizeT getIndex() const { return Number; }
IceString getName() const;
- void setName(IceString &NewName) {
+ void setName(const IceString &NewName) {
// Make sure that the name can only be set once.
- assert(Name.empty());
- Name = NewName;
+ assert(NameIndex < 0);
+ if (!NewName.empty())
+ NameIndex = Func->addNodeName(NewName);
}
IceString getAsmName() const {
return ".L" + Func->getFunctionName() + "$" + getName();
@@ -87,10 +88,10 @@
void dump(Cfg *Func) const;
private:
- CfgNode(Cfg *Func, SizeT LabelIndex, IceString Name);
+ CfgNode(Cfg *Func, SizeT LabelIndex);
Cfg *const Func;
const SizeT Number; // label index
- IceString Name; // for dumping only
+ int32_t 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 e06e290..a8148f9 100644
--- a/src/IceConverter.cpp
+++ b/src/IceConverter.cpp
@@ -156,7 +156,9 @@
Ice::CfgNode *mapBasicBlockToNode(const BasicBlock *BB) {
if (NodeMap.find(BB) == NodeMap.end()) {
- NodeMap[BB] = Func->makeNode(BB->getName());
+ NodeMap[BB] = Func->makeNode();
+ if (ALLOW_DUMP)
+ NodeMap[BB]->setName(BB->getName());
}
return NodeMap[BB];
}
diff --git a/src/PNaClTranslator.cpp b/src/PNaClTranslator.cpp
index 124ed89..8f1f99d 100644
--- a/src/PNaClTranslator.cpp
+++ b/src/PNaClTranslator.cpp
@@ -2678,7 +2678,8 @@
return;
}
std::string Nm(Name.data(), Name.size());
- getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
+ if (ALLOW_DUMP)
+ getFunctionParser()->getFunc()->getNodes()[Index]->setName(Nm);
}
bool FunctionParser::ParseBlock(unsigned BlockID) {