Commit e898243c by Ian Lance Taylor

compiler: support inlining functions that use index expressions

    
    Also move the determine_types pass on an inlined function body to one
    place, rather than doing it ad hoc as needed.
    
    This adds 79 new inlinable functions in the standard library, such as
    bytes.HasPrefix and bytes.LastIndexByte.
    
    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/181261

From-SVN: r272133
parent 35c19de6
764fe6702f2bb8650622d4102de31058e484ecb5 b1ae35965cadac235d7d218e689944286cccdd90
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.
...@@ -7110,6 +7110,12 @@ Binary_expression::do_import(Import_expression* imp, Location loc) ...@@ -7110,6 +7110,12 @@ Binary_expression::do_import(Import_expression* imp, Location loc)
op = OPERATOR_BITCLEAR; op = OPERATOR_BITCLEAR;
imp->advance(4); imp->advance(4);
} }
else if (imp->match_c_string(")"))
{
// Not a binary operator after all.
imp->advance(1);
return left;
}
else else
{ {
go_error_at(imp->location(), "unrecognized binary operator"); go_error_at(imp->location(), "unrecognized binary operator");
...@@ -12808,6 +12814,38 @@ Array_index_expression::do_get_backend(Translate_context* context) ...@@ -12808,6 +12814,38 @@ Array_index_expression::do_get_backend(Translate_context* context)
return ret; return ret;
} }
// Export an array index expression.
void
Array_index_expression::do_export(Export_function_body* efb) const
{
efb->write_c_string("(");
this->array_->export_expression(efb);
efb->write_c_string(")[");
Type* old_context = efb->type_context();
efb->set_type_context(Type::lookup_integer_type("int"));
this->start_->export_expression(efb);
if (this->end_ == NULL)
go_assert(this->cap_ == NULL);
else
{
efb->write_c_string(":");
if (!this->end_->is_nil_expression())
this->end_->export_expression(efb);
if (this->cap_ != NULL)
{
efb->write_c_string(":");
this->cap_->export_expression(efb);
}
}
efb->set_type_context(old_context);
efb->write_c_string("]");
}
// Dump ast representation for an array index expression. // Dump ast representation for an array index expression.
void void
...@@ -13068,6 +13106,31 @@ String_index_expression::do_get_backend(Translate_context* context) ...@@ -13068,6 +13106,31 @@ String_index_expression::do_get_backend(Translate_context* context)
crash, bstrslice, loc); crash, bstrslice, loc);
} }
// Export a string index expression.
void
String_index_expression::do_export(Export_function_body* efb) const
{
efb->write_c_string("(");
this->string_->export_expression(efb);
efb->write_c_string(")[");
Type* old_context = efb->type_context();
efb->set_type_context(Type::lookup_integer_type("int"));
this->start_->export_expression(efb);
if (this->end_ != NULL)
{
efb->write_c_string(":");
if (!this->end_->is_nil_expression())
this->end_->export_expression(efb);
}
efb->set_type_context(old_context);
efb->write_c_string("]");
}
// Dump ast representation for a string index expression. // Dump ast representation for a string index expression.
void void
...@@ -13338,6 +13401,25 @@ Map_index_expression::get_value_pointer(Gogo* gogo) ...@@ -13338,6 +13401,25 @@ Map_index_expression::get_value_pointer(Gogo* gogo)
return this->value_pointer_; return this->value_pointer_;
} }
// Export a map index expression.
void
Map_index_expression::do_export(Export_function_body* efb) const
{
efb->write_c_string("(");
this->map_->export_expression(efb);
efb->write_c_string(")[");
Type* old_context = efb->type_context();
efb->set_type_context(this->get_map_type()->key_type());
this->index_->export_expression(efb);
efb->set_type_context(old_context);
efb->write_c_string("]");
}
// Dump ast representation for a map index expression // Dump ast representation for a map index expression
void void
...@@ -17974,6 +18056,29 @@ Expression::import_expression(Import_expression* imp, Location loc) ...@@ -17974,6 +18056,29 @@ Expression::import_expression(Import_expression* imp, Location loc)
imp->require_c_string(")"); imp->require_c_string(")");
expr = Expression::make_call(expr, args, is_varargs, loc); expr = Expression::make_call(expr, args, is_varargs, loc);
} }
else if (imp->match_c_string("["))
{
imp->advance(1);
Expression* start = Expression::import_expression(imp, loc);
Expression* end = NULL;
Expression* cap = NULL;
if (imp->match_c_string(":"))
{
imp->advance(1);
int c = imp->peek_char();
if (c == ':' || c == ']')
end = Expression::make_nil(loc);
else
end = Expression::import_expression(imp, loc);
if (imp->match_c_string(":"))
{
imp->advance(1);
cap = Expression::import_expression(imp, loc);
}
}
imp->require_c_string("]");
expr = Expression::make_index(expr, start, end, cap, loc);
}
else else
break; break;
} }
......
...@@ -3089,6 +3089,13 @@ class Array_index_expression : public Expression ...@@ -3089,6 +3089,13 @@ class Array_index_expression : public Expression
Bexpression* Bexpression*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
int
do_inlining_cost() const
{ return this->end_ != NULL ? 2 : 1; }
void
do_export(Export_function_body*) const;
void void
do_dump_expression(Ast_dump_context*) const; do_dump_expression(Ast_dump_context*) const;
...@@ -3161,6 +3168,13 @@ class String_index_expression : public Expression ...@@ -3161,6 +3168,13 @@ class String_index_expression : public Expression
Bexpression* Bexpression*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
int
do_inlining_cost() const
{ return this->end_ != NULL ? 2 : 1; }
void
do_export(Export_function_body*) const;
void void
do_dump_expression(Ast_dump_context*) const; do_dump_expression(Ast_dump_context*) const;
...@@ -3247,6 +3261,13 @@ class Map_index_expression : public Expression ...@@ -3247,6 +3261,13 @@ class Map_index_expression : public Expression
Bexpression* Bexpression*
do_get_backend(Translate_context*); do_get_backend(Translate_context*);
int
do_inlining_cost() const
{ return 5; }
void
do_export(Export_function_body*) const;
void void
do_dump_expression(Ast_dump_context*) const; do_dump_expression(Ast_dump_context*) const;
......
...@@ -7282,6 +7282,7 @@ Function_declaration::import_function_body(Gogo* gogo, Named_object* no) ...@@ -7282,6 +7282,7 @@ Function_declaration::import_function_body(Gogo* gogo, Named_object* no)
return; return;
gogo->lower_block(no, outer); gogo->lower_block(no, outer);
outer->determine_types();
gogo->add_imported_inline_function(no); gogo->add_imported_inline_function(no);
} }
......
...@@ -1238,7 +1238,7 @@ Import::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code) ...@@ -1238,7 +1238,7 @@ Import::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code)
// characters that stop an identifier, without worrying about // characters that stop an identifier, without worrying about
// characters that are permitted in an identifier. That lets us skip // characters that are permitted in an identifier. That lets us skip
// UTF-8 parsing. // UTF-8 parsing.
static const char * const identifier_stop = " \n;,()[]"; static const char * const identifier_stop = " \n;:,()[]";
// Read an identifier from the stream. // Read an identifier from the stream.
......
...@@ -465,8 +465,6 @@ Variable_declaration_statement::do_import(Import_function_body* ifb, ...@@ -465,8 +465,6 @@ Variable_declaration_statement::do_import(Import_function_body* ifb,
{ {
ifb->advance(3); ifb->advance(3);
init = Expression::import_expression(ifb, loc); 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); Variable* var = new Variable(type, init, false, false, false, loc);
var->set_is_used(); var->set_is_used();
...@@ -753,11 +751,6 @@ Temporary_statement::do_import(Import_function_body* ifb, Location loc) ...@@ -753,11 +751,6 @@ Temporary_statement::do_import(Import_function_body* ifb, Location loc)
{ {
ifb->advance(3); ifb->advance(3);
init = Expression::import_expression(ifb, loc); init = Expression::import_expression(ifb, loc);
if (type != NULL)
{
Type_context context(type, false);
init->determine_type(&context);
}
} }
if (type == NULL && init == NULL) if (type == NULL && init == NULL)
{ {
...@@ -3730,8 +3723,6 @@ If_statement::do_import(Import_function_body* ifb, Location loc) ...@@ -3730,8 +3723,6 @@ If_statement::do_import(Import_function_body* ifb, Location loc)
ifb->require_c_string("if "); ifb->require_c_string("if ");
Expression* cond = Expression::import_expression(ifb, loc); Expression* cond = Expression::import_expression(ifb, loc);
Type_context context(Type::lookup_bool_type(), false);
cond->determine_type(&context);
ifb->require_c_string(" "); ifb->require_c_string(" ");
if (!ifb->match_c_string("{")) if (!ifb->match_c_string("{"))
......
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