On Wed, Oct 16, 2013 at 2:12 AM, Zhenqiang Chen <zhenqiang.c...@linaro.org> wrote: > Hi, > > The patch enhances ifcombine pass to recover some non short circuit > branches. Basically, it will do the following transformation: > > Case 1: > if (cond1) > if (cond2) > ==> > if (cond1 && cond2) > > Case 2: > if (cond1) > goto L1 > if (cond2) > goto L1 > ==> > if (cond1 || cond2) > goto L1 > > Case 3: > if (cond1) > goto L1 > else > goto L2 > L1: > if (cond2) > goto L2 > ==> > if (invert (cond1) || cond2) > goto L2 > > Case 4: > if (cond1) > goto L1 > if (cond2) > goto L2 > L1: > ==> > if (invert (cond1) && cond2) > goto L2 > > Bootstrap on X86-64 and ARM. > > Two new FAILs in regression tests: > gcc.dg/uninit-pred-8_b.c > gcc.dg/uninit-pred-9_b.c > uninit pass should be enhanced to handle more complex conditions. Will > submit a bug to track it and fix it later. > > Is it OK for trunk?
I had a much simpler change which did basically the same from 4.7 (I can update it if people think this is a better approach). Thanks, Andrew Pinski 2012-09-29 Andrew Pinski <apin...@cavium.com> * tree-ssa-ifcombine.c: Include rtl.h and tm_p.h. (ifcombine_ifandif): Handle cases where maybe_fold_and_comparisons fails, combining the branches anyways. (tree_ssa_ifcombine): Inverse the order of the basic block walk, increases the number of combinings. * Makefile.in (tree-ssa-ifcombine.o): Update dependencies. * testsuite/gcc.dg/tree-ssa/phi-opt-2.c: Expect zero ifs as the compiler produces a & b now. * testsuite/gcc.dg/tree-ssa/phi-opt-9.c: Use a function call to prevent conditional move to be used. * testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c: Remove check for "one or more intermediate". > > Thanks! > -Zhenqiang > > ChangeLog: > 2013-10-16 Zhenqiang Chen <zhenqiang.c...@linaro.org> > > * fold-const.c (simple_operand_p_2): Make it global. > * tree.h (simple_operand_p_2): Declare it. > * tree-ssa-ifcombine.c: Include rtl.h and tm_p.h. > (bb_has_overhead_p, generate_condition_node, > ifcombine_ccmp): New functions. > (ifcombine_fold_ifandif): New function, extracted from > ifcombine_ifandif. > (ifcombine_ifandif): Call ifcombine_ccmp. > (tree_ssa_ifcombine_bb): Skip optimized bb. > > testsuite/ChangeLog > 2013-10-16 Zhenqiang Chen <zhenqiang.c...@linaro.org> > > * gcc.dg/tree-ssa/ssa-ifcombine-ccmp-1.c: New test case. > * gcc.dg/tree-ssa/ssa-ifcombine-ccmp-2.c: New test case. > * gcc.dg/tree-ssa/ssa-ifcombine-ccmp-3.c: New test case. > * gcc.dg/tree-ssa/ssa-ifcombine-ccmp-4.c: New test case. > * gcc.dg/tree-ssa/ssa-ifcombine-ccmp-5.c: New test case. > * gcc.dg/tree-ssa/ssa-ifcombine-ccmp-6.c: New test case. > * gcc.dg/tree-ssa/ssa-dom-thread-3.c: Updated.
commit 90434d0567109d9add1eb5583ae38df06cc6ffa1 Author: Andrew Pinski <apin...@cavium.com> Date: Sat Sep 29 01:29:12 2012 -0700 2012-09-29 Andrew Pinski <apin...@cavium.com> * tree-ssa-ifcombine.c: Include rtl.h and tm_p.h. (ifcombine_ifandif): Handle cases where maybe_fold_and_comparisons fails, combining the branches anyways. (tree_ssa_ifcombine): Inverse the order of the basic block walk, increases the number of combinings. * Makefile.in (tree-ssa-ifcombine.o): Update dependencies. * testsuite/gcc.dg/tree-ssa/phi-opt-2.c: Expect zero ifs as the compiler produces a & b now. * testsuite/gcc.dg/tree-ssa/phi-opt-9.c: Use a function call to prevent conditional move to be used. * testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c: Remove check for "one or more intermediate". diff --git a/gcc/ChangeLog.CAVIUM b/gcc/ChangeLog.CAVIUM index 4739ded..8413818 100644 --- a/gcc/ChangeLog.CAVIUM +++ b/gcc/ChangeLog.CAVIUM @@ -1,5 +1,22 @@ 2012-09-29 Andrew Pinski <apin...@cavium.com> + * tree-ssa-ifcombine.c: Include rtl.h and tm_p.h. + (ifcombine_ifandif): Handle cases where + maybe_fold_and_comparisons fails, combining the branches + anyways. + (tree_ssa_ifcombine): Inverse the order of + the basic block walk, increases the number of combinings. + * Makefile.in (tree-ssa-ifcombine.o): Update dependencies. + + * testsuite/gcc.dg/tree-ssa/phi-opt-2.c: Expect zero ifs as the compiler + produces a & b now. + * testsuite/gcc.dg/tree-ssa/phi-opt-9.c: Use a function call + to prevent conditional move to be used. + * testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c: Remove check for + "one or more intermediate". + +2012-09-29 Andrew Pinski <apin...@cavium.com> + Revert: 2012-07-23 Andrew Pinski <apin...@cavium.com> diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 172dde2..ef8cb98 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -2357,7 +2357,7 @@ tree-ssa-phiprop.o : tree-ssa-phiprop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \ langhooks.h $(FLAGS_H) tree-pretty-print.h gimple-pretty-print.h tree-ssa-ifcombine.o : tree-ssa-ifcombine.c $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h $(TM_H) $(TREE_H) $(BASIC_BLOCK_H) \ + coretypes.h $(TM_H) $(RTL_H) $(TM_P_H) $(TREE_H) $(BASIC_BLOCK_H) \ $(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_DUMP_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) \ tree-pretty-print.h tree-merge-const-bfstores.o : tree-merge-const-bfstores.c $(CONFIG_H) \ diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h index 6c680be..89c76d9 100644 --- a/gcc/config/mips/mips.h +++ b/gcc/config/mips/mips.h @@ -2428,7 +2428,6 @@ typedef struct mips_args { 1 is the default; other values are interpreted relative to that. */ #define BRANCH_COST(speed_p, predictable_p) mips_branch_cost -#define LOGICAL_OP_NON_SHORT_CIRCUIT 0 /* If defined, modifies the length assigned to instruction INSN as a function of the context in which it is used. LENGTH is an lvalue diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-2.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-2.c index 415c117..26952ac 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-2.c @@ -13,10 +13,7 @@ _Bool f1(_Bool a, _Bool b) return 0; } - -/* There should be only one if, the outer one; the inner one - should have been changed to straight line code with the - value of b (except that we don't fold ! (b != 0) into b - which can be fixed in a different patch). */ -/* { dg-final { scan-tree-dump-times "if" 1 "optimized"} } */ +/* There should be only no ifs; both of them should have + been changed into straight line code (a & b). */ +/* { dg-final { scan-tree-dump-times "if" 0 "optimized"} } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-9.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-9.c index dccea7b..a224788 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-9.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-9.c @@ -2,13 +2,14 @@ /* { dg-options "-O -fdump-tree-optimized" } */ int g(int,int); +int h(int); int f(int t, int c) { int d = 0; int e = 0; if (t) { - d = c+1; + d = h(c); e = t; } else d = 0, e = 0; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c index d851bf2..8fb3ef8 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c @@ -42,6 +42,5 @@ expand_one_var (tree var, unsigned char toplevel, unsigned char really_expand) } /* We should thread the jump, through an intermediate block. */ /* { dg-final { scan-tree-dump-times "Threaded" 1 "dom1"} } */ -/* { dg-final { scan-tree-dump-times "one or more intermediate" 1 "dom1"} } */ /* { dg-final { cleanup-tree-dump "dom1" } } */ diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index 4e6075b..6e18ec8 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -22,6 +22,10 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tm.h" +/* rtl is needed only because arm back-end requires it for + BRANCH_COST. */ +#include "rtl.h" +#include "tm_p.h" #include "tree.h" #include "basic-block.h" #include "timevar.h" @@ -30,6 +34,12 @@ along with GCC; see the file COPYING3. If not see #include "tree-pass.h" #include "tree-dump.h" +#ifndef LOGICAL_OP_NON_SHORT_CIRCUIT +#define LOGICAL_OP_NON_SHORT_CIRCUIT \ + (BRANCH_COST (optimize_function_for_speed_p (cfun), \ + false) >= 2) +#endif + /* This pass combines COND_EXPRs to simplify control flow. It currently recognizes bit tests and comparisons in chains that represent logical and or logical or of two COND_EXPRs. @@ -486,7 +496,30 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, outer_cond_code, gimple_cond_lhs (outer_cond), gimple_cond_rhs (outer_cond)))) - return false; + { + tree t1, t2; + gimple_stmt_iterator gsi; + if (!LOGICAL_OP_NON_SHORT_CIRCUIT) + return false; + /* Only do this optimization if the inner bb contains only the conditional. */ + if (!gsi_one_before_end_p (gsi_start_nondebug_bb (inner_cond_bb))) + return false; + t1 = fold_build2_loc (gimple_location (inner_cond), + inner_cond_code, + boolean_type_node, + gimple_cond_lhs (inner_cond), + gimple_cond_rhs (inner_cond)); + t2 = fold_build2_loc (gimple_location (outer_cond), + outer_cond_code, + boolean_type_node, + gimple_cond_lhs (outer_cond), + gimple_cond_rhs (outer_cond)); + t = fold_build2_loc (gimple_location (inner_cond), + TRUTH_AND_EXPR, boolean_type_node, t1, t2); + gsi = gsi_for_stmt (inner_cond); + t = force_gimple_operand_gsi (&gsi, t, true, NULL, true, + GSI_SAME_STMT); + } if (result_inv) t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t); t = canonicalize_cond_expr_cond (t); @@ -629,7 +662,7 @@ tree_ssa_ifcombine (void) bbs = blocks_in_phiopt_order (); calculate_dominance_info (CDI_DOMINATORS); - for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; ++i) + for (i = n_basic_blocks - NUM_FIXED_BLOCKS -1; i >= 0; i--) { basic_block bb = bbs[i]; gimple stmt = last_stmt (bb);