From: Ian Lance Taylor Date: Wed, 5 Jun 2019 00:18:17 +0000 (+0000) Subject: compiler: statically allocate constant interface data X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=34f66a53b4f529f17643c1c1fc68dd3ae3f338ea;p=gcc.git 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 --- diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 167f3d3aa47..e9072a85851 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 6aca5f86ec7..d7bf4d75c95 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);