compiler: add an option to emit optimization diagnostics
authorCherry Zhang <cherryyz@google.com>
Wed, 8 May 2019 00:14:17 +0000 (00:14 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 8 May 2019 00:14:17 +0000 (00:14 +0000)
    Add a -fgo-debug-optimization option to emit optimization
    diagnostics. This can be used for testing optimizations. Apply
    this to the range clear optimizations of maps and arrays.

    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/170002

gcc/go:

* lang.opt (-fgo-debug-optimization): New option.
* go-c.h (struct go_create_gogo_args): Add debug_optimization
field.
* go-lang.c (go_langhook_init): Set debug_optimization field.
* gccgo.texi (Invoking gccgo): Document -fgo-debug-optimization.

gcc/testsuite:

* go.dg/arrayclear.go: New test.
* go.dg/mapclear.go: New test.

From-SVN: r270993

13 files changed:
gcc/go/ChangeLog
gcc/go/gccgo.texi
gcc/go/go-c.h
gcc/go/go-lang.c
gcc/go/gofrontend/MERGE
gcc/go/gofrontend/go.cc
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/gogo.h
gcc/go/gofrontend/statements.cc
gcc/go/lang.opt
gcc/testsuite/ChangeLog
gcc/testsuite/go.dg/arrayclear.go [new file with mode: 0644]
gcc/testsuite/go.dg/mapclear.go [new file with mode: 0644]

index 2c88593b05b5915840125832aa8892c7d4c08c0b..a73072f2546e5892e9f476292ca84cd151b59744 100644 (file)
@@ -1,3 +1,11 @@
+2019-05-07  Cherry Zhang  <cherryyz@google.com>
+
+       * lang.opt (-fgo-debug-optimization): New option.
+       * go-c.h (struct go_create_gogo_args): Add debug_optimization
+       field.
+       * go-lang.c (go_langhook_init): Set debug_optimization field.
+       * gccgo.texi (Invoking gccgo): Document -fgo-debug-optimization.
+
 2019-03-06  Ian Lance Taylor  <iant@golang.org>
 
        PR go/89227
 2019-03-06  Ian Lance Taylor  <iant@golang.org>
 
        PR go/89227
index 231019541998ca2840abde79db8e8dd983d945f6..92fd74501ec9a5ed9ed02d4592c0195ab28cfc6b 100644 (file)
@@ -246,6 +246,11 @@ This runs escape analysis only on functions whose names hash to values
 that match the given suffix @var{n}.  This can be used to binary
 search across functions to uncover escape analysis bugs.
 
 that match the given suffix @var{n}.  This can be used to binary
 search across functions to uncover escape analysis bugs.
 
+@item -fgo-debug-optimization
+@cindex @option{-fgo-debug-optimization}
+@cindex @option{-fno-go-debug-optimization}
+Output optimization diagnostics.
+
 @item -fgo-c-header=@var{file}
 @cindex @option{-fgo-c-header}
 Write top-level named Go struct definitions to @var{file} as C code.
 @item -fgo-c-header=@var{file}
 @cindex @option{-fgo-c-header}
 Write top-level named Go struct definitions to @var{file} as C code.
index 42e86cd335843040485cd0451cf27f4a29dfc205..695484cb84f08eaa2f90ff7119f0d8489b13c206 100644 (file)
@@ -49,6 +49,7 @@ struct go_create_gogo_args
   int debug_escape_level;
   const char* debug_escape_hash;
   int64_t nil_check_size_threshold;
   int debug_escape_level;
   const char* debug_escape_hash;
   int64_t nil_check_size_threshold;
+  bool debug_optimization;
 };
 
 extern void go_create_gogo (const struct go_create_gogo_args*);
 };
 
 extern void go_create_gogo (const struct go_create_gogo_args*);
index dd22fdab33fe288f3734f439f5ef339fc047d807..94f2cb25df3fdd306749add65fa4b3413d6ccb83 100644 (file)
@@ -118,6 +118,7 @@ go_langhook_init (void)
   args.debug_escape_level = go_debug_escape_level;
   args.debug_escape_hash = go_debug_escape_hash;
   args.nil_check_size_threshold = TARGET_AIX ? -1 : 4096;
   args.debug_escape_level = go_debug_escape_level;
   args.debug_escape_hash = go_debug_escape_hash;
   args.nil_check_size_threshold = TARGET_AIX ? -1 : 4096;
+  args.debug_optimization = go_debug_optimization;
   args.linemap = go_get_linemap();
   args.backend = go_get_backend();
   go_create_gogo (&args);
   args.linemap = go_get_linemap();
   args.backend = go_get_backend();
   go_create_gogo (&args);
index 6cb0662957ee28703e8724d0ac0e3fc313fd1536..aafb52c90ad8b4f271e8d4ee4a30ee5d3e607e08 100644 (file)
@@ -1,4 +1,4 @@
-4b3015de639cf22ed11ff96097555700909827c8
+dc9c1b43753f392fdc2045bcb7a4abaa44fe79f1
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index d8da232bbf036ea7a63b88c75b9b6218ed4e2424..183664a56625df6f3e8241c485a34dd961f78506 100644 (file)
@@ -44,6 +44,8 @@ go_create_gogo(const struct go_create_gogo_args* args)
   if (args->debug_escape_hash != NULL)
     ::gogo->set_debug_escape_hash(args->debug_escape_hash);
   ::gogo->set_nil_check_size_threshold(args->nil_check_size_threshold);
   if (args->debug_escape_hash != NULL)
     ::gogo->set_debug_escape_hash(args->debug_escape_hash);
   ::gogo->set_nil_check_size_threshold(args->nil_check_size_threshold);
+  if (args->debug_optimization)
+    ::gogo->set_debug_optimization(args->debug_optimization);
 }
 
 // Parse the input files.
 }
 
 // Parse the input files.
index f45576ee77dc0ab53d8a6e0140a65e4e3ee20cf3..9f18e14aecd27a9c6621f363a7b91c4c3abae4d3 100644 (file)
@@ -55,6 +55,7 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int, int pointer_size)
     check_divide_overflow_(true),
     compiling_runtime_(false),
     debug_escape_level_(0),
     check_divide_overflow_(true),
     compiling_runtime_(false),
     debug_escape_level_(0),
+    debug_optimization_(false),
     nil_check_size_threshold_(4096),
     verify_types_(),
     interface_types_(),
     nil_check_size_threshold_(4096),
     verify_types_(),
     interface_types_(),
index 1c9f0de0b366e60b1795e8108182d16df9a7adc6..cfa238ac6e81a1b0580589379495849bb98f4e8d 100644 (file)
@@ -326,6 +326,16 @@ class Gogo
   set_debug_escape_hash(const std::string& s)
   { this->debug_escape_hash_ = s; }
 
   set_debug_escape_hash(const std::string& s)
   { this->debug_escape_hash_ = s; }
 
+  // Return whether to output optimization diagnostics.
+  bool
+  debug_optimization() const
+  { return this->debug_optimization_; }
+
+  // Set the option to output optimization diagnostics.
+  void
+  set_debug_optimization(bool b)
+  { this->debug_optimization_ = b; }
+
   // Return the size threshold used to determine whether to issue
   // a nil-check for a given pointer dereference. A threshold of -1
   // implies that all potentially faulting dereference ops should
   // Return the size threshold used to determine whether to issue
   // a nil-check for a given pointer dereference. A threshold of -1
   // implies that all potentially faulting dereference ops should
@@ -1075,6 +1085,9 @@ class Gogo
   // -fgo-debug-escape-hash option. The analysis is run only on
   // functions with names that hash to the matching value.
   std::string debug_escape_hash_;
   // -fgo-debug-escape-hash option. The analysis is run only on
   // functions with names that hash to the matching value.
   std::string debug_escape_hash_;
+  // Whether to output optimization diagnostics, from the
+  // -fgo-debug-optimization option.
+  bool debug_optimization_;
   // Nil-check size threshhold.
   int64_t nil_check_size_threshold_;
   // A list of types to verify.
   // Nil-check size threshhold.
   int64_t nil_check_size_threshold_;
   // A list of types to verify.
index 1827f81901bab00927e9383562f9d4286ef7db14..2e2d039afbd99ad68bf31b99898e28bda0f49a93 100644 (file)
@@ -5512,6 +5512,8 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
                                                      range_temp, loc);
       if (clear != NULL)
         {
                                                      range_temp, loc);
       if (clear != NULL)
         {
+          if (gogo->debug_optimization())
+            go_inform(loc, "map range clear");
           temp_block->add_statement(clear);
           return Statement::make_block_statement(temp_block, loc);
         }
           temp_block->add_statement(clear);
           return Statement::make_block_statement(temp_block, loc);
         }
@@ -5527,6 +5529,8 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
                                                        range_temp, loc);
       if (clear != NULL)
         {
                                                        range_temp, loc);
       if (clear != NULL)
         {
+          if (gogo->debug_optimization())
+            go_inform(loc, "array range clear");
           temp_block->add_statement(clear);
           return Statement::make_block_statement(temp_block, loc);
         }
           temp_block->add_statement(clear);
           return Statement::make_block_statement(temp_block, loc);
         }
index f1a8126653567d46796882fbac53b796231bbf4d..91b8e4631a622f44036cb5a6d882adaef4689c4a 100644 (file)
@@ -85,6 +85,10 @@ fgo-debug-escape-hash=
 Go Joined RejectNegative Var(go_debug_escape_hash) Init(0)
 -fgo-debug-escape-hash=<string>        Hash value to debug escape analysis.
 
 Go Joined RejectNegative Var(go_debug_escape_hash) Init(0)
 -fgo-debug-escape-hash=<string>        Hash value to debug escape analysis.
 
+fgo-debug-optimization
+Go Var(go_debug_optimization) Init(0)
+Emit optimization diagnostics.
+
 o
 Go Joined Separate
 ; Documented in common.opt
 o
 Go Joined Separate
 ; Documented in common.opt
index a7b40dfc64e0516d7efa539aa9a0d4c6ea620ece..e132b5b8d7f3de2eb8ba74e972c2d12774823471 100644 (file)
@@ -1,3 +1,8 @@
+2019-05-07  Cherry Zhang  <cherryyz@google.com>
+
+       * go.dg/arrayclear.go: New test.
+       * go.dg/mapclear.go: New test.
+
 2019-05-07  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        PR target/89765
 2019-05-07  Kelvin Nilsen  <kelvin@gcc.gnu.org>
 
        PR target/89765
diff --git a/gcc/testsuite/go.dg/arrayclear.go b/gcc/testsuite/go.dg/arrayclear.go
new file mode 100644 (file)
index 0000000..6daebc0
--- /dev/null
@@ -0,0 +1,20 @@
+// { dg-do compile }
+// { dg-options "-fgo-debug-optimization" }
+
+package p
+
+var a [10]int
+
+func arrayClear() {
+       for i := range a { // { dg-error "array range clear" }
+               a[i] = 0
+       }
+}
+
+var s []int
+
+func sliceClear() {
+       for i := range s { // { dg-error "array range clear" }
+               s[i] = 0
+       }
+}
diff --git a/gcc/testsuite/go.dg/mapclear.go b/gcc/testsuite/go.dg/mapclear.go
new file mode 100644 (file)
index 0000000..a3bebe4
--- /dev/null
@@ -0,0 +1,10 @@
+// { dg-do compile }
+// { dg-options "-fgo-debug-optimization" }
+
+package p
+
+func clear(m map[int]int) {
+       for k := range m { // { dg-error "map range clear" }
+               delete(m, k)
+       }
+}