diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-06-10 21:34:12 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-06-10 21:34:12 +0000 |
commit | e898243c23c82247ec01b32f551402ca52f32927 (patch) | |
tree | b0d9c35dc562318a0568ad5a47888711864bc4c1 /gcc | |
parent | 35c19de69645b18eeef7dbecfcd98b19f9948c84 (diff) | |
download | gcc-e898243c23c82247ec01b32f551402ca52f32927.zip gcc-e898243c23c82247ec01b32f551402ca52f32927.tar.gz gcc-e898243c23c82247ec01b32f551402ca52f32927.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 105 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 21 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 1 | ||||
-rw-r--r-- | gcc/go/gofrontend/import.cc | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 9 |
6 files changed, 129 insertions, 11 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 84c00ae..d89e8e3 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -764fe6702f2bb8650622d4102de31058e484ecb5 +b1ae35965cadac235d7d218e689944286cccdd90 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index d82eebd..740daec 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -7110,6 +7110,12 @@ Binary_expression::do_import(Import_expression* imp, Location loc) op = OPERATOR_BITCLEAR; imp->advance(4); } + else if (imp->match_c_string(")")) + { + // Not a binary operator after all. + imp->advance(1); + return left; + } else { go_error_at(imp->location(), "unrecognized binary operator"); @@ -12808,6 +12814,38 @@ Array_index_expression::do_get_backend(Translate_context* context) 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. void @@ -13068,6 +13106,31 @@ String_index_expression::do_get_backend(Translate_context* context) 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. void @@ -13338,6 +13401,25 @@ Map_index_expression::get_value_pointer(Gogo* gogo) 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 void @@ -17974,6 +18056,29 @@ Expression::import_expression(Import_expression* imp, Location loc) imp->require_c_string(")"); 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 break; } diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 22dd2fc..1595eb1 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -3089,6 +3089,13 @@ class Array_index_expression : public Expression Bexpression* do_get_backend(Translate_context*); + int + do_inlining_cost() const + { return this->end_ != NULL ? 2 : 1; } + + void + do_export(Export_function_body*) const; + void do_dump_expression(Ast_dump_context*) const; @@ -3161,6 +3168,13 @@ class String_index_expression : public Expression Bexpression* do_get_backend(Translate_context*); + int + do_inlining_cost() const + { return this->end_ != NULL ? 2 : 1; } + + void + do_export(Export_function_body*) const; + void do_dump_expression(Ast_dump_context*) const; @@ -3247,6 +3261,13 @@ class Map_index_expression : public Expression Bexpression* do_get_backend(Translate_context*); + int + do_inlining_cost() const + { return 5; } + + void + do_export(Export_function_body*) const; + void do_dump_expression(Ast_dump_context*) const; diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 62d6870..42a7674 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -7282,6 +7282,7 @@ Function_declaration::import_function_body(Gogo* gogo, Named_object* no) return; gogo->lower_block(no, outer); + outer->determine_types(); gogo->add_imported_inline_function(no); } diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc index 02c1c48..2d76f75 100644 --- a/gcc/go/gofrontend/import.cc +++ b/gcc/go/gofrontend/import.cc @@ -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 are permitted in an identifier. That lets us skip // UTF-8 parsing. -static const char * const identifier_stop = " \n;,()[]"; +static const char * const identifier_stop = " \n;:,()[]"; // Read an identifier from the stream. diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 9ab1172..7f424fd 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -465,8 +465,6 @@ Variable_declaration_statement::do_import(Import_function_body* ifb, { 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(); @@ -753,11 +751,6 @@ Temporary_statement::do_import(Import_function_body* ifb, Location loc) { ifb->advance(3); init = Expression::import_expression(ifb, loc); - if (type != NULL) - { - Type_context context(type, false); - init->determine_type(&context); - } } if (type == NULL && init == NULL) { @@ -3730,8 +3723,6 @@ If_statement::do_import(Import_function_body* ifb, Location loc) ifb->require_c_string("if "); Expression* cond = Expression::import_expression(ifb, loc); - Type_context context(Type::lookup_bool_type(), false); - cond->determine_type(&context); ifb->require_c_string(" "); if (!ifb->match_c_string("{")) |