Go patch committed: Support inlining functions that use index expressions

Ian Lance Taylor iant@golang.org
Mon Jun 10 21:34:00 GMT 2019


This patch to the Go frontend supports inlining functions that use
index expressions.  It also moves 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.  Bootstrapped and ran
Go testsuite on x86_64-pc-linux-gnu.  Committed to mainline.

Ian
-------------- next part --------------
Index: gcc/go/gofrontend/MERGE
===================================================================
--- gcc/go/gofrontend/MERGE	(revision 272132)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -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: gcc/go/gofrontend/expressions.cc
===================================================================
--- gcc/go/gofrontend/expressions.cc	(revision 272132)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -7110,6 +7110,12 @@ Binary_expression::do_import(Import_expr
       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(T
   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(
 						 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(
   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_exp
 	  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: gcc/go/gofrontend/expressions.h
===================================================================
--- gcc/go/gofrontend/expressions.h	(revision 272127)
+++ gcc/go/gofrontend/expressions.h	(working copy)
@@ -3089,6 +3089,13 @@ class Array_index_expression : public Ex
   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 E
   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 Expr
   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: gcc/go/gofrontend/gogo.cc
===================================================================
--- gcc/go/gofrontend/gogo.cc	(revision 272132)
+++ gcc/go/gofrontend/gogo.cc	(working copy)
@@ -7282,6 +7282,7 @@ Function_declaration::import_function_bo
     return;
 
   gogo->lower_block(no, outer);
+  outer->determine_types();
 
   gogo->add_imported_inline_function(no);
 }
Index: gcc/go/gofrontend/import.cc
===================================================================
--- gcc/go/gofrontend/import.cc	(revision 272131)
+++ gcc/go/gofrontend/import.cc	(working copy)
@@ -1238,7 +1238,7 @@ Import::register_builtin_type(Gogo* gogo
 // 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: gcc/go/gofrontend/statements.cc
===================================================================
--- gcc/go/gofrontend/statements.cc	(revision 272131)
+++ gcc/go/gofrontend/statements.cc	(working copy)
@@ -465,8 +465,6 @@ Variable_declaration_statement::do_impor
     {
       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_fu
     {
       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_
   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("{"))


More information about the Gcc-patches mailing list