From: Mark Mitchell Date: Wed, 30 Sep 1998 10:10:02 +0000 (+0000) Subject: function.c (gen_mem_addressof): If the address REG is REG_USERVAR_P make the new... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=95ca22f405ab053a5275610e22b869f595c8e68b;p=gcc.git function.c (gen_mem_addressof): If the address REG is REG_USERVAR_P make the new REG be so also. * function.c (gen_mem_addressof): If the address REG is REG_USERVAR_P make the new REG be so also. * loop.c (scan_loop): Apply DeMorgan's laws and add documentation in an attempt to clarify slightly. From-SVN: r22667 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b8176014e06..b7d489fbc05 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +Wed Sep 30 10:09:39 1998 Mark Mitchell + + * function.c (gen_mem_addressof): If the address REG is + REG_USERVAR_P make the new REG be so also. + * loop.c (scan_loop): Apply DeMorgan's laws and add documentation + in an attempt to clarify slightly. + Wed Sep 30 09:57:40 1998 Jeffrey A Law (law@cygnus.com) * expr.c (expand_expr): Handle COMPONENT_REF, BIT_FIELD_REF ARRAY_REF diff --git a/gcc/function.c b/gcc/function.c index 99163e61a3c..54407fdb156 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -2756,9 +2756,11 @@ gen_mem_addressof (reg, decl) tree decl; { tree type = TREE_TYPE (decl); - rtx r = gen_rtx_ADDRESSOF (Pmode, gen_reg_rtx (GET_MODE (reg)), REGNO (reg)); SET_ADDRESSOF_DECL (r, decl); + /* If the original REG was a user-variable, then so is the REG whose + address is being taken. */ + REG_USERVAR_P (XEXP (r, 0)) = REG_USERVAR_P (reg); XEXP (reg, 0) = r; PUT_CODE (reg, MEM); diff --git a/gcc/loop.c b/gcc/loop.c index f1a59b35f8d..0a6cf059b44 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -871,19 +871,31 @@ scan_loop (loop_start, end, unroll_p, bct_p) We don't know its life-span, so we can't compute the benefit. */ if (REGNO (SET_DEST (set)) >= max_reg_before_loop) ; - /* In order to move a register, we need to have one of three cases: - (1) it is used only in the same basic block as the set - (2) it is not a user variable and it is not used in the - exit test (this can cause the variable to be used - before it is set just like a user-variable). - (3) the set is guaranteed to be executed once the loop starts, - and the reg is not used until after that. */ - else if (! ((! maybe_never - && ! loop_reg_used_before_p (set, p, loop_start, - scan_start, end)) - || (! REG_USERVAR_P (SET_DEST (set)) - && ! REG_LOOP_TEST_P (SET_DEST (set))) - || reg_in_basic_block_p (p, SET_DEST (set)))) + else if (/* The set is a user-variable or it is used in + the exit test (this can cause the variable to be + used before it is set just like a + user-variable)... */ + (REG_USERVAR_P (SET_DEST (set)) + || REG_LOOP_TEST_P (SET_DEST (set))) + /* And the set is not guaranteed to be executed one + the loop starts, or the value before the set is + needed before the set occurs... */ + && (maybe_never + || loop_reg_used_before_p (set, p, loop_start, + scan_start, end)) + /* And the register is used in basic blocks other + than the one where it is set (meaning that + something after this point in the loop might + depend on its value before the set). */ + && !reg_in_basic_block_p (p, SET_DEST (set))) + /* It is unsafe to move the set. The fact that these + three conditions are considered in conjunction means + that we are assuming various conditions, such as: + + o It's OK to move a set of a variable which was not + created by the user and is not used in an exit test + even if that point in the set would not be reached + during execution of the loop. */ ; else if ((tem = invariant_p (src)) && (dependencies == 0 diff --git a/gcc/testsuite/gcc.c-torture/execute/980929-1.c b/gcc/testsuite/gcc.c-torture/execute/980929-1.c new file mode 100644 index 00000000000..1d9246e01d7 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/980929-1.c @@ -0,0 +1,21 @@ +void f(int i) +{ + if (i != 1000) + abort (); +} + + +int main() +{ + int n=1000; + int i; + + f(n); + for(i=0; i<1; ++i) { + f(n); + n=666; + &n; + } + + exit (0); +}