compiler: record final type for numeric expressions
authorIan Lance Taylor <ian@gcc.gnu.org>
Tue, 27 Nov 2018 23:29:15 +0000 (23:29 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 27 Nov 2018 23:29:15 +0000 (23:29 +0000)
    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
gcc/go/gofrontend/export.h
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/types.cc

index 8032c4c6435185e5e39443dc8eed7700e340a25c..9ce86dea723bf042d44fe6a9832328adf33773af 100644 (file)
@@ -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.
index 3cbf8e16e8cee18a33573649ff2f7dac7b77aff5..69fbd6e3bdb1a5e73d4d1382a1b42e31994aa9d2 100644 (file)
@@ -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_;
 };
index c33f66989eaebbe0bbf2138e2056186bd0c3b0ee..5f00eff5655f6955c901b628fa52b787855a6513 100644 (file)
@@ -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(")");
 }
 
index e4bd39d70423aa4f29fbcc14c69f1f04c8a91d85..5654e30849d3bde6b321d16437d5df91e88465a1 100644 (file)
@@ -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());
 
index 38c7f1723355ddd548c60b0198a470b308a92e51..a50156c2a2bafac9f45a09bb70e2ef1bec6bbcfc 100644 (file)
@@ -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());
     }