From 8a8a7d332d5d01db5aea7336a36d9fd71a679fb1 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 28 Jun 2021 16:47:55 -0700 Subject: compiler: in composite literals use temps only for interfaces For a composite literal we only need to introduce a temporary variable if we may be converting to an interface type, so only do it then. This saves over 80% of compilation time when using gccgo to compile cmd/internal/obj/x86, as the GCC middle-end spends a lot of time pointlessly computing interactions between temporary variables. For PR debug/101064 For golang/go#46600 Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/331513 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 17 +++++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index f16fb9f..f7bcc8c 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -bcafcb3c39530bb325514d6377747eb3127d1a03 +cad187fe3aceb2a7d964b64c70dfa8c8ad24ce65 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 5d45e4b..94342b2 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -15148,7 +15148,7 @@ Struct_construction_expression::do_copy() } // Flatten a struct construction expression. Store the values into -// temporaries in case they need interface conversion. +// temporaries if they may need interface conversion. Expression* Struct_construction_expression::do_flatten(Gogo*, Named_object*, @@ -15162,10 +15162,13 @@ Struct_construction_expression::do_flatten(Gogo*, Named_object*, return this; Location loc = this->location(); + const Struct_field_list* fields = this->type_->struct_type()->fields(); + Struct_field_list::const_iterator pf = fields->begin(); for (Expression_list::iterator pv = this->vals()->begin(); pv != this->vals()->end(); - ++pv) + ++pv, ++pf) { + go_assert(pf != fields->end()); if (*pv != NULL) { if ((*pv)->is_error_expression() || (*pv)->type()->is_error_type()) @@ -15173,7 +15176,8 @@ Struct_construction_expression::do_flatten(Gogo*, Named_object*, go_assert(saw_errors()); return Expression::make_error(loc); } - if (!(*pv)->is_multi_eval_safe()) + if (pf->type()->interface_type() != NULL + && !(*pv)->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, *pv, loc); @@ -15448,7 +15452,7 @@ Array_construction_expression::do_check_types(Gogo*) } // Flatten an array construction expression. Store the values into -// temporaries in case they need interface conversion. +// temporaries if they may need interface conversion. Expression* Array_construction_expression::do_flatten(Gogo*, Named_object*, @@ -15467,6 +15471,11 @@ Array_construction_expression::do_flatten(Gogo*, Named_object*, if (this->is_constant_array() || this->is_static_initializer()) return this; + // If the array element type is not an interface type, we don't need + // temporaries. + if (this->type_->array_type()->element_type()->interface_type() == NULL) + return this; + Location loc = this->location(); for (Expression_list::iterator pv = this->vals()->begin(); pv != this->vals()->end(); -- cgit v1.1 From cca7eb8f7cc157ed1b351cbaa10a4066f8065c3a Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 29 Jun 2021 12:12:16 -0700 Subject: go-gcc: set DECL_NAMELESS for temporary variables * go-gcc.cc (Gcc_backend::static_chain_variable): Set DECL_NAMELESS on the new decl. (Gcc_backend::temporary_variable): Likewise. (Gcc_backend::function): Set DECL_NAMELESS on the result decl. --- gcc/go/go-gcc.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gcc/go') diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 41f309e..f812796 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -2853,6 +2853,7 @@ Gcc_backend::static_chain_variable(Bfunction* function, const std::string& name, TREE_USED(decl) = 1; DECL_ARTIFICIAL(decl) = 1; DECL_IGNORED_P(decl) = 1; + DECL_NAMELESS(decl) = 1; TREE_READONLY(decl) = 1; struct function *f = DECL_STRUCT_FUNCTION(fndecl); @@ -2912,6 +2913,7 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock, type_tree); DECL_ARTIFICIAL(var) = 1; DECL_IGNORED_P(var) = 1; + DECL_NAMELESS(var) = 1; TREE_USED(var) = 1; DECL_CONTEXT(var) = decl; @@ -3290,6 +3292,7 @@ Gcc_backend::function(Btype* fntype, const std::string& name, build_decl(location.gcc_location(), RESULT_DECL, NULL_TREE, restype); DECL_ARTIFICIAL(resdecl) = 1; DECL_IGNORED_P(resdecl) = 1; + DECL_NAMELESS(resdecl) = 1; DECL_CONTEXT(resdecl) = decl; DECL_RESULT(decl) = resdecl; } -- cgit v1.1 From 13c906f43f473ee9ff16d80590789d719f2190a4 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 29 Jun 2021 12:53:02 -0700 Subject: compiler: don't generate temporaries for composite literals We were generating temporaries for composite literals when a conversion to interface type was required. However, Cherry's https://golang.org/cl/176459 changed the compiler to insert explicit type conversions. And those explicit type conversions insert the required temporaries in Type_conversion_expression::do_flatten. So in practice the composite literal do_flatten methods would never insert temporaries, as the values they see would always be multi_eval_safe. So just remove the unnecessary do_flatten methods. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/331691 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/expressions.cc | 103 +++------------------------------------ gcc/go/gofrontend/expressions.h | 6 --- 3 files changed, 7 insertions(+), 104 deletions(-) (limited to 'gcc/go') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index f7bcc8c..ab1384d 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -cad187fe3aceb2a7d964b64c70dfa8c8ad24ce65 +01cb2b5e69a2d08ef3cc1ea023c22ed9b79f5114 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 94342b2..a0472ac 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -15147,48 +15147,6 @@ Struct_construction_expression::do_copy() return ret; } -// Flatten a struct construction expression. Store the values into -// temporaries if they may need interface conversion. - -Expression* -Struct_construction_expression::do_flatten(Gogo*, Named_object*, - Statement_inserter* inserter) -{ - if (this->vals() == NULL) - return this; - - // If this is a constant struct, we don't need temporaries. - if (this->is_constant_struct() || this->is_static_initializer()) - return this; - - Location loc = this->location(); - const Struct_field_list* fields = this->type_->struct_type()->fields(); - Struct_field_list::const_iterator pf = fields->begin(); - for (Expression_list::iterator pv = this->vals()->begin(); - pv != this->vals()->end(); - ++pv, ++pf) - { - go_assert(pf != fields->end()); - if (*pv != NULL) - { - if ((*pv)->is_error_expression() || (*pv)->type()->is_error_type()) - { - go_assert(saw_errors()); - return Expression::make_error(loc); - } - if (pf->type()->interface_type() != NULL - && !(*pv)->is_multi_eval_safe()) - { - Temporary_statement* temp = - Statement::make_temporary(NULL, *pv, loc); - inserter->insert(temp); - *pv = Expression::make_temporary_reference(temp, loc); - } - } - } - return this; -} - // Make implicit type conversions explicit. void @@ -15451,55 +15409,6 @@ Array_construction_expression::do_check_types(Gogo*) } } -// Flatten an array construction expression. Store the values into -// temporaries if they may need interface conversion. - -Expression* -Array_construction_expression::do_flatten(Gogo*, Named_object*, - Statement_inserter* inserter) -{ - if (this->is_error_expression()) - { - go_assert(saw_errors()); - return this; - } - - if (this->vals() == NULL) - return this; - - // If this is a constant array, we don't need temporaries. - if (this->is_constant_array() || this->is_static_initializer()) - return this; - - // If the array element type is not an interface type, we don't need - // temporaries. - if (this->type_->array_type()->element_type()->interface_type() == NULL) - return this; - - Location loc = this->location(); - for (Expression_list::iterator pv = this->vals()->begin(); - pv != this->vals()->end(); - ++pv) - { - if (*pv != NULL) - { - if ((*pv)->is_error_expression() || (*pv)->type()->is_error_type()) - { - go_assert(saw_errors()); - return Expression::make_error(loc); - } - if (!(*pv)->is_multi_eval_safe()) - { - Temporary_statement* temp = - Statement::make_temporary(NULL, *pv, loc); - inserter->insert(temp); - *pv = Expression::make_temporary_reference(temp, loc); - } - } - } - return this; -} - // Make implicit type conversions explicit. void @@ -15768,14 +15677,14 @@ Slice_construction_expression::create_array_val() // the new temp statement. Expression* -Slice_construction_expression::do_flatten(Gogo* gogo, Named_object* no, +Slice_construction_expression::do_flatten(Gogo*, Named_object*, Statement_inserter* inserter) { if (this->type()->array_type() == NULL) - return NULL; - - // Base class flattening first - this->Array_construction_expression::do_flatten(gogo, no, inserter); + { + go_assert(saw_errors()); + return Expression::make_error(this->location()); + } // Create a stack-allocated storage temp if storage won't escape if (!this->storage_escapes_ @@ -15784,7 +15693,7 @@ Slice_construction_expression::do_flatten(Gogo* gogo, Named_object* no, { Location loc = this->location(); this->array_val_ = this->create_array_val(); - go_assert(this->array_val_); + go_assert(this->array_val_ != NULL); Temporary_statement* temp = Statement::make_temporary(this->valtype_, this->array_val_, loc); inserter->insert(temp); diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index e3747cc..57c974d 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -3806,9 +3806,6 @@ class Struct_construction_expression : public Expression, Expression* do_copy(); - Expression* - do_flatten(Gogo*, Named_object*, Statement_inserter*); - Bexpression* do_get_backend(Translate_context*); @@ -3881,9 +3878,6 @@ protected: indexes() { return this->indexes_; } - Expression* - do_flatten(Gogo*, Named_object*, Statement_inserter*); - // Get the backend constructor for the array values. Bexpression* get_constructor(Translate_context* context, Btype* btype); -- cgit v1.1 From 6bc18203dd2a696cdfcd9d45eae3b9cce7b08822 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 30 Jun 2021 00:16:52 +0000 Subject: Daily bump. --- gcc/go/ChangeLog | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'gcc/go') diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index b6ec83c..60ebb89 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,10 @@ +2021-06-29 Ian Lance Taylor + + * go-gcc.cc (Gcc_backend::static_chain_variable): Set + DECL_NAMELESS on the new decl. + (Gcc_backend::temporary_variable): Likewise. + (Gcc_backend::function): Set DECL_NAMELESS on the result decl. + 2021-05-27 Ian Lance Taylor * gccgo.texi (Function Names): Don't HTML quote ampersand. -- cgit v1.1