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
This commit is contained in:
parent
da29d2a36e
commit
9b4e458bd7
5 changed files with 66 additions and 2 deletions
|
@ -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.
|
||||
|
|
|
@ -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_;
|
||||
};
|
||||
|
|
|
@ -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(")");
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue