compiler: add an option to emit optimization diagnostics

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
This commit is contained in:
Cherry Zhang 2019-05-08 00:14:17 +00:00 committed by Ian Lance Taylor
parent a88158bc4d
commit f837b9c41a
13 changed files with 75 additions and 1 deletions

View 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

View 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.
@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.

View 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;
bool debug_optimization;
};
extern void go_create_gogo (const struct go_create_gogo_args*);

View 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_optimization = go_debug_optimization;
args.linemap = go_get_linemap();
args.backend = go_get_backend();
go_create_gogo (&args);

View 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.

View 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_optimization)
::gogo->set_debug_optimization(args->debug_optimization);
}
// Parse the input files.

View 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),
debug_optimization_(false),
nil_check_size_threshold_(4096),
verify_types_(),
interface_types_(),

View File

@ -326,6 +326,16 @@ class Gogo
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
@ -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_;
// 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.

View File

@ -5512,6 +5512,8 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
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);
}
@ -5527,6 +5529,8 @@ For_range_statement::do_lower(Gogo* gogo, Named_object*, Block* enclosing,
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);
}

View 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.
fgo-debug-optimization
Go Var(go_debug_optimization) Init(0)
Emit optimization diagnostics.
o
Go Joined Separate
; Documented in common.opt

View 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

View File

@ -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
}
}

View File

@ -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)
}
}