Commit 668a7a33 by Jim Stichnoth

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
parent 9bb188d8
...@@ -44,9 +44,9 @@ void Cfg::setError(const IceString &Message) { ...@@ -44,9 +44,9 @@ void Cfg::setError(const IceString &Message) {
Ctx->getStrDump() << "ICE translation error: " << ErrorMessage << "\n"; Ctx->getStrDump() << "ICE translation error: " << ErrorMessage << "\n";
} }
CfgNode *Cfg::makeNode(const IceString &Name) { CfgNode *Cfg::makeNode() {
SizeT LabelIndex = Nodes.size(); SizeT LabelIndex = Nodes.size();
CfgNode *Node = CfgNode::create(this, LabelIndex, Name); CfgNode *Node = CfgNode::create(this, LabelIndex);
Nodes.push_back(Node); Nodes.push_back(Node);
return Node; return Node;
} }
......
...@@ -59,9 +59,17 @@ public: ...@@ -59,9 +59,17 @@ public:
void setEntryNode(CfgNode *EntryNode) { Entry = EntryNode; } void setEntryNode(CfgNode *EntryNode) { Entry = EntryNode; }
CfgNode *getEntryNode() const { return Entry; } CfgNode *getEntryNode() const { return Entry; }
// Create a node and append it to the end of the linearized list. // 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(); } SizeT getNumNodes() const { return Nodes.size(); }
const NodeList &getNodes() const { return Nodes; } 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. // Manage instruction numbering.
InstNumberT newInstNumber() { return NextInstNumber++; } InstNumberT newInstNumber() { return NextInstNumber++; }
...@@ -175,6 +183,7 @@ private: ...@@ -175,6 +183,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;
InstNumberT NextInstNumber; InstNumberT NextInstNumber;
VarList Variables; VarList Variables;
VarList Args; // subset of Variables, in argument order VarList Args; // subset of Variables, in argument order
......
...@@ -22,15 +22,15 @@ ...@@ -22,15 +22,15 @@
namespace Ice { namespace Ice {
CfgNode::CfgNode(Cfg *Func, SizeT LabelNumber, IceString Name) CfgNode::CfgNode(Cfg *Func, SizeT LabelNumber)
: Func(Func), Number(LabelNumber), Name(Name), HasReturn(false), : Func(Func), Number(LabelNumber), NameIndex(-1), HasReturn(false),
NeedsPlacement(false), InstCountEstimate(0) {} 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 (!Name.empty()) if (NameIndex >= 0)
return Name; return Func->getNodeName(NameIndex);
return "__" + std::to_string(getIndex()); return "__" + std::to_string(getIndex());
} }
...@@ -219,8 +219,9 @@ void CfgNode::deletePhis() { ...@@ -219,8 +219,9 @@ void CfgNode::deletePhis() {
// out-edge list, this node's in-edge list, and the Phi instruction's // out-edge list, this node's in-edge list, and the Phi instruction's
// operand list. // operand list.
CfgNode *CfgNode::splitIncomingEdge(CfgNode *Pred, SizeT EdgeIndex) { CfgNode *CfgNode::splitIncomingEdge(CfgNode *Pred, SizeT EdgeIndex) {
CfgNode *NewNode = CfgNode *NewNode = Func->makeNode();
Func->makeNode("split_" + Pred->getName() + "_" + getName() + "_" + if (ALLOW_DUMP)
NewNode->setName("split_" + Pred->getName() + "_" + getName() + "_" +
std::to_string(EdgeIndex)); std::to_string(EdgeIndex));
// The new node is added to the end of the node list, and will later // The new node is added to the end of the node list, and will later
// need to be sorted into a reasonable topological order. // need to be sorted into a reasonable topological order.
......
...@@ -26,17 +26,18 @@ class CfgNode { ...@@ -26,17 +26,18 @@ class CfgNode {
CfgNode &operator=(const CfgNode &) = delete; CfgNode &operator=(const CfgNode &) = delete;
public: public:
static CfgNode *create(Cfg *Func, SizeT LabelIndex, IceString Name = "") { static CfgNode *create(Cfg *Func, SizeT LabelIndex) {
return new (Func->allocate<CfgNode>()) CfgNode(Func, LabelIndex, Name); return new (Func->allocate<CfgNode>()) CfgNode(Func, LabelIndex);
} }
// Access the label number and name for this node. // Access the label number and name for this node.
SizeT getIndex() const { return Number; } SizeT getIndex() const { return Number; }
IceString getName() const; IceString getName() const;
void setName(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(Name.empty()); assert(NameIndex < 0);
Name = NewName; if (!NewName.empty())
NameIndex = Func->addNodeName(NewName);
} }
IceString getAsmName() const { IceString getAsmName() const {
return ".L" + Func->getFunctionName() + "$" + getName(); return ".L" + Func->getFunctionName() + "$" + getName();
...@@ -87,10 +88,10 @@ public: ...@@ -87,10 +88,10 @@ public:
void dump(Cfg *Func) const; void dump(Cfg *Func) const;
private: private:
CfgNode(Cfg *Func, SizeT LabelIndex, IceString Name); CfgNode(Cfg *Func, SizeT LabelIndex);
Cfg *const Func; Cfg *const Func;
const SizeT Number; // label index 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 HasReturn; // does this block need an epilog?
bool NeedsPlacement; bool NeedsPlacement;
InstNumberT InstCountEstimate; // rough instruction count estimate InstNumberT InstCountEstimate; // rough instruction count estimate
......
...@@ -156,7 +156,9 @@ private: ...@@ -156,7 +156,9 @@ private:
Ice::CfgNode *mapBasicBlockToNode(const BasicBlock *BB) { Ice::CfgNode *mapBasicBlockToNode(const BasicBlock *BB) {
if (NodeMap.find(BB) == NodeMap.end()) { 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]; return NodeMap[BB];
} }
......
...@@ -2678,7 +2678,8 @@ void FunctionValuesymtabParser::setBbName(uint64_t Index, StringType &Name) { ...@@ -2678,7 +2678,8 @@ void FunctionValuesymtabParser::setBbName(uint64_t Index, StringType &Name) {
return; return;
} }
std::string Nm(Name.data(), Name.size()); 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) { bool FunctionParser::ParseBlock(unsigned BlockID) {
......
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