On Wed, Jan 4, 2017 at 8:08 PM Alexandre Oliva <aol...@redhat.com> wrote:
>
> On Jan  4, 2017, Alexandre Oliva <aol...@redhat.com> wrote:
>
> > So I guess we need some alternate PerFunction option flag that makes
> > it per-function, but not part of the ICF hash?
>
> Like this...
>
> If we include them in the ICF hash, they may cause congruence_groups to
> be processed in a different order due to different hashes, which in turn
> causes different funcdef_nos to be assigned to functions.  Since these
> numbers are included in -fcompare-debug dumps, they cause failures.
>
> Since these options are not optimization options, in that they do not
> (or should not, save for bugs like this) affect the executable code
> output by the compiler, they should not be marked as such.
>
> This patch replaces the Optimization flag in the var-tracking options
> with the newly-introduced PerFunction flag, so that it can still be
> controlled on a per-function basis, but that disregards it in the hash
> computation used by ICF.
>
> This fixes -fcompare-debug failures in numerous LTO testcases.
>
> Regstrapped on x86_64-linux-gnu and i686-linux-gnu.  Ok to install?
>
> for  gcc/ChangeLog
>
>         * doc/options.texi (PerFunction): New.
>         * opt-functions.awk (switch_flags): Map both Optimization and
>         PerFunction to CL_OPTIMIZATION.
>         * opth-gen.awk: Test for PerFunction flag along with
>         Optimization.
>         * optc-save-gen.awk: Likewise.  Introduce var_opt_hash and set
>         it only when the latter is present.  Skip those that don't in
>         the hash function generator.
>         * common.opt (fvar-tracking): Mark as PerFunction instead of
>         Optimization.
>         (fvar-tracking-assignments): Likewise.
>         (fvar-tracking-assignments-toggle): Likewise.
>         (fvar-tracking-uninit): Likewise.


> diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk
> index 8ce4248..0928d5d 100644
> --- a/gcc/optc-save-gen.awk
> +++ b/gcc/optc-save-gen.awk
> @@ -100,7 +100,7 @@ var_opt_range["optimize_debug"] = "0, 1";
>  # cache.
>
>  for (i = 0; i < n_opts; i++) {
> -       if (flag_set_p("Optimization", flags[i])) {
> +       if (flag_set_p("(Optimization|PerFunction)", flags[i])) {
>                 name = var_name(flags[i])
>                 if(name == "")
>                         continue;
> @@ -743,7 +743,7 @@ var_opt_val[2] = "x_optimize_debug"
>  var_opt_val_type[1] = "char "
>  var_opt_val_type[2] = "char "
>  for (i = 0; i < n_opts; i++) {
> -       if (flag_set_p("Optimization", flags[i])) {
> +       if (flag_set_p("(Optimization|PerFunction)", flags[i])) {
>                 name = var_name(flags[i])
>                 if(name == "")
>                         continue;
> @@ -756,6 +756,7 @@ for (i = 0; i < n_opts; i++) {
>                 otype = var_type_struct(flags[i])
>                 var_opt_val_type[n_opt_val] = otype;
>                 var_opt_val[n_opt_val++] = "x_" name;
> +               var_opt_hash[n_opt_val] = flag_set_p("Optimization", 
> flags[i]);
>         }
>  }
>  print "";


This patch was committed a couple of years ago, but it's buggy in two
ways.  The var_opt_hash array is not set for the three flags that
precede this loop (x_optimize, x_optimize_size, and x_optimize_debug).
And, as you can see by noticing the position of n_opt_val++ above,
it's set for the wrong flag for the other cases--it's always set for
the next flag, not the current one.  This causes the hash and equality
comparisons of cl_optimization_eq to do the wrong thing.  It's hard to
notice, because in practice there tend to be other changes that affect
the result.  I was able to construct a (rather fragile) test case that
shows the problem, in which the compiler thinks that two sets of
function optimization attributes are the same when using the hash
table in build_optimization_node, although one is -O2 and one is -Os.

Any objections to my committing this patch?  Bootstrapped and tested
on x86_64-pc-linux-gnu.

Ian

2019-02-13  Ian Lance Taylor  <i...@golang.org>

        * optc-save-gen.awk: Set var_opt_hash for initial optimizations
        and set current index for other optimizations.

2019-02-13  Ian Lance Taylor  <i...@golang.org>

        * gcc.dg/func-attr-1.c: New test.
Index: optc-save-gen.awk
===================================================================
--- optc-save-gen.awk   (revision 268833)
+++ optc-save-gen.awk   (working copy)
@@ -770,8 +770,11 @@
 n_opt_val = 3;
 var_opt_val[0] = "x_optimize"
 var_opt_val_type[0] = "char "
+var_opt_hash[0] = 1;
 var_opt_val[1] = "x_optimize_size"
+var_opt_hash[1] = 1;
 var_opt_val[2] = "x_optimize_debug"
+var_opt_hash[2] = 1;
 var_opt_val_type[1] = "char "
 var_opt_val_type[2] = "char "
 for (i = 0; i < n_opts; i++) {
@@ -787,8 +790,9 @@
 
                otype = var_type_struct(flags[i])
                var_opt_val_type[n_opt_val] = otype;
-               var_opt_val[n_opt_val++] = "x_" name;
+               var_opt_val[n_opt_val] = "x_" name;
                var_opt_hash[n_opt_val] = flag_set_p("Optimization", flags[i]);
+                n_opt_val++;
        }
 }
 print "";
Index: testsuite/gcc.dg/func-attr-1.c
===================================================================
--- testsuite/gcc.dg/func-attr-1.c      (nonexistent)
+++ testsuite/gcc.dg/func-attr-1.c      (working copy)
@@ -0,0 +1,23 @@
+/* Test that setting -Os in a function attribute works.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-bbro" } */
+
+extern void f1 ();
+extern int f2 ();
+
+__attribute__ ((__optimize__ ("O2")))
+void
+f3()
+{
+}
+
+__attribute__ ((__optimize__ ("-Os", "-falign-functions", "-falign-jumps", 
"-falign-labels", "-falign-loops", "-fno-inline-functions", 
"-foptimize-strlen")))
+int
+f4 () {
+  if (f2 () == 0) {
+    f1 ();
+  }
+  return 0;
+}
+
+/* { dg-final { scan-rtl-dump-not "Duplicated bb" "bbro" } } */

Reply via email to