For: void test55 (void) { int u; int XXX, YYY; XXX = foo (); YYY = bar (); if (XXX != 5 && YYY) { u = XXX + 22; if (u != 27) baz (); } } The .optimized dump looks like: ;; Function test55 (test55) test55 () { int T.1; int T.0; <bb 0>: T.0 = foo (); T.1 = bar (); if (T.0 != 5 && T.1 != 0) goto <L0>; else goto <L2>; <L0>:; if (T.0 + 22 != 27) goto <L1>; else goto <L2>; <L1>:; baz (); <L2>:; <L3>:; return; } The XXX and YYY variables have been replaced with the compiler generated T.0 and T.1 T.0 and T.1 are created in .generic T.0 = foo (); XXX = T.0; T.1 = bar (); YYY = T.1; T.2 = XXX != 5; T.3 = YYY != 0; T.4 = T.2 && T.3; in .dom1 XXX and YYY in the T.2 and T.3 assignments are replaces with T.0 and T.1 T.0_1 = foo (); XXX_2 = T.0_1; T.1_3 = bar (); YYY_4 = T.1_3; T.2_5 = T.0_1 != 5; T.3_6 = T.1_3 != 0; and finally dce2 eliminates XXX and YYY as they are not used anymore.
Confirmed, I am ready to add a pessimizes-debug keyword also.
This comment in gimplify_modify_expr seems to be relevant here: /* If the RHS of the MODIFY_EXPR may throw or make a nonlocal goto and the LHS is a user variable, then we need to introduce a temporary. ie temp = RHS; LHS = temp. This way the optimizers can determine that the user variable is only modified if evaluation of the RHS does not throw. FIXME this should be handled by the is_gimple_rhs predicate. */
Perhaps something like this patch. Dan can you test this? Index: gimplify.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/Attic/gimplify.c,v retrieving revision 1.1.2.141 diff -c -3 -p -r1.1.2.141 gimplify.c *** gimplify.c 30 Jan 2004 13:14:02 -0000 1.1.2.141 --- gimplify.c 5 Feb 2004 00:26:34 -0000 *************** gimplify_modify_expr (tree *expr_p, tree *** 2389,2396 **** FIXME this should be handled by the is_gimple_rhs predicate. */ ! if (TREE_CODE (*from_p) == CALL_EXPR ! || (flag_non_call_exceptions && tree_could_trap_p (*from_p)) /* If we're dealing with a renamable type, either source or dest must be a renamed variable. */ || (is_gimple_reg_type (TREE_TYPE (*from_p)) --- 2389,2395 ---- FIXME this should be handled by the is_gimple_rhs predicate. */ ! if (tree_could_throw_p (*from_p) /* If we're dealing with a renamable type, either source or dest must be a renamed variable. */ || (is_gimple_reg_type (TREE_TYPE (*from_p))
ay, wait. this won't work because now it would completely ignore noncall exceptions. But the logic may need to be similar to what tree_could_throw_p does...
I believe this is more than an enhancement. This PR makes it impossible to debug code because almost all user variables just disappear.
Patch here: <http://gcc.gnu.org/ml/gcc-patches/2004-02/msg02616.html>
I'll have a more final version shortly, once it runs through final tests. I'll post what I check In. Andrew
FInal version is in the attachment: http://gcc.gnu.org/ml/gcc-patches/2004-03/msg00037.html
Created attachment 5830 [details] patch This has been checked into the branch. Andrew
Fixed so closing.