aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2016-08-03 16:32:17 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2016-08-03 16:32:17 +0000
commit3af8a0a8101a69866dad7f8a3e2d687040838260 (patch)
tree9077206ae7a7ad737453d252c89fd7742f09cd64
parent612a6ffe0ea3b27a5f8180a8d0844593a791568c (diff)
downloadgcc-3af8a0a8101a69866dad7f8a3e2d687040838260.zip
gcc-3af8a0a8101a69866dad7f8a3e2d687040838260.tar.gz
gcc-3af8a0a8101a69866dad7f8a3e2d687040838260.tar.bz2
escape: Stack allocate non-escaping expressions.
Stack allocate expressions that the analysis tracked and determined did not escape. Reviewed-on: https://go-review.googlesource.com/22377 From-SVN: r239083
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc50
2 files changed, 44 insertions, 8 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 7e1cc13..5009c89 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -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.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 5f7e4c9..ff2893f 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -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();