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; + }