aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-06-05 00:18:17 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-06-05 00:18:17 +0000
commit34f66a53b4f529f17643c1c1fc68dd3ae3f338ea (patch)
tree0bd3561a889220cfb173c2bdcb4e8cdbe9cf64fb /gcc
parentabccc5d2198f9bac2f09680bb9fb6882bfeae087 (diff)
downloadgcc-34f66a53b4f529f17643c1c1fc68dd3ae3f338ea.zip
gcc-34f66a53b4f529f17643c1c1fc68dd3ae3f338ea.tar.gz
gcc-34f66a53b4f529f17643c1c1fc68dd3ae3f338ea.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc23
2 files changed, 21 insertions, 4 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 167f3d3..e9072a8 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-e4d8ccaed06f81683e79774ede6c61949f6df8b8
+949c3b7aa603bc09e650d62e82c600b3463802f0
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 6aca5f8..d7bf4d7 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -323,9 +323,14 @@ Expression::convert_type_to_interface(Type* lhs_type, Expression* rhs,
{
// We are assigning a non-pointer value to the interface; the
// interface gets a copy of the value in the heap if it escapes.
- obj = Expression::make_heap_expression(rhs, location);
- if (on_stack)
- obj->heap_expression()->set_allocate_on_stack();
+ if (rhs->is_constant())
+ obj = Expression::make_unary(OPERATOR_AND, rhs, location);
+ else
+ {
+ obj = Expression::make_heap_expression(rhs, location);
+ if (on_stack)
+ obj->heap_expression()->set_allocate_on_stack();
+ }
}
return Expression::make_interface_value(lhs_type, first_field, obj, location);
@@ -4896,6 +4901,18 @@ Unary_expression::do_get_backend(Translate_context* context)
false, btype, loc, bexpr);
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());
ret = gogo->backend()->address_expression(bexpr, loc);