compiler: permit inlining variable declaration statements

This adds all of two inlinable functions to the standard library:
    crypto/subtle.ConstantTimeLessOrEq, regexp.(*Regexp).Copy.
    
    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/176378

From-SVN: r271063
This commit is contained in:
Ian Lance Taylor 2019-05-10 13:44:36 +00:00
parent cd6437427d
commit 93d2b7038d
4 changed files with 71 additions and 9 deletions

View File

@ -1,4 +1,4 @@
3dbf51c01c5d0acbf9ae47f77166fa9935881749
b5e4ba88a2e7f3c34e9183f43370c38ea639c393
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.

View File

@ -843,14 +843,14 @@ Var_expression::do_address_taken(bool escapes)
}
// The cost to inline a variable reference. We currently only support
// references to parameters.
// references to parameters and local variables.
int
Var_expression::do_inlining_cost() const
{
if (this->variable_->is_variable())
{
if (this->variable_->var_value()->is_parameter())
if (!this->variable_->var_value()->is_global())
return 1;
}
else if (this->variable_->is_result_variable())

View File

@ -155,6 +155,8 @@ Statement::import_statement(Import_function_body* ifb, Location loc)
ifb->advance(6);
return Statement::make_return_statement(NULL, loc);
}
else if (ifb->match_c_string("var "))
return Variable_declaration_statement::do_import(ifb, loc);
Expression* lhs = Expression::import_expression(ifb, loc);
ifb->require_c_string(" = ");
@ -408,6 +410,57 @@ Statement::make_variable_declaration(Named_object* var)
return new Variable_declaration_statement(var);
}
// Export a variable declaration.
void
Variable_declaration_statement::do_export_statement(Export_function_body* efb)
{
efb->write_c_string("var ");
efb->write_string(Gogo::unpack_hidden_name(this->var_->name()));
efb->write_c_string(" ");
Variable* var = this->var_->var_value();
Type* type = var->type();
efb->write_type(type);
Expression* init = var->init();
if (init != NULL)
{
efb->write_c_string(" = ");
go_assert(efb->type_context() == NULL);
efb->set_type_context(type);
init->export_expression(efb);
efb->set_type_context(NULL);
}
}
// Import a variable declaration.
Statement*
Variable_declaration_statement::do_import(Import_function_body* ifb,
Location loc)
{
ifb->require_c_string("var ");
std::string id = ifb->read_identifier();
ifb->require_c_string(" ");
Type* type = ifb->read_type();
Expression* init = NULL;
if (ifb->match_c_string(" = "))
{
ifb->advance(3);
init = Expression::import_expression(ifb, loc);
Type_context context(type, false);
init->determine_type(&context);
}
Variable* var = new Variable(type, init, false, false, false, loc);
var->set_is_used();
// FIXME: The package we are importing does not yet exist, so we
// can't pass the correct package here. It probably doesn't matter.
Named_object* no = ifb->block()->bindings()->add_variable(id, NULL, var);
return Statement::make_variable_declaration(no);
}
// Class Temporary_statement.
// Return the type of the temporary variable.

View File

@ -16,6 +16,7 @@ class Block;
class Function;
class Unnamed_label;
class Export_function_body;
class Import_function_body;
class Assignment_statement;
class Temporary_statement;
class Variable_declaration_statement;
@ -332,8 +333,7 @@ class Statement
inlining_cost()
{ return this->do_inlining_cost(); }
// Export data for this statement to BODY. INDENT is an indentation
// level used if the export data requires multiple lines.
// Export data for this statement to BODY.
void
export_statement(Export_function_body* efb)
{ this->do_export_statement(efb); }
@ -514,10 +514,8 @@ class Statement
{ return 0x100000; }
// Implemented by child class: write export data for this statement
// to the string. The integer is an indentation level used if the
// export data requires multiple lines. This need only be
// implemented by classes that implement do_inlining_cost with a
// reasonable value.
// to the string. This need only be implemented by classes that
// implement do_inlining_cost with a reasonable value.
virtual void
do_export_statement(Export_function_body*)
{ go_unreachable(); }
@ -746,6 +744,10 @@ class Variable_declaration_statement : public Statement
var()
{ return this->var_; }
// Import a variable declaration.
static Statement*
do_import(Import_function_body*, Location);
protected:
int
do_traverse(Traverse*);
@ -756,6 +758,13 @@ class Variable_declaration_statement : public Statement
Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
int
do_inlining_cost()
{ return 1; }
void
do_export_statement(Export_function_body*);
Statement*
do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);