compiler: support inlining functions that use index expressions
authorIan Lance Taylor <ian@gcc.gnu.org>
Mon, 10 Jun 2019 21:34:12 +0000 (21:34 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Mon, 10 Jun 2019 21:34:12 +0000 (21:34 +0000)
    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

gcc/go/gofrontend/MERGE
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/import.cc
gcc/go/gofrontend/statements.cc

index 84c00ae570eb51f4b7f1f9ea2d6fdd41ac26ec0e..d89e8e3e2884a11c23529cb9da6ca6aa37ee3d0a 100644 (file)
@@ -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.
index d82eebd521e1a5eab62ea4b9c8125bfbf7921d41..740daec5f2178e92ae80ea131d517854e6a71e1e 100644 (file)
@@ -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;
     }
index 22dd2fc4c1d3eb8999d20b4ad567293e9419c6d5..1595eb152266871db4596c3a1e7ec64f180592e5 100644 (file)
@@ -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;
 
index 62d687056711f13fe2da012d0e3e90999e1d640e..42a76745925aa6034d86225cc0fdbf40f9696023 100644 (file)
@@ -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);
 }
index 02c1c48191b04b61e1c6edfe690ba28dfaa9d2bb..2d76f75a3de23c7d721b5b4ad0698f1a314bf224 100644 (file)
@@ -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.
 
index 9ab11727fe93851fac03ed5ed714015b0d2c7987..7f424fd7b7af1447f3a012ef813e5ebb0ea38ecc 100644 (file)
@@ -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("{"))