Commit 93d2b703 by Ian Lance Taylor

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
parent cd643742
3dbf51c01c5d0acbf9ae47f77166fa9935881749 b5e4ba88a2e7f3c34e9183f43370c38ea639c393
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.
...@@ -843,14 +843,14 @@ Var_expression::do_address_taken(bool escapes) ...@@ -843,14 +843,14 @@ Var_expression::do_address_taken(bool escapes)
} }
// The cost to inline a variable reference. We currently only support // The cost to inline a variable reference. We currently only support
// references to parameters. // references to parameters and local variables.
int int
Var_expression::do_inlining_cost() const Var_expression::do_inlining_cost() const
{ {
if (this->variable_->is_variable()) if (this->variable_->is_variable())
{ {
if (this->variable_->var_value()->is_parameter()) if (!this->variable_->var_value()->is_global())
return 1; return 1;
} }
else if (this->variable_->is_result_variable()) else if (this->variable_->is_result_variable())
......
...@@ -155,6 +155,8 @@ Statement::import_statement(Import_function_body* ifb, Location loc) ...@@ -155,6 +155,8 @@ Statement::import_statement(Import_function_body* ifb, Location loc)
ifb->advance(6); ifb->advance(6);
return Statement::make_return_statement(NULL, loc); 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); Expression* lhs = Expression::import_expression(ifb, loc);
ifb->require_c_string(" = "); ifb->require_c_string(" = ");
...@@ -408,6 +410,57 @@ Statement::make_variable_declaration(Named_object* var) ...@@ -408,6 +410,57 @@ Statement::make_variable_declaration(Named_object* var)
return new Variable_declaration_statement(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. // Class Temporary_statement.
// Return the type of the temporary variable. // Return the type of the temporary variable.
......
...@@ -16,6 +16,7 @@ class Block; ...@@ -16,6 +16,7 @@ class Block;
class Function; class Function;
class Unnamed_label; class Unnamed_label;
class Export_function_body; class Export_function_body;
class Import_function_body;
class Assignment_statement; class Assignment_statement;
class Temporary_statement; class Temporary_statement;
class Variable_declaration_statement; class Variable_declaration_statement;
...@@ -332,8 +333,7 @@ class Statement ...@@ -332,8 +333,7 @@ class Statement
inlining_cost() inlining_cost()
{ return this->do_inlining_cost(); } { return this->do_inlining_cost(); }
// Export data for this statement to BODY. INDENT is an indentation // Export data for this statement to BODY.
// level used if the export data requires multiple lines.
void void
export_statement(Export_function_body* efb) export_statement(Export_function_body* efb)
{ this->do_export_statement(efb); } { this->do_export_statement(efb); }
...@@ -514,10 +514,8 @@ class Statement ...@@ -514,10 +514,8 @@ class Statement
{ return 0x100000; } { return 0x100000; }
// Implemented by child class: write export data for this statement // Implemented by child class: write export data for this statement
// to the string. The integer is an indentation level used if the // to the string. This need only be implemented by classes that
// export data requires multiple lines. This need only be // implement do_inlining_cost with a reasonable value.
// implemented by classes that implement do_inlining_cost with a
// reasonable value.
virtual void virtual void
do_export_statement(Export_function_body*) do_export_statement(Export_function_body*)
{ go_unreachable(); } { go_unreachable(); }
...@@ -746,6 +744,10 @@ class Variable_declaration_statement : public Statement ...@@ -746,6 +744,10 @@ class Variable_declaration_statement : public Statement
var() var()
{ return this->var_; } { return this->var_; }
// Import a variable declaration.
static Statement*
do_import(Import_function_body*, Location);
protected: protected:
int int
do_traverse(Traverse*); do_traverse(Traverse*);
...@@ -756,6 +758,13 @@ class Variable_declaration_statement : public Statement ...@@ -756,6 +758,13 @@ class Variable_declaration_statement : public Statement
Statement* Statement*
do_lower(Gogo*, Named_object*, Block*, Statement_inserter*); do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
int
do_inlining_cost()
{ return 1; }
void
do_export_statement(Export_function_body*);
Statement* Statement*
do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*); do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);
......
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