aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMark Mitchell <mark@markmitchell.com>1998-09-30 10:10:02 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>1998-09-30 10:10:02 +0000
commit95ca22f405ab053a5275610e22b869f595c8e68b (patch)
tree013f50ee70583c8416e79aa57fe911e240371d76 /gcc
parentee06cc21bf611f5e1fa1bc72ec901ac1d75ed62d (diff)
downloadgcc-95ca22f405ab053a5275610e22b869f595c8e68b.zip
gcc-95ca22f405ab053a5275610e22b869f595c8e68b.tar.gz
gcc-95ca22f405ab053a5275610e22b869f595c8e68b.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/function.c4
-rw-r--r--gcc/loop.c38
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/980929-1.c21
4 files changed, 56 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b817601..b7d489f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/function.c b/gcc/function.c
index 99163e6..54407fd 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 f1a59b3..0a6cf05 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 0000000..1d9246e
--- /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);
+}