tree-vrp.c (identify_jump_threads): Handle GIMPLE_SWITCH too.

* tree-vrp.c (identify_jump_threads): Handle GIMPLE_SWITCH too.

	* gcc.dg/tree-ssa/vrp56.c: new test.

From-SVN: r172938
This commit is contained in:
Jeff Law 2011-04-25 13:55:13 -06:00 committed by Jeff Law
parent 328db4501e
commit 1f3fcdc3a9
4 changed files with 61 additions and 11 deletions

View File

@ -1,3 +1,7 @@
2011-04-25 Jeff Law <law@redhat.com>
* tree-vrp.c (identify_jump_threads): Handle GIMPLE_SWITCH too.
2011-04-25 Jan Kratochvil <jan.kratochvil@redhat.com>
* system.h (ENUM_BITFIELD): Remove.

View File

@ -1,3 +1,7 @@
2011-04-25 Jeff Law <law@redhat.com>
* gcc.dg/tree-ssa/vrp56.c: new test.
2011-04-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* go.test/go-test.exp (go-set-goarch): Accept mips*-*-*.

View File

@ -0,0 +1,42 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
typedef struct basic_block_def *basic_block;
struct basic_block_def;
struct edge_def;
typedef struct edge_def *edge;
typedef struct VEC_edge_base
{
unsigned num;
} VEC_edge_base;
typedef struct VEC_edge_none
{
VEC_edge_base base;
} VEC_edge_none;
static __inline__ unsigned
VEC_edge_base_length (VEC_edge_base * vec_)
{
return vec_ ? vec_->num : 0;
}
typedef struct VEC_edge_gc
{
VEC_edge_base base;
} VEC_edge_gc;
struct basic_block_def
{
VEC_edge_gc *succs;
};
unsigned char
cleanup_empty_eh (basic_block bb)
{
edge e_out;
switch (VEC_edge_base_length (&bb->succs->base))
{
case 1:
foo ();
}
}
/* { dg-final { scan-tree-dump-times "Threaded" 2 "vrp1"} } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */

View File

@ -7555,25 +7555,25 @@ identify_jump_threads (void)
may be some value in handling SWITCH_EXPR here, I doubt it's
terribly important. */
last = gsi_stmt (gsi_last_bb (bb));
if (gimple_code (last) != GIMPLE_COND)
continue;
/* We're basically looking for any kind of conditional with
/* We're basically looking for a switch or any kind of conditional with
integral or pointer type arguments. Note the type of the second
argument will be the same as the first argument, so no need to
check it explicitly. */
if (TREE_CODE (gimple_cond_lhs (last)) == SSA_NAME
&& (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (last)))
|| POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (last))))
&& (TREE_CODE (gimple_cond_rhs (last)) == SSA_NAME
|| is_gimple_min_invariant (gimple_cond_rhs (last))))
if (gimple_code (last) == GIMPLE_SWITCH
|| (gimple_code (last) == GIMPLE_COND
&& TREE_CODE (gimple_cond_lhs (last)) == SSA_NAME
&& (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (last)))
|| POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (last))))
&& (TREE_CODE (gimple_cond_rhs (last)) == SSA_NAME
|| is_gimple_min_invariant (gimple_cond_rhs (last)))))
{
edge_iterator ei;
/* We've got a block with multiple predecessors and multiple
successors which also ends in a suitable conditional. For
each predecessor, see if we can thread it to a specific
successor. */
successors which also ends in a suitable conditional or
switch statement. For each predecessor, see if we can thread
it to a specific successor. */
FOR_EACH_EDGE (e, ei, bb->preds)
{
/* Do not thread across back edges or abnormal edges