This patch by Cherry Zhang fixes the Go frontend to reclaim the memory of escape analysis Nodes before kicking off the backend, as they are not needed in get_backend. 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 256706) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -afac7d7bed07ebe3add1784aaa9547c4d660d0ed +ff851e1190923f8612004c6c214a7c202471b0ba 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 256593) +++ gcc/go/gofrontend/escape.cc (working copy) @@ -445,6 +445,17 @@ Node::state(Escape_context* context, Nam return this->state_; } +Node::~Node() +{ + if (this->state_ != NULL) + { + if (this->expr() == NULL || this->expr()->var_expression() == NULL) + // Var expression Node is excluded since it shares state with the + // underlying var Node. + delete this->state_; + } +} + int Node::encoding() { @@ -552,6 +563,7 @@ Node::is_sink() const std::map<Named_object*, Node*> Node::objects; std::map<Expression*, Node*> Node::expressions; std::map<Statement*, Node*> Node::statements; +std::vector<Node*> Node::indirects; // Make a object node or return a cached node for this object. @@ -601,6 +613,7 @@ Node* Node::make_indirect_node(Node* child) { Node* n = new Node(child); + Node::indirects.push_back(n); return n; } @@ -3335,3 +3348,39 @@ Gogo::tag_function(Escape_context* conte Escape_analysis_tag eat(context); eat.tag(fn); } + +// Reclaim memory of escape analysis Nodes. + +void +Gogo::reclaim_escape_nodes() +{ + Node::reclaim_nodes(); +} + +void +Node::reclaim_nodes() +{ + for (std::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(); + p != Node::expressions.end(); + ++p) + delete p->second; + Node::expressions.clear(); + + for (std::map<Statement*, Node*>::iterator p = Node::statements.begin(); + p != Node::statements.end(); + ++p) + delete p->second; + Node::statements.clear(); + + for (std::vector<Node*>::iterator p = Node::indirects.begin(); + p != Node::indirects.end(); + ++p) + delete *p; + Node::indirects.clear(); +} Index: gcc/go/gofrontend/escape.h =================================================================== --- gcc/go/gofrontend/escape.h (revision 256593) +++ gcc/go/gofrontend/escape.h (working copy) @@ -191,6 +191,8 @@ class Node child_(n) {} + ~Node(); + // Return this node's type. Type* type() const; @@ -296,6 +298,10 @@ class Node static int note_inout_flows(int e, int index, Level level); + // Reclaim nodes. + static void + reclaim_nodes(); + private: // The classification of this Node. Node_classification classification_; @@ -326,6 +332,10 @@ class Node static std::map<Named_object*, Node*> objects; static std::map<Expression*, Node*> expressions; static std::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. + static std::vector<Node*> indirects; }; // The amount of bits used for the escapement encoding. Index: gcc/go/gofrontend/go.cc =================================================================== --- gcc/go/gofrontend/go.cc (revision 256593) +++ gcc/go/gofrontend/go.cc (working copy) @@ -167,6 +167,9 @@ go_parse_input_files(const char** filena // Flatten the parse tree. ::gogo->flatten(); + // Reclaim memory of escape analysis Nodes. + ::gogo->reclaim_escape_nodes(); + // Dump ast, use filename[0] as the base name ::gogo->dump_ast(filenames[0]); } Index: gcc/go/gofrontend/gogo.h =================================================================== --- gcc/go/gofrontend/gogo.h (revision 256593) +++ gcc/go/gofrontend/gogo.h (working copy) @@ -682,6 +682,10 @@ class Gogo void tag_function(Escape_context*, Named_object*); + // Reclaim memory of escape analysis Nodes. + void + reclaim_escape_nodes(); + // Do all exports. void do_exports();