Commit 3af8a0a8 by Ian Lance Taylor

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
parent 612a6ffe
89a0b3a04f80df388242166b8835f12e82ceb194 7d6c53910e52b7db2a77c1c1c3bc2c170283a1fa
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -252,7 +252,9 @@ Expression::convert_type_to_interface(Type* lhs_type, Expression* rhs, ...@@ -252,7 +252,9 @@ Expression::convert_type_to_interface(Type* lhs_type, Expression* rhs,
else else
{ {
// We are assigning a non-pointer value to the interface; the // 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); obj = Expression::make_heap_expression(rhs, location);
} }
...@@ -729,6 +731,13 @@ Var_expression::do_address_taken(bool escapes) ...@@ -729,6 +731,13 @@ Var_expression::do_address_taken(bool escapes)
else else
go_unreachable(); 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. // Get the backend representation for a reference to a variable.
...@@ -831,6 +840,10 @@ Enclosed_var_expression::do_address_taken(bool escapes) ...@@ -831,6 +840,10 @@ Enclosed_var_expression::do_address_taken(bool escapes)
else else
go_unreachable(); 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. // Ast dump for enclosed variable expression.
...@@ -3769,9 +3782,18 @@ Unary_expression::do_flatten(Gogo* gogo, Named_object*, ...@@ -3769,9 +3782,18 @@ Unary_expression::do_flatten(Gogo* gogo, Named_object*,
// value does not escape. If this->escapes_ is true, we may be // 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 // able to set it to false if taking the address of a variable
// that does not escape. // 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()) if (var->is_variable())
this->escapes_ = var->var_value()->escapes(); this->escapes_ = var->var_value()->escapes();
if (var->is_result_variable()) if (var->is_result_variable())
...@@ -11658,7 +11680,9 @@ Allocation_expression::do_get_backend(Translate_context* context) ...@@ -11658,7 +11680,9 @@ Allocation_expression::do_get_backend(Translate_context* context)
Gogo* gogo = context->gogo(); Gogo* gogo = context->gogo();
Location loc = this->location(); 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; int64_t size;
bool ok = this->type_->backend_type_size(gogo, &size); bool ok = this->type_->backend_type_size(gogo, &size);
...@@ -12344,7 +12368,15 @@ Slice_construction_expression::do_get_backend(Translate_context* context) ...@@ -12344,7 +12368,15 @@ Slice_construction_expression::do_get_backend(Translate_context* context)
space->unary_expression()->set_is_slice_init(); space->unary_expression()->set_is_slice_init();
} }
else 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. // Build a constructor for the slice.
...@@ -13417,8 +13449,12 @@ Heap_expression::do_get_backend(Translate_context* context) ...@@ -13417,8 +13449,12 @@ Heap_expression::do_get_backend(Translate_context* context)
Location loc = this->location(); Location loc = this->location();
Gogo* gogo = context->gogo(); Gogo* gogo = context->gogo();
Btype* btype = this->type()->get_backend(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; Bstatement* decl;
Named_object* fn = context->function(); Named_object* fn = context->function();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment