Go patch committed: Permit inlining variable declaration statements

Ian Lance Taylor iant@golang.org
Fri May 10 13:44:00 GMT 2019


This patch to the Go frontend permits inlining variable declaration
statements.  This adds all of two inlinable functions to the standard
library: crypto/subtle.ConstantTimeLessOrEq, regexp.(*Regexp).Copy.
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 271044)
+++ gcc/go/gofrontend/MERGE	(working copy)
@@ -1,4 +1,4 @@
-3dbf51c01c5d0acbf9ae47f77166fa9935881749
+b5e4ba88a2e7f3c34e9183f43370c38ea639c393
 
 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 271044)
+++ gcc/go/gofrontend/expressions.cc	(working copy)
@@ -843,14 +843,14 @@ Var_expression::do_address_taken(bool es
 }
 
 // The cost to inline a variable reference.  We currently only support
-// references to parameters.
+// references to parameters and local variables.
 
 int
 Var_expression::do_inlining_cost() const
 {
   if (this->variable_->is_variable())
     {
-      if (this->variable_->var_value()->is_parameter())
+      if (!this->variable_->var_value()->is_global())
 	return 1;
     }
   else if (this->variable_->is_result_variable())
Index: gcc/go/gofrontend/statements.cc
===================================================================
--- gcc/go/gofrontend/statements.cc	(revision 271044)
+++ gcc/go/gofrontend/statements.cc	(working copy)
@@ -155,6 +155,8 @@ Statement::import_statement(Import_funct
       ifb->advance(6);
       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);
   ifb->require_c_string(" = ");
@@ -408,6 +410,57 @@ Statement::make_variable_declaration(Nam
   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.
 
 // Return the type of the temporary variable.
Index: gcc/go/gofrontend/statements.h
===================================================================
--- gcc/go/gofrontend/statements.h	(revision 270877)
+++ gcc/go/gofrontend/statements.h	(working copy)
@@ -16,6 +16,7 @@ class Block;
 class Function;
 class Unnamed_label;
 class Export_function_body;
+class Import_function_body;
 class Assignment_statement;
 class Temporary_statement;
 class Variable_declaration_statement;
@@ -332,8 +333,7 @@ class Statement
   inlining_cost()
   { return this->do_inlining_cost(); }
 
-  // Export data for this statement to BODY.  INDENT is an indentation
-  // level used if the export data requires multiple lines.
+  // Export data for this statement to BODY.
   void
   export_statement(Export_function_body* efb)
   { this->do_export_statement(efb); }
@@ -514,10 +514,8 @@ class Statement
   { return 0x100000; }
 
   // Implemented by child class: write export data for this statement
-  // to the string.  The integer is an indentation level used if the
-  // export data requires multiple lines.  This need only be
-  // implemented by classes that implement do_inlining_cost with a
-  // reasonable value.
+  // to the string.  This need only be implemented by classes that
+  // implement do_inlining_cost with a reasonable value.
   virtual void
   do_export_statement(Export_function_body*)
   { go_unreachable(); }
@@ -746,6 +744,10 @@ class Variable_declaration_statement : p
   var()
   { return this->var_; }
 
+  // Import a variable declaration.
+  static Statement*
+  do_import(Import_function_body*, Location);
+
  protected:
   int
   do_traverse(Traverse*);
@@ -756,6 +758,13 @@ class Variable_declaration_statement : p
   Statement*
   do_lower(Gogo*, Named_object*, Block*, Statement_inserter*);
 
+  int
+  do_inlining_cost()
+  { return 1; }
+
+  void
+  do_export_statement(Export_function_body*);
+
   Statement*
   do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);
 


More information about the Gcc-patches mailing list