escape: Stack allocate non-escaping expressions.
authorIan Lance Taylor <ian@gcc.gnu.org>
Wed, 3 Aug 2016 16:32:17 +0000 (16:32 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 3 Aug 2016 16:32:17 +0000 (16:32 +0000)
    Stack allocate expressions that the analysis tracked and determined
    did not escape.

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

From-SVN: r239083

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

index 7e1cc13ef9350f6449858b5652f767c5a82639ed..5009c891e8aed16d76aa2093125154db22f3a669 100644 (file)
@@ -1,4 +1,4 @@
-89a0b3a04f80df388242166b8835f12e82ceb194
+7d6c53910e52b7db2a77c1c1c3bc2c170283a1fa
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 5f7e4c9c0e3f4a5fada331c3df12025b8761043c..ff2893f960c154f840a86b53b7c7b6a574849579 100644 (file)
@@ -252,7 +252,9 @@ Expression::convert_type_to_interface(Type* lhs_type, Expression* rhs,
   else
     {
       // We are assigning a non-pointer value to the interface; the
-      // interface gets a copy of the value in the heap.
+      // interface gets a copy of the value in the heap if it escapes.
+      // TODO(cmang): Associate escape state state of RHS with newly
+      // created OBJ.
       obj = Expression::make_heap_expression(rhs, location);
     }
 
@@ -729,6 +731,13 @@ Var_expression::do_address_taken(bool escapes)
       else
        go_unreachable();
     }
+
+  if (this->variable_->is_variable()
+      && this->variable_->var_value()->is_in_heap())
+    {
+      Node::make_node(this)->set_encoding(Node::ESCAPE_HEAP);
+      Node::make_node(this->variable_)->set_encoding(Node::ESCAPE_HEAP);
+    }
 }
 
 // Get the backend representation for a reference to a variable.
@@ -831,6 +840,10 @@ Enclosed_var_expression::do_address_taken(bool escapes)
       else
        go_unreachable();
     }
+
+  if (this->variable_->is_variable()
+      && this->variable_->var_value()->is_in_heap())
+    Node::make_node(this->variable_)->set_encoding(Node::ESCAPE_HEAP);
 }
 
 // Ast dump for enclosed variable expression.
@@ -3769,9 +3782,18 @@ Unary_expression::do_flatten(Gogo* gogo, Named_object*,
       // value does not escape.  If this->escapes_ is true, we may be
       // able to set it to false if taking the address of a variable
       // that does not escape.
-      if (this->escapes_ && this->expr_->var_expression() != NULL)
+      Node* n = Node::make_node(this);
+      if ((n->encoding() & ESCAPE_MASK) == int(Node::ESCAPE_NONE))
+       this->escapes_ = false;
+
+      Named_object* var = NULL;
+      if (this->expr_->var_expression() != NULL)
+       var = this->expr_->var_expression()->named_object();
+      else if (this->expr_->enclosed_var_expression() != NULL)
+       var = this->expr_->enclosed_var_expression()->variable();
+
+      if (this->escapes_ && var != NULL)
        {
-         Named_object* var = this->expr_->var_expression()->named_object();
          if (var->is_variable())
            this->escapes_ = var->var_value()->escapes();
          if (var->is_result_variable())
@@ -11658,7 +11680,9 @@ Allocation_expression::do_get_backend(Translate_context* context)
   Gogo* gogo = context->gogo();
   Location loc = this->location();
 
-  if (this->allocate_on_stack_)
+  Node* n = Node::make_node(this);
+  if (this->allocate_on_stack_
+      || (n->encoding() & ESCAPE_MASK) == int(Node::ESCAPE_NONE))
     {
       int64_t size;
       bool ok = this->type_->backend_type_size(gogo, &size);
@@ -12344,7 +12368,15 @@ Slice_construction_expression::do_get_backend(Translate_context* context)
       space->unary_expression()->set_is_slice_init();
     }
   else
-    space = Expression::make_heap_expression(array_val, loc);
+    {
+      space = Expression::make_heap_expression(array_val, loc);
+      Node* n = Node::make_node(this);
+      if ((n->encoding() & ESCAPE_MASK) == int(Node::ESCAPE_NONE))
+       {
+         n = Node::make_node(space);
+         n->set_encoding(Node::ESCAPE_NONE);
+       }
+    }
 
   // Build a constructor for the slice.
 
@@ -13417,8 +13449,12 @@ Heap_expression::do_get_backend(Translate_context* context)
   Location loc = this->location();
   Gogo* gogo = context->gogo();
   Btype* btype = this->type()->get_backend(gogo);
-  Bexpression* space = Expression::make_allocation(this->expr_->type(),
-                                                  loc)->get_backend(context);
+
+  Expression* alloc = Expression::make_allocation(this->expr_->type(), loc);
+  Node* n = Node::make_node(this);
+  if ((n->encoding() & ESCAPE_MASK) == int(Node::ESCAPE_NONE))
+    alloc->allocation_expression()->set_allocate_on_stack();
+  Bexpression* space = alloc->get_backend(context);
 
   Bstatement* decl;
   Named_object* fn = context->function();