-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 04/22/11 02:56, Richard Guenther wrote:
> On Thu, Apr 21, 2011 at 5:47 PM, Jeff Law <l...@redhat.com> wrote:
> 
> For some dumb reason I thought handling threading through a SWITCH_EXPR
> was hard in VRP; that's definitely not the case, it's no more difficult
> than handling a COND_EXPR.
> 
> This patch allows tree-vrp.c to thread through a SWITCH_EXPR when we
> know the switch index via a particular path.  Most of these would have
> eventually been caught by DOM, but we get to pick up more secondary
> effects if we can catch them in VRP.
> 
> Bootstrapped and regression tested on x86_64-unknown-linux-gnu.  OK for
> trunk?
> 
>> Ok.  Can you add a testcase?
Attached is the patch checked in (no functional changes since the
submission, just the new testcase).

Jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJNtdF2AAoJEBRtltQi2kC7VwYH/2pIkRUesXHnCCJ/GeqptZTM
J3aExZeG3kuxAEaWcmlPvurfUWoZVI56uM4igEBKKHl857Y3Qx/EMfHNaTXRHbDA
lzos+rMRpT5cPbFfpvsSoDEyS07LDYA4VsMQ910whiNhFKC14+HkXHH13PA8Enr9
gID8VviapiGh87CeCoAK/OsS72o8T0QBqsOKj0Ww+ZzHjqCSQnHPt0COw4qmxfij
gsZQIdFtYwzV+LSwu3KpO5jmXe2IPtT36vSvtkGmQgEJ5S0L4Sc66yuiLY3p8SEh
Di5ajN0m9ZWcaKvLKZVFRrv3eAXo8/hQp2Jrs+HDA8YTwIRKHj9bR4oJVuSoHwM=
=+Whu
-----END PGP SIGNATURE-----
Index: ChangeLog
===================================================================
*** ChangeLog   (revision 172937)
--- ChangeLog   (working copy)
***************
*** 1,3 ****
--- 1,7 ----
+ 2011-04-25  Jeff Law  <l...@redhat.com>
+ 
+       * tree-vrp.c (identify_jump_threads): Handle GIMPLE_SWITCH too.
+ 
  2011-04-25  Jan Kratochvil  <jan.kratoch...@redhat.com>
  
        * system.h (ENUM_BITFIELD): Remove.
Index: tree-vrp.c
===================================================================
*** tree-vrp.c  (revision 172937)
--- tree-vrp.c  (working copy)
*************** identify_jump_threads (void)
*** 7555,7579 ****
         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
         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))))
        {
          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.  */
          FOR_EACH_EDGE (e, ei, bb->preds)
            {
              /* Do not thread across back edges or abnormal edges
--- 7555,7579 ----
         may be some value in handling SWITCH_EXPR here, I doubt it's
         terribly important.  */
        last = gsi_stmt (gsi_last_bb (bb));
  
!       /* 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 (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 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
Index: testsuite/gcc.dg/tree-ssa/vrp56.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/vrp56.c   (revision 0)
--- testsuite/gcc.dg/tree-ssa/vrp56.c   (revision 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" } } */
+ 
Index: testsuite/ChangeLog
===================================================================
*** testsuite/ChangeLog (revision 172937)
--- testsuite/ChangeLog (working copy)
***************
*** 1,3 ****
--- 1,7 ----
+ 2011-04-25  Jeff Law <l...@redhat.com>
+ 
+       * gcc.dg/tree-ssa/vrp56.c: new test.
+ 
  2011-04-25  Rainer Orth  <r...@cebitec.uni-bielefeld.de>
  
        * go.test/go-test.exp (go-set-goarch): Accept mips*-*-*.

Reply via email to