The testcase currently spends all of its time in tree if-conversion
bool pattern repair and most of its time in walking immediate uses
of 'var' to look for the use operand to replace in a specifc stmt.

When there are a lot of immediate uses that's slow and it is faster
to walk the uses on the specific stmt and to check whether the use
is the one to replace.

This reduces compile-time from 20s to 6s (-O0 trunk with -fno-checking)
and if-conversion percentage from 81% to 54%.  It's still slow
(exponentially unsharing stuff), but it's an easy start.

Bootstrap / regtest running on x86_64-unknown-linux-gnu.

2016-05-25  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/71261
        * tree-if-conv.c (ifcvt_split_def_stmt): Walk uses on the
        interesting stmt instead of immediate uses when looking
        for the use operand to replace.

        * c-c++-common/torture/pr71261.c: New testcase.

Index: gcc/tree-if-conv.c
===================================================================
*** gcc/tree-if-conv.c  (revision 236695)
--- gcc/tree-if-conv.c  (working copy)
*************** ifcvt_split_def_stmt (gimple *def_stmt,
*** 2529,2535 ****
    gimple *copy_stmt;
    gimple_stmt_iterator gsi;
    use_operand_p use_p;
!   imm_use_iterator imm_iter;
  
    var = gimple_assign_lhs (def_stmt);
    copy_stmt = gimple_copy (def_stmt);
--- 2529,2535 ----
    gimple *copy_stmt;
    gimple_stmt_iterator gsi;
    use_operand_p use_p;
!   ssa_op_iter iter;
  
    var = gimple_assign_lhs (def_stmt);
    copy_stmt = gimple_copy (def_stmt);
*************** ifcvt_split_def_stmt (gimple *def_stmt,
*** 2548,2556 ****
        print_generic_expr (dump_file, lhs, TDF_SLIM);
        fprintf (dump_file, "\n");
      }
!   FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var)
      {
!       if (USE_STMT (use_p) != use_stmt)
        continue;
        SET_USE (use_p, lhs);
        break;
--- 2548,2556 ----
        print_generic_expr (dump_file, lhs, TDF_SLIM);
        fprintf (dump_file, "\n");
      }
!   FOR_EACH_SSA_USE_OPERAND (use_p, use_stmt, iter, SSA_OP_USE)
      {
!       if (USE_FROM_PTR (use_p) != var)
        continue;
        SET_USE (use_p, lhs);
        break;
Index: gcc/testsuite/c-c++-common/torture/pr71261.c
===================================================================
*** gcc/testsuite/c-c++-common/torture/pr71261.c        (revision 0)
--- gcc/testsuite/c-c++-common/torture/pr71261.c        (working copy)
***************
*** 0 ****
--- 1,11 ----
+ /* { dg-do compile } */
+ /* { dg-additional-options "-mavx2" { target x86_64-*-* i?86-*-* } } */
+ 
+ extern int a, b, c, d, e, f;
+ void fn1()
+ {
+   for (int g = 0; g < d; g = 1)
+     for (int h = 0; h < 8; h = h + 2)
+       for (int i = h; i < h + 2; i = i + 1)
+       f = a && e || c && b;
+ }

Reply via email to