diff mbox series

Go patch committed: Delay escaping sliced arrays

Message ID CAOyqgcW1w1YEZ5XpuX6de7hO7fSBmMmmSQyAJfdwV33ufNfzCw@mail.gmail.com
State New
Headers show
Series Go patch committed: Delay escaping sliced arrays | expand

Commit Message

Ian Lance Taylor Jan. 9, 2018, 11:16 p.m. UTC
This patch to the Go frontend by Cherry Zhang delays escaping sliced
arrays.  Arrays that are sliced are set to escape in type checking,
very early in compilation.  The escape analysis runs later but cannot
undo it.  This patch changes it to not escape in the early stage.
Later the escape analysis will make it escape when needed.
Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian
diff mbox series

Patch

Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 256399)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@ 
-cd422bacf0505e9656661d97a571668ad1bde0fe
+91169ab206266361624236f0137668162ee8cb9b
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
Index: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 256366)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -10679,7 +10679,7 @@  Array_index_expression::do_determine_typ
 // Check types of an array index.
 
 void
-Array_index_expression::do_check_types(Gogo* gogo)
+Array_index_expression::do_check_types(Gogo*)
 {
   Numeric_constant nc;
   unsigned long v;
@@ -10798,18 +10798,9 @@  Array_index_expression::do_check_types(G
       if (!this->array_->is_addressable())
 	this->report_error(_("slice of unaddressable value"));
       else
-	{
-	  bool escapes = true;
-
-	  // When compiling the runtime, a slice operation does not
-	  // cause local variables to escape.  When escape analysis
-	  // becomes the default, this should be changed to make it an
-	  // error if we have a slice operation that escapes.
-	  if (gogo->compiling_runtime() && gogo->package_name() == "runtime")
-	    escapes = false;
-
-	  this->array_->address_taken(escapes);
-	}
+        // Set the array address taken but not escape. The escape
+        // analysis will make it escape to heap when needed.
+        this->array_->address_taken(false);
     }
 }
 
Index: gcc/go/gofrontend/wb.cc
===================================================================
--- gcc/go/gofrontend/wb.cc	(revision 256366)
+++ gcc/go/gofrontend/wb.cc	(working copy)
@@ -45,6 +45,25 @@  Mark_address_taken::expression(Expressio
   Unary_expression* ue = expr->unary_expression();
   if (ue != NULL)
     ue->check_operand_address_taken(this->gogo_);
+
+  Array_index_expression* aie = expr->array_index_expression();
+  if (aie != NULL
+      && aie->end() != NULL
+      && !aie->array()->type()->is_slice_type())
+    {
+      // Slice of an array. The escape analysis models this with
+      // a child Node representing the address of the array.
+      bool escapes = false;
+      if (!this->gogo_->compiling_runtime()
+          || this->gogo_->package_name() != "runtime")
+        {
+          Node* n = Node::make_node(expr);
+          if (n->child() == NULL
+              || (n->child()->encoding() & ESCAPE_MASK) != Node::ESCAPE_NONE)
+            escapes = true;
+        }
+      aie->array()->address_taken(escapes);
+    }
   return TRAVERSE_CONTINUE;
 }