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:
parent
cd6437427d
commit
93d2b7038d
@ -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.
|
||||
|
@ -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())
|
||||
|
@ -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.
|
||||
|
@ -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*);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user