On Wed, Oct 16, 2013 at 2:12 AM, Zhenqiang Chen
<[email protected]> 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 <[email protected]>
* 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 <[email protected]>
>
> * 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 <[email protected]>
>
> * 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 <[email protected]>
Date: Sat Sep 29 01:29:12 2012 -0700
2012-09-29 Andrew Pinski <[email protected]>
* 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 <[email protected]>
+ * 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 <[email protected]>
+
Revert:
2012-07-23 Andrew Pinski <[email protected]>
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);