aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-11-27 23:29:15 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-11-27 23:29:15 +0000
commit9b4e458bd7a31b288e5c944cd27419a7f434367e (patch)
tree64a5c3a3eacb60fdeed40da0d460c6c6a27647f0 /gcc
parentda29d2a36ef4bc2d6459267ce21ac932ddfbad6a (diff)
downloadgcc-9b4e458bd7a31b288e5c944cd27419a7f434367e.zip
gcc-9b4e458bd7a31b288e5c944cd27419a7f434367e.tar.gz
gcc-9b4e458bd7a31b288e5c944cd27419a7f434367e.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/export.h14
-rw-r--r--gcc/go/gofrontend/expressions.cc49
-rw-r--r--gcc/go/gofrontend/gogo.cc2
-rw-r--r--gcc/go/gofrontend/types.cc1
5 files changed, 66 insertions, 2 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 8032c4c..9ce86de 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 3cbf8e1..69fbd6e 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 c33f669..5f00eff 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 e4bd39d..5654e30 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 38c7f17..a50156c 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());
}