This patch to the Go frontend changes some maps used by the escape analysis pass to use hash tables instead. It also changes them to use just one table lookup, not two. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline.
Ian
Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 276228) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -10a1671d94ddc0c39f2f4b039e5ea33358f414c0 +07faafda5fbd66a710153814f30d93c91461e7cb The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: gcc/go/gofrontend/escape.cc =================================================================== --- gcc/go/gofrontend/escape.cc (revision 276221) +++ gcc/go/gofrontend/escape.cc (working copy) @@ -579,9 +579,9 @@ Node::is_sink() const return false; } -std::map<Named_object*, Node*> Node::objects; -std::map<Expression*, Node*> Node::expressions; -std::map<Statement*, Node*> Node::statements; +Unordered_map(Named_object*, Node*) Node::objects; +Unordered_map(Expression*, Node*) Node::expressions; +Unordered_map(Statement*, Node*) Node::statements; std::vector<Node*> Node::indirects; // Make a object node or return a cached node for this object. @@ -589,13 +589,12 @@ std::vector<Node*> Node::indirects; Node* Node::make_node(Named_object* no) { - if (Node::objects.find(no) != Node::objects.end()) - return Node::objects[no]; - - Node* n = new Node(no); - std::pair<Named_object*, Node*> val(no, n); - Node::objects.insert(val); - return n; + std::pair<Named_object*, Node*> val(no, NULL); + std::pair<Unordered_map(Named_object*, Node*)::iterator, bool> ins = + Node::objects.insert(val); + if (ins.second) + ins.first->second = new Node(no); + return ins.first->second; } // Make an expression node or return a cached node for this expression. @@ -603,13 +602,12 @@ Node::make_node(Named_object* no) Node* Node::make_node(Expression* e) { - if (Node::expressions.find(e) != Node::expressions.end()) - return Node::expressions[e]; - - Node* n = new Node(e); - std::pair<Expression*, Node*> val(e, n); - Node::expressions.insert(val); - return n; + std::pair<Expression*, Node*> val(e, NULL); + std::pair<Unordered_map(Expression*, Node*)::iterator, bool> ins = + Node::expressions.insert(val); + if (ins.second) + ins.first->second = new Node(e); + return ins.first->second; } // Make a statement node or return a cached node for this statement. @@ -617,13 +615,12 @@ Node::make_node(Expression* e) Node* Node::make_node(Statement* s) { - if (Node::statements.find(s) != Node::statements.end()) - return Node::statements[s]; - - Node* n = new Node(s); - std::pair<Statement*, Node*> val(s, n); - Node::statements.insert(val); - return n; + std::pair<Statement*, Node*> val(s, NULL); + std::pair<Unordered_map(Statement*, Node*)::iterator, bool> ins = + Node::statements.insert(val); + if (ins.second) + ins.first->second = new Node(s); + return ins.first->second; } // Make an indirect node with given child. @@ -3447,19 +3444,22 @@ Gogo::reclaim_escape_nodes() void Node::reclaim_nodes() { - for (std::map<Named_object*, Node*>::iterator p = Node::objects.begin(); + for (Unordered_map(Named_object*, Node*)::iterator p = + Node::objects.begin(); p != Node::objects.end(); ++p) delete p->second; Node::objects.clear(); - for (std::map<Expression*, Node*>::iterator p = Node::expressions.begin(); + for (Unordered_map(Expression*, Node*)::iterator p = + Node::expressions.begin(); p != Node::expressions.end(); ++p) delete p->second; Node::expressions.clear(); - for (std::map<Statement*, Node*>::iterator p = Node::statements.begin(); + for (Unordered_map(Statement*, Node*)::iterator p = + Node::statements.begin(); p != Node::statements.end(); ++p) delete p->second; Index: gcc/go/gofrontend/escape.h =================================================================== --- gcc/go/gofrontend/escape.h (revision 276221) +++ gcc/go/gofrontend/escape.h (working copy) @@ -329,9 +329,9 @@ class Node Node* child_; // Cache all the Nodes created via Node::make_node to make the API simpler. - static std::map<Named_object*, Node*> objects; - static std::map<Expression*, Node*> expressions; - static std::map<Statement*, Node*> statements; + static Unordered_map(Named_object*, Node*) objects; + static Unordered_map(Expression*, Node*) expressions; + static Unordered_map(Statement*, Node*) statements; // Collection of all NODE_INDIRECT Nodes, used for reclaiming memory. This // is not a cache -- each make_indirect_node will make a fresh Node.