OSDN Git Service

* function.c (gen_mem_addressof): If the address REG is
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 30 Sep 1998 10:10:02 +0000 (10:10 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 30 Sep 1998 10:10:02 +0000 (10:10 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@22667 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/function.c
gcc/loop.c
gcc/testsuite/gcc.c-torture/execute/980929-1.c [new file with mode: 0644]

index b817601..b7d489f 100644 (file)
@@ -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
index 99163e6..54407fd 100644 (file)
@@ -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);
index f1a59b3..0a6cf05 100644 (file)
@@ -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 (file)
index 0000000..1d9246e
--- /dev/null
@@ -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);
+}