Commit 9b4e458b by Ian Lance Taylor

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
parent da29d2a3
5d0c788cd6099c2bb28bb0ff6a04d94006fbfca8 267d91b41571329e71a88f56df46444b305482da
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -303,7 +303,7 @@ class Export_function_body : public String_dump ...@@ -303,7 +303,7 @@ class Export_function_body : public String_dump
{ {
public: public:
Export_function_body(Export* exp, int indent) Export_function_body(Export* exp, int indent)
: exp_(exp), indent_(indent) : exp_(exp), type_context_(NULL), indent_(indent)
{ } { }
// Write a character to the body. // Write a character to the body.
...@@ -326,6 +326,16 @@ class Export_function_body : public String_dump ...@@ -326,6 +326,16 @@ class Export_function_body : public String_dump
write_type(const Type* type) write_type(const Type* type)
{ this->exp_->write_type_to(type, this); } { 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. // Append as many spaces as the current indentation level.
void void
indent() indent()
...@@ -354,6 +364,8 @@ class Export_function_body : public String_dump ...@@ -354,6 +364,8 @@ class Export_function_body : public String_dump
Export* exp_; Export* exp_;
// The body we are building. // The body we are building.
std::string body_; 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. // Current indentation level: the number of spaces before each statement.
int indent_; int indent_;
}; };
......
...@@ -2142,11 +2142,25 @@ Integer_expression::export_integer(String_dump* exp, const mpz_t val) ...@@ -2142,11 +2142,25 @@ Integer_expression::export_integer(String_dump* exp, const mpz_t val)
void void
Integer_expression::do_export(Export_function_body* efb) const 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_); Integer_expression::export_integer(efb, this->val_);
if (this->is_character_constant_) if (this->is_character_constant_)
efb->write_c_string("'"); efb->write_c_string("'");
// A trailing space lets us reliably identify the end of the number. // A trailing space lets us reliably identify the end of the number.
efb->write_c_string(" "); efb->write_c_string(" ");
if (added_type)
efb->write_c_string(")");
} }
// Import an integer, floating point, or complex value. This handles // 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) ...@@ -2509,9 +2523,23 @@ Float_expression::export_float(String_dump *exp, const mpfr_t val)
void void
Float_expression::do_export(Export_function_body* efb) const 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_); Float_expression::export_float(efb, this->val_);
// A trailing space lets us reliably identify the end of the number. // A trailing space lets us reliably identify the end of the number.
efb->write_c_string(" "); efb->write_c_string(" ");
if (added_type)
efb->write_c_string(")");
} }
// Dump a floating point number to the dump file. // Dump a floating point number to the dump file.
...@@ -2699,9 +2727,23 @@ Complex_expression::export_complex(String_dump* exp, const mpc_t val) ...@@ -2699,9 +2727,23 @@ Complex_expression::export_complex(String_dump* exp, const mpc_t val)
void void
Complex_expression::do_export(Export_function_body* efb) const 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_); Complex_expression::export_complex(efb, this->val_);
// A trailing space lets us reliably identify the end of the number. // A trailing space lets us reliably identify the end of the number.
efb->write_c_string(" "); efb->write_c_string(" ");
if (added_type)
efb->write_c_string(")");
} }
// Dump a complex expression to the dump file. // Dump a complex expression to the dump file.
...@@ -3620,7 +3662,14 @@ Type_conversion_expression::do_export(Export_function_body* efb) const ...@@ -3620,7 +3662,14 @@ Type_conversion_expression::do_export(Export_function_body* efb) const
efb->write_c_string("$convert("); efb->write_c_string("$convert(");
efb->write_type(this->type_); efb->write_type(this->type_);
efb->write_c_string(", "); efb->write_c_string(", ");
Type* old_context = efb->type_context();
efb->set_type_context(this->type_);
this->expr_->export_expression(efb); this->expr_->export_expression(efb);
efb->set_type_context(old_context);
efb->write_c_string(")"); efb->write_c_string(")");
} }
......
...@@ -7635,6 +7635,8 @@ Named_constant::export_const(Export* exp, const std::string& name) const ...@@ -7635,6 +7635,8 @@ Named_constant::export_const(Export* exp, const std::string& name) const
exp->write_c_string("= "); exp->write_c_string("= ");
Export_function_body efb(exp, 0); Export_function_body efb(exp, 0);
if (!this->type_->is_abstract())
efb.set_type_context(this->type_);
this->expr()->export_expression(&efb); this->expr()->export_expression(&efb);
exp->write_string(efb.body()); exp->write_string(efb.body());
......
...@@ -7552,6 +7552,7 @@ Array_type::do_export(Export* exp) const ...@@ -7552,6 +7552,7 @@ Array_type::do_export(Export* exp) const
if (this->length_ != NULL) if (this->length_ != NULL)
{ {
Export_function_body efb(exp, 0); Export_function_body efb(exp, 0);
efb.set_type_context(this->length_->type());
this->length_->export_expression(&efb); this->length_->export_expression(&efb);
exp->write_string(efb.body()); exp->write_string(efb.body());
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment