compiler: delay escaping sliced arrays
authorIan Lance Taylor <ian@gcc.gnu.org>
Tue, 9 Jan 2018 23:16:13 +0000 (23:16 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 9 Jan 2018 23:16:13 +0000 (23:16 +0000)
    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 CL changes it to not escape in the early stage.
    Later the escape analysis will make it escape when needed.

    Reviewed-on: https://go-review.googlesource.com/85635

From-SVN: r256403

gcc/go/gofrontend/MERGE
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/wb.cc

index 043e56021fca68ee925be95ca2731db8a5f9b5d0..23d2d3ad53147e49a5aa4941a167b4a0dd4bc335 100644 (file)
@@ -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 c34a5b01b6763784e25199346f2887ef91891788..4ba116860e1b9ce55c38e6ef80a0a110ed1f90c1 100644 (file)
@@ -10679,7 +10679,7 @@ Array_index_expression::do_determine_type(const Type_context*)
 // 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(Gogo* gogo)
       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 5870661b66e9cf4fca9d2639d0093dfc81bc32a3..c672bf36b26cea639328a82fcf36cae85b641974 100644 (file)
@@ -45,6 +45,25 @@ Mark_address_taken::expression(Expression** pexpr)
   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;
 }