Commit 34f66a53 by Ian Lance Taylor

compiler: statically allocate constant interface data

    
    When converting a constant to interface, such as interface{}(42)
    or interface{}("hello"), if the interface escapes, we currently
    generate a heap allocation to hold the constant value.
    
    This CL changes it to generate a static allocation instead, as
    the gc compiler does. This reduces allocations in such cases.
    
    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/180277

From-SVN: r271945
parent abccc5d2
e4d8ccaed06f81683e79774ede6c61949f6df8b8 949c3b7aa603bc09e650d62e82c600b3463802f0
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.
...@@ -323,10 +323,15 @@ Expression::convert_type_to_interface(Type* lhs_type, Expression* rhs, ...@@ -323,10 +323,15 @@ Expression::convert_type_to_interface(Type* lhs_type, Expression* rhs,
{ {
// 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 if it escapes. // interface gets a copy of the value in the heap if it escapes.
if (rhs->is_constant())
obj = Expression::make_unary(OPERATOR_AND, rhs, location);
else
{
obj = Expression::make_heap_expression(rhs, location); obj = Expression::make_heap_expression(rhs, location);
if (on_stack) if (on_stack)
obj->heap_expression()->set_allocate_on_stack(); obj->heap_expression()->set_allocate_on_stack();
} }
}
return Expression::make_interface_value(lhs_type, first_field, obj, location); return Expression::make_interface_value(lhs_type, first_field, obj, location);
} }
...@@ -4896,6 +4901,18 @@ Unary_expression::do_get_backend(Translate_context* context) ...@@ -4896,6 +4901,18 @@ Unary_expression::do_get_backend(Translate_context* context)
false, btype, loc, bexpr); false, btype, loc, bexpr);
bexpr = gogo->backend()->var_expression(decl, loc); bexpr = gogo->backend()->var_expression(decl, loc);
} }
else if (this->expr_->is_constant())
{
std::string var_name(gogo->initializer_name());
std::string asm_name(go_selectively_encode_id(var_name));
Bvariable* decl =
gogo->backend()->implicit_variable(var_name, asm_name, btype,
true, true, false, 0);
gogo->backend()->implicit_variable_set_init(decl, var_name, btype,
true, true, false,
bexpr);
bexpr = gogo->backend()->var_expression(decl, loc);
}
go_assert(!this->create_temp_ || this->expr_->is_variable()); go_assert(!this->create_temp_ || this->expr_->is_variable());
ret = gogo->backend()->address_expression(bexpr, loc); ret = gogo->backend()->address_expression(bexpr, loc);
......
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