From 9b4e458bd7a31b288e5c944cd27419a7f434367e Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 27 Nov 2018 23:29:15 +0000 Subject: [PATCH] compiler: record final type for numeric expressions Inlinable function bodies are generated after the determine_types pass, so we know the type for all constants. Rather than try to determine it again when inlining, record the type in the export data, using a $convert expression. Reduce the number of explicit $convert expressions by recording a type context with the expected type in cases where that type is known. Reviewed-on: https://go-review.googlesource.com/c/150071 From-SVN: r266534 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/export.h | 14 ++++++++- gcc/go/gofrontend/expressions.cc | 49 ++++++++++++++++++++++++++++++++ gcc/go/gofrontend/gogo.cc | 2 ++ gcc/go/gofrontend/types.cc | 1 + 5 files changed, 66 insertions(+), 2 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 8032c4c6435..9ce86dea723 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -5d0c788cd6099c2bb28bb0ff6a04d94006fbfca8 +267d91b41571329e71a88f56df46444b305482da 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/export.h b/gcc/go/gofrontend/export.h index 3cbf8e16e8c..69fbd6e3bdb 100644 --- a/gcc/go/gofrontend/export.h +++ b/gcc/go/gofrontend/export.h @@ -303,7 +303,7 @@ class Export_function_body : public String_dump { public: Export_function_body(Export* exp, int indent) - : exp_(exp), indent_(indent) + : exp_(exp), type_context_(NULL), indent_(indent) { } // Write a character to the body. @@ -326,6 +326,16 @@ class Export_function_body : public String_dump write_type(const Type* type) { this->exp_->write_type_to(type, this); } + // Return the current type context. + Type* + type_context() const + { return this->type_context_; } + + // Set the current type context. + void + set_type_context(Type* type) + { this->type_context_ = type; } + // Append as many spaces as the current indentation level. void indent() @@ -354,6 +364,8 @@ class Export_function_body : public String_dump Export* exp_; // The body we are building. std::string body_; + // Current type context. Used to avoid duplicate type conversions. + Type* type_context_; // Current indentation level: the number of spaces before each statement. int indent_; }; diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index c33f66989ea..5f00eff5655 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -2142,11 +2142,25 @@ Integer_expression::export_integer(String_dump* exp, const mpz_t val) void Integer_expression::do_export(Export_function_body* efb) const { + bool added_type = false; + if (this->type_ != NULL + && !this->type_->is_abstract() + && this->type_ != efb->type_context()) + { + efb->write_c_string("$convert("); + efb->write_type(this->type_); + efb->write_c_string(", "); + added_type = true; + } + Integer_expression::export_integer(efb, this->val_); if (this->is_character_constant_) efb->write_c_string("'"); // A trailing space lets us reliably identify the end of the number. efb->write_c_string(" "); + + if (added_type) + efb->write_c_string(")"); } // Import an integer, floating point, or complex value. This handles @@ -2509,9 +2523,23 @@ Float_expression::export_float(String_dump *exp, const mpfr_t val) void Float_expression::do_export(Export_function_body* efb) const { + bool added_type = false; + if (this->type_ != NULL + && !this->type_->is_abstract() + && this->type_ != efb->type_context()) + { + efb->write_c_string("$convert("); + efb->write_type(this->type_); + efb->write_c_string(", "); + added_type = true; + } + Float_expression::export_float(efb, this->val_); // A trailing space lets us reliably identify the end of the number. efb->write_c_string(" "); + + if (added_type) + efb->write_c_string(")"); } // Dump a floating point number to the dump file. @@ -2699,9 +2727,23 @@ Complex_expression::export_complex(String_dump* exp, const mpc_t val) void Complex_expression::do_export(Export_function_body* efb) const { + bool added_type = false; + if (this->type_ != NULL + && !this->type_->is_abstract() + && this->type_ != efb->type_context()) + { + efb->write_c_string("$convert("); + efb->write_type(this->type_); + efb->write_c_string(", "); + added_type = true; + } + Complex_expression::export_complex(efb, this->val_); // A trailing space lets us reliably identify the end of the number. efb->write_c_string(" "); + + if (added_type) + efb->write_c_string(")"); } // Dump a complex expression to the dump file. @@ -3620,7 +3662,14 @@ Type_conversion_expression::do_export(Export_function_body* efb) const efb->write_c_string("$convert("); efb->write_type(this->type_); efb->write_c_string(", "); + + Type* old_context = efb->type_context(); + efb->set_type_context(this->type_); + this->expr_->export_expression(efb); + + efb->set_type_context(old_context); + efb->write_c_string(")"); } diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index e4bd39d7042..5654e30849d 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -7635,6 +7635,8 @@ Named_constant::export_const(Export* exp, const std::string& name) const exp->write_c_string("= "); Export_function_body efb(exp, 0); + if (!this->type_->is_abstract()) + efb.set_type_context(this->type_); this->expr()->export_expression(&efb); exp->write_string(efb.body()); diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 38c7f172335..a50156c2a2b 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -7552,6 +7552,7 @@ Array_type::do_export(Export* exp) const if (this->length_ != NULL) { Export_function_body efb(exp, 0); + efb.set_type_context(this->length_->type()); this->length_->export_expression(&efb); exp->write_string(efb.body()); } -- 2.30.2