-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
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? -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/ iQEcBAEBAgAGBQJNsFGKAAoJEBRtltQi2kC7wP4IAJZ6e/jF5WAnFdG5/G6lWdEp D1mBlaFvrSgAXp/Qx9y8uLQfnpzSvcgb59naTH2p+rDILjAs9Bw1eXZN0MCwTN4H tylFm3w4a9BMzHbzgiwGzDBTkUyzIQyQ1XzqSHbOTWtzEuFGbAmRzSgDoFPbZEPD cWXsh7yRLr/aqOFLCoEbN/Wp87aBDSXi+I7d5rU+la97En3FWBSNku84dZf1F+8C 9qW4wCW7lX1LVnWy3LmeSxXf0k9JmJGkUvdmSr2TYtZVPvPLqHg97NOWG9CAfUVO cTZW5QOFuyEGg/vbYOFmfWRI7uw+YjggV/v0LzUYjRV00fj+rygjgUfgA5f3rGA= =NPtm -----END PGP SIGNATURE-----
* tree-vrp.c (identify_jump_threads): Handle GIMPLE_SWITCH too. Index: tree-vrp.c =================================================================== *** tree-vrp.c (revision 172644) --- 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