Go patch committed: Scan all function literals for escape analysis

Message ID CAOyqgcV_xB=_Qx-9ev5R3aEb4hC1eCPouX6JQdyWJKT-ubXOrA@mail.gmail.com
State New
Headers show
Series
  • Go patch committed: Scan all function literals for escape analysis
Related show

Commit Message

David Malcolm via Gcc-patches July 27, 2020, 4:41 p.m.
This patch to the Go frontend scans all function literals for escape
analysis.  We were scanning only function literals with closures, but
not all function literals have closures.  The effect of this is a
missed optimization in some cases: we will allocate some variables on
the heap unnecessarily.  Bootstrapped and ran Go testsuite on
x86_64-pc-linux-gnu.  Committed to mainline.

Ian
a449a09f88f149f4c29fae09539ba0a909204a36

Patch

diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index d23e7377306..0fa32a43489 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@ 
-587d4595e446c597efe97ccdc81b2f05cbc04a21
+e86f2cb5d6b1984fde345d6ade605e377fa38c04
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/escape.cc b/gcc/go/gofrontend/escape.cc
index 0d38858897d..8962f3f38d1 100644
--- a/gcc/go/gofrontend/escape.cc
+++ b/gcc/go/gofrontend/escape.cc
@@ -142,18 +142,22 @@  Node::ast_format(Gogo* gogo) const
   else if (this->expr() != NULL)
     {
       Expression* e = this->expr();
+
       bool is_call = e->call_expression() != NULL;
       if (is_call)
-	e->call_expression()->fn();
+	e = e->call_expression()->fn();
       Func_expression* fe = e->func_expression();;
-
-      bool is_closure = fe != NULL && fe->closure() != NULL;
-      if (is_closure)
+      if (fe != NULL)
 	{
-	  if (is_call)
-	    return "(func literal)()";
-	  return "func literal";
+	  Named_object* no = fe->named_object();
+	  if (no->is_function() && no->func_value()->enclosing() != NULL)
+	    {
+	      if (is_call)
+		return "(func literal)()";
+	      return "func literal";
+	    }
 	}
+
       Ast_dump_context::dump_to_stream(this->expr(), &ss);
     }
   else if (this->statement() != NULL)
@@ -1172,11 +1176,14 @@  Escape_discover_expr::expression(Expression** pexpr)
       // Method call or function call.
       fn = e->call_expression()->fn()->func_expression()->named_object();
     }
-  else if (e->func_expression() != NULL
-           && e->func_expression()->closure() != NULL)
+  else if (e->func_expression() != NULL)
     {
-      // Closure.
-      fn = e->func_expression()->named_object();
+      Named_object* no = e->func_expression()->named_object();
+      if (no->is_function() && no->func_value()->enclosing() != NULL)
+	{
+	  // Nested function.
+	  fn = no;
+	}
     }
 
   if (fn != NULL)