Go patch committed: turn global "a = b; b = x' to "a = x" when possible

Message ID CAOyqgcVTPWAen1ErjE6LPrWjOi7TSE9FcDYos4jtPoWNxkmtLQ@mail.gmail.com
State New
Headers show
Series
  • Go patch committed: turn global "a = b; b = x' to "a = x" when possible
Related show

Commit Message

xionghu luo via Gcc-patches July 28, 2020, 12:03 a.m.
This patch to the Go frontend changes package-scope "a = b; b = x" to
just set "a = x".  This avoids requiring an init function to
initialize the variable.  This can only be done if x is a static
initializer.

The go1.15rc1 runtime package relies on this optimization.  The
package has a variable "var maxSearchAddr = maxOffAddr".  The
maxSearchAddr variable is used by code that runs before package
initialization is complete.

Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu.  Committed
to mainline.

Ian
2b29792a4c40cde1f5a5d0858234162258d7c1b3

Patch

diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 0fa32a43489..12e48c19932 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@ 
-e86f2cb5d6b1984fde345d6ade605e377fa38c04
+8b9c7fb00ccaf1d4bcc8d581a1a4d46a35771b77
 
 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/gogo.cc b/gcc/go/gofrontend/gogo.cc
index c1021e5679c..4c8c55fcb14 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -1622,16 +1622,31 @@  Gogo::write_globals()
               // The initializer is constant if it is the zero-value of the
               // variable's type or if the initial value is an immutable value
               // that is not copied to the heap.
-              bool is_static_initializer = false;
-              if (var->init() == NULL)
+	      Expression* init = var->init();
+
+	      // If we see "a = b; b = x", and x is a static
+	      // initializer, just set a to x.
+	      while (init != NULL && init->var_expression() != NULL)
+		{
+		  Named_object* ino = init->var_expression()->named_object();
+		  if (!ino->is_variable() || ino->package() != NULL)
+		    break;
+		  Expression* ino_init = ino->var_value()->init();
+		  if (ino->var_value()->has_pre_init()
+		      || ino_init == NULL
+		      || !ino_init->is_static_initializer())
+		    break;
+		  init = ino_init;
+		}
+
+              bool is_static_initializer;
+              if (init == NULL)
                 is_static_initializer = true;
               else
                 {
                   Type* var_type = var->type();
-                  Expression* init = var->init();
-                  Expression* init_cast =
-                      Expression::make_cast(var_type, init, var->location());
-                  is_static_initializer = init_cast->is_static_initializer();
+                  init = Expression::make_cast(var_type, init, var->location());
+                  is_static_initializer = init->is_static_initializer();
                 }
 
 	      // Non-constant variable initializations might need to create
@@ -1650,7 +1665,15 @@  Gogo::write_globals()
                     }
 		  var_init_fn = init_fndecl;
 		}
-              Bexpression* var_binit = var->get_init(this, var_init_fn);
+
+	      Bexpression* var_binit;
+	      if (init == NULL)
+		var_binit = NULL;
+	      else
+		{
+		  Translate_context context(this, var_init_fn, NULL, NULL);
+		  var_binit = init->get_backend(&context);
+		}
 
               if (var_binit == NULL)
 		;