mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-22 22:01:20 +08:00
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
This commit is contained in:
parent
ee06cc21bf
commit
95ca22f405
@ -1,3 +1,10 @@
|
||||
Wed Sep 30 10:09:39 1998 Mark Mitchell <mark@markmitchell.com>
|
||||
|
||||
* 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
|
||||
|
@ -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);
|
||||
|
38
gcc/loop.c
38
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
|
||||
|
21
gcc/testsuite/gcc.c-torture/execute/980929-1.c
Normal file
21
gcc/testsuite/gcc.c-torture/execute/980929-1.c
Normal file
@ -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);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user