Commit 5d2a9da9 by Andrew Pinski Committed by Andrew Pinski

tree-ssa-ifcombine.c: Include rtl.h and tm_p.h.

2013-10-29  Andrew Pinski <apinski@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.
        * gimple.h (gsi_start_nondebug_after_labels_bb): New function.

2013-10-29  Andrew Pinski <apinski@cavium.com>
            Zhenqiang Chen  <zhenqiang.chen@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/phi-opt-9.c: Use a function call to prevent
        conditional move to be used.
        * gcc.dg/tree-ssa/ssa-dom-thread-3.c: Remove.


Co-Authored-By: Zhenqiang Chen <zhenqiang.chen@linaro.org>

From-SVN: r204194
parent d8487c94
2013-10-29 Andrew Pinski <apinski@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.
* gimple.h (gsi_start_nondebug_after_labels_bb): New function.
2013-10-29 Mike Stump <mikestump@comcast.net> 2013-10-29 Mike Stump <mikestump@comcast.net>
* machmode.def (PARTIAL_INT_MODE): Add precision and name. * machmode.def (PARTIAL_INT_MODE): Add precision and name.
...@@ -5533,6 +5533,20 @@ gsi_start_nondebug_bb (basic_block bb) ...@@ -5533,6 +5533,20 @@ gsi_start_nondebug_bb (basic_block bb)
return i; return i;
} }
/* Return a new iterator pointing to the first non-debug non-label statement in
basic block BB. */
static inline gimple_stmt_iterator
gsi_start_nondebug_after_labels_bb (basic_block bb)
{
gimple_stmt_iterator i = gsi_after_labels (bb);
if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
gsi_next_nondebug (&i);
return i;
}
/* Return a new iterator pointing to the last non-debug statement in /* Return a new iterator pointing to the last non-debug statement in
basic block BB. */ basic block BB. */
......
2013-10-29 Andrew Pinski <apinski@cavium.com>
Zhenqiang Chen <zhenqiang.chen@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/phi-opt-9.c: Use a function call to prevent
conditional move to be used.
* gcc.dg/tree-ssa/ssa-dom-thread-3.c: Remove.
2013-10-29 Tobias Burnus <burnus@net-b.de> 2013-10-29 Tobias Burnus <burnus@net-b.de>
PR fortran/44350 PR fortran/44350
......
...@@ -2,13 +2,14 @@ ...@@ -2,13 +2,14 @@
/* { dg-options "-O -fdump-tree-optimized" } */ /* { dg-options "-O -fdump-tree-optimized" } */
int g(int,int); int g(int,int);
int h(int);
int f(int t, int c) int f(int t, int c)
{ {
int d = 0; int d = 0;
int e = 0; int e = 0;
if (t) if (t)
{ {
d = c+1; d = h(c);
e = t; e = t;
} }
else d = 0, e = 0; else d = 0, e = 0;
......
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-dom1-details -fno-short-enums" } */
extern void abort (void) __attribute__ ((__noreturn__));
union tree_node;
typedef union tree_node *tree;
enum tree_code
{
VAR_DECL,
SSA_NAME,
MAX_TREE_CODES
};
extern unsigned char tree_contains_struct[MAX_TREE_CODES][64];
struct tree_base
{
enum tree_code code:16;
};
enum tree_node_structure_enum
{
TS_DECL_COMMON
};
struct tree_ssa_name
{
tree var;
};
union tree_node
{
struct tree_base base;
struct tree_ssa_name ssa_name;
};
long
expand_one_var (tree var, unsigned char toplevel, unsigned char really_expand)
{
tree origvar = var;
var = var->ssa_name.var;
if (((enum tree_code) (origvar)->base.code) == SSA_NAME
&& !((var->base.code != VAR_DECL)))
abort ();
if ((var->base.code) != VAR_DECL && ((origvar)->base.code) != SSA_NAME)
;
else if (tree_contains_struct[(var->base.code)][(TS_DECL_COMMON)] != 1)
abort ();
}
/* We should thread the jump, through an intermediate block. */
/* { dg-final { scan-tree-dump-times "Threaded" 2 "dom1"} } */
/* { dg-final { scan-tree-dump-times "Registering jump thread: \\(.*\\) incoming edge; \\(.*\\) joiner; \\(.*\\) nocopy;" 1 "dom1"} } */
/* { dg-final { cleanup-tree-dump "dom1" } } */
/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
int t (int a, int b)
{
if (a > 0)
if (b > 0)
return 0;
return 1;
}
/* { dg-final { scan-tree-dump "\&" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
int t (int a, int b)
{
if (a > 0)
goto L1;
if (b > 0)
goto L1;
return 0;
L1:
return 1;
}
/* { dg-final { scan-tree-dump "\|" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
int t (int a, int b)
{
if (a > 0)
goto L1;
else
goto L2;
L1:
if (b > 0)
goto L2;
return 5;
L2:
return 6;
}
/* { dg-final { scan-tree-dump "\|" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
int t (int a, int b)
{
if (a > 0)
goto L1;
if (b > 0)
goto L2;
L1:
return 0;
L2:
return 1;
}
/* { dg-final { scan-tree-dump "\&" "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
int t (int a, int b, int c)
{
if (a > 0 && b > 0 && c > 0)
return 0;
return 1;
}
/* { dg-final { scan-tree-dump-times "\&" 2 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
/* { dg-options "-O2 -g -fdump-tree-optimized" } */
/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
int t (int a, int b, int c)
{
if (a > 0 || b > 0 || c > 0)
return 0;
return 1;
}
/* { dg-final { scan-tree-dump-times "\\|" 2 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
...@@ -22,6 +22,10 @@ along with GCC; see the file COPYING3. If not see ...@@ -22,6 +22,10 @@ along with GCC; see the file COPYING3. If not see
#include "system.h" #include "system.h"
#include "coretypes.h" #include "coretypes.h"
#include "tm.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 "tree.h"
#include "basic-block.h" #include "basic-block.h"
#include "tree-pretty-print.h" #include "tree-pretty-print.h"
...@@ -32,6 +36,12 @@ along with GCC; see the file COPYING3. If not see ...@@ -32,6 +36,12 @@ along with GCC; see the file COPYING3. If not see
#include "ssa-iterators.h" #include "ssa-iterators.h"
#include "tree-pass.h" #include "tree-pass.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 /* This pass combines COND_EXPRs to simplify control flow. It
currently recognizes bit tests and comparisons in chains that currently recognizes bit tests and comparisons in chains that
represent logical and or logical or of two COND_EXPRs. represent logical and or logical or of two COND_EXPRs.
...@@ -488,7 +498,35 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, ...@@ -488,7 +498,35 @@ ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv,
outer_cond_code, outer_cond_code,
gimple_cond_lhs (outer_cond), gimple_cond_lhs (outer_cond),
gimple_cond_rhs (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_after_labels_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);
if (result_inv)
{
t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t);
result_inv = false;
}
gsi = gsi_for_stmt (inner_cond);
t = force_gimple_operand_gsi_1 (&gsi, t, is_gimple_condexpr, NULL, true,
GSI_SAME_STMT);
}
if (result_inv) if (result_inv)
t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t); t = fold_build1 (TRUTH_NOT_EXPR, TREE_TYPE (t), t);
t = canonicalize_cond_expr_cond (t); t = canonicalize_cond_expr_cond (t);
...@@ -631,7 +669,15 @@ tree_ssa_ifcombine (void) ...@@ -631,7 +669,15 @@ tree_ssa_ifcombine (void)
bbs = single_pred_before_succ_order (); bbs = single_pred_before_succ_order ();
calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; ++i) /* Search every basic block for COND_EXPR we may be able to optimize.
We walk the blocks in order that guarantees that a block with
a single predecessor is processed after the predecessor.
This ensures that we collapse outter ifs before visiting the
inner ones, and also that we do not try to visit a removed
block. This is opposite of PHI-OPT, because we cascade the
combining rather than cascading PHIs. */
for (i = n_basic_blocks - NUM_FIXED_BLOCKS - 1; i >= 0; i--)
{ {
basic_block bb = bbs[i]; basic_block bb = bbs[i];
gimple stmt = last_stmt (bb); gimple stmt = last_stmt (bb);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment