]> gcc.gnu.org Git - gcc.git/commitdiff
*** empty log message ***
authorRichard Kenner <kenner@gcc.gnu.org>
Sat, 11 Apr 1992 18:17:54 +0000 (14:17 -0400)
committerRichard Kenner <kenner@gcc.gnu.org>
Sat, 11 Apr 1992 18:17:54 +0000 (14:17 -0400)
From-SVN: r726

gcc/genextract.c
gcc/reload.c
gcc/reload.h
gcc/reload1.c
gcc/tree.c

index 74899a33a2415cca04e7ebf91b6f6832dc09e5b7..121fa302f42bd4124c279ea38f7cd93424c41d26 100644 (file)
@@ -110,8 +110,8 @@ gen_insn (insn)
   for (; i >= 0; i--)
     if (!operand_seen[i])
       {
-       printf ("      recog_operand[%d] = const0_rtx;\n", i);
-       printf ("      recog_operand_loc[%d] = &junk;\n", i);
+       printf ("      ro[%d] = const0_rtx;\n", i);
+       printf ("      ro_loc[%d] = &junk;\n", i);
       }
   printf ("      break;\n");
 }
@@ -158,7 +158,7 @@ walk_rtx (x, path)
     case MATCH_OPERAND:
     case MATCH_SCRATCH:
       mark_operand_seen (XINT (x, 0));
-      printf ("      recog_operand[%d] = *(recog_operand_loc[%d]\n        = &",
+      printf ("      ro[%d] = *(ro_loc[%d] = &",
              XINT (x, 0), XINT (x, 0));
       print_path (path);
       printf (");\n");
@@ -175,7 +175,7 @@ walk_rtx (x, path)
 
     case MATCH_OPERATOR:
       mark_operand_seen (XINT (x, 0));
-      printf ("      recog_operand[%d] = *(recog_operand_loc[%d]\n        = &",
+      printf ("      ro[%d] = *(ro_loc[%d]\n        = &",
              XINT (x, 0), XINT (x, 0));
       print_path (path);
       printf (");\n");
@@ -190,7 +190,7 @@ walk_rtx (x, path)
 
     case MATCH_PARALLEL:
       mark_operand_seen (XINT (x, 0));
-      printf ("      recog_operand[%d] = *(recog_operand_loc[%d]\n        = &",
+      printf ("      ro[%d] = *(ro_loc[%d]\n        = &",
              XINT (x, 0), XINT (x, 0));
       print_path (path);
       printf (");\n");
@@ -350,11 +350,14 @@ from the machine description file `md'.  */\n\n");
   printf ("extern rtx *recog_operand_loc[];\n");
   printf ("extern rtx *recog_dup_loc[];\n");
   printf ("extern char recog_dup_num[];\n");
-  printf ("extern void fatal_insn_not_found ();\n\n");
+  printf ("extern\n#ifdef __GNUC__\nvolatile\n#endif\n");
+  printf ("void fatal_insn_not_found ();\n\n");
 
   printf ("void\ninsn_extract (insn)\n");
   printf ("     rtx insn;\n");
   printf ("{\n");
+  printf ("  register rtx *ro = recog_operand;\n");
+  printf ("  register rtx **ro_loc = recog_operand_loc;\n");
   printf ("  int insn_code = INSN_CODE (insn);\n");
   printf ("  if (insn_code == -1) fatal_insn_not_found (insn);\n");
   printf ("  insn = PATTERN (insn);\n");
@@ -401,7 +404,7 @@ from the machine description file `md'.  */\n\n");
       printf ("#if __GNUC__ > 1 && !defined (bcopy)\n");
       printf ("#define bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)\n");
       printf ("#endif\n");
-      printf ("      bcopy (&XVECEXP (insn, 0, 0), recog_operand,\n");
+      printf ("      bcopy (&XVECEXP (insn, 0, 0), ro,\n");
       printf ("             sizeof (rtx) * XVECLEN (insn, 0));\n");
       printf ("      break;\n");
     }
index f7f1fc335187134c51469ac028f994d80b366d70..05c1a2737dcfd724e123a711aa2261eb1249a781 100644 (file)
@@ -4179,6 +4179,46 @@ copy_replacements (x, y)
        }
 }
 \f
+/* If LOC was scheduled to be replaced by something, return the replacement.
+   Otherwise, return *LOC.  */
+
+rtx
+find_replacement (loc)
+     rtx *loc;
+{
+  struct replacement *r;
+
+  for (r = &replacements[0]; r < &replacements[n_replacements]; r++)
+    {
+      rtx reloadreg = reload_reg_rtx[r->what];
+
+      if (reloadreg && r->where == loc)
+       {
+         if (r->mode != VOIDmode && GET_MODE (reloadreg) != r->mode)
+           reloadreg = gen_rtx (REG, r->mode, REGNO (reloadreg));
+
+         return reloadreg;
+       }
+      else if (reloadreg && r->subreg_loc == loc)
+       {
+         /* RELOADREG must be either a REG or a SUBREG.
+
+            ??? Is it actually still ever a SUBREG?  If so, why?  */
+
+         if (GET_CODE (reloadreg) == REG)
+           return gen_rtx (REG, GET_MODE (*loc),
+                           REGNO (reloadreg) + SUBREG_WORD (*loc));
+         else if (GET_MODE (reloadreg) == GET_MODE (*loc))
+           return reloadreg;
+         else
+           return gen_rtx (SUBREG, GET_MODE (*loc), SUBREG_REG (reloadreg),
+                           SUBREG_WORD (reloadreg) + SUBREG_WORD (*loc));
+       }
+    }
+
+  return *loc;
+}
+\f
 /* Return nonzero if register in range [REGNO, ENDREGNO)
    appears either explicitly or implicitly in X
    other than being stored into.
index 1f1fed7cfa40cbcf3fd545895a5d81e3923ca939..e7b21446c4680204b2bf119ff1ebb9d35bcf9a5b 100644 (file)
@@ -110,3 +110,4 @@ extern void find_reloads ();
 extern void subst_reloads ();
 extern rtx eliminate_regs ();
 extern rtx gen_input_reload ();
+extern rtx find_replacement ();
index fea5758eacb72a56f149d6dca0897652051ed918..bac9c2f29e121865bfd20280cc74ef4e583d6ada 100644 (file)
@@ -5428,9 +5428,12 @@ gen_input_reload (reloadreg, in, before_insn)
         `insn_extract'and it is simpler to emit and then delete the insn if
         not valid than to dummy things up.  */
 
-      rtx move_operand, other_operand, insn;
+      rtx op0, op1, tem, insn;
       int code;
 
+      op0 = find_replacement (&XEXP (in, 0));
+      op1 = find_replacement (&XEXP (in, 1));
+
       /* Since constraint checking is strict, commutativity won't be
         checked, so we need to do that here to avoid spurious failure
         if the add instruction is two-address and the second operand
@@ -5440,7 +5443,10 @@ gen_input_reload (reloadreg, in, before_insn)
 
       if (GET_CODE (XEXP (in, 1)) == REG
          && REGNO (reloadreg) == REGNO (XEXP (in, 1)))
-       in = gen_rtx (PLUS, GET_MODE (in), XEXP (in, 1), XEXP (in, 0));
+       tem = op0, op0 = op1, op1 = tem;
+
+      if (op0 != XEXP (in, 0) || op1 != XEXP (in, 1))
+       in = gen_rtx (PLUS, GET_MODE (in), op0, op1);
 
       insn = emit_insn_before (gen_rtx (SET, VOIDmode, reloadreg, in),
                                   before_insn);
@@ -5463,23 +5469,20 @@ gen_input_reload (reloadreg, in, before_insn)
 
       /* If that failed, we must use a conservative two-insn sequence.
         use move to copy constant, MEM, or pseudo register to the reload
-        register since "move" will be able to handle arbitrary operand, unlike
-        add which can't, in general.  Then add the registers.
+        register since "move" will be able to handle an arbitrary operand,
+        unlike add which can't, in general.  Then add the registers.
 
         If there is another way to do this for a specific machine, a
         DEFINE_PEEPHOLE should be specified that recognizes the sequence
         we emit below.  */
 
-      if (CONSTANT_P (XEXP (in, 1))
-         || GET_CODE (XEXP (in, 1)) == MEM
-         || (GET_CODE (XEXP (in, 1)) == REG
-             && REGNO (XEXP (in, 1)) >= FIRST_PSEUDO_REGISTER))
-       move_operand = XEXP (in, 1), other_operand = XEXP (in, 0);
-      else
-       move_operand = XEXP (in, 0), other_operand = XEXP (in, 1);
+      if (CONSTANT_P (op1) || GET_CODE (op1) == MEM
+         || (GET_CODE (op1) == REG
+             && REGNO (op1) >= FIRST_PSEUDO_REGISTER))
+       tem = op0, op0 = op1, op1 = tem;
 
-      emit_insn_before (gen_move_insn (reloadreg, move_operand), before_insn);
-      emit_insn_before (gen_add2_insn (reloadreg, other_operand), before_insn);
+      emit_insn_before (gen_move_insn (reloadreg, op0), before_insn);
+      emit_insn_before (gen_add2_insn (reloadreg, op1), before_insn);
     }
 
   /* If IN is a simple operand, use gen_move_insn.  */
index c6a74a11c6dfa2040568edd3f7562e5a9307c95f..2b914a66d731c9e60f8460e4b0a82f93ebab7467 100644 (file)
@@ -1742,10 +1742,12 @@ save_expr (expr)
 
   /* If the tree evaluates to a constant, then we don't want to hide that
      fact (i.e. this allows further folding, and direct checks for constants).
+     However, a read-only object that has side effects cannot be bypassed.
      Since it is no problem to reevaluate literals, we just return the 
      literal node. */
 
-  if (TREE_CONSTANT (t) || TREE_READONLY (t) || TREE_CODE (t) == SAVE_EXPR)
+  if (TREE_CONSTANT (t) || (TREE_READONLY (t) && ! TREE_SIDE_EFFECTS (t))
+      || TREE_CODE (t) == SAVE_EXPR)
     return t;
 
   t = build (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl, NULL);
@@ -1852,7 +1854,12 @@ stabilize_reference_1 (e)
   register int length;
   register enum tree_code code = TREE_CODE (e);
 
-  if (TREE_CONSTANT (e) || TREE_READONLY (e) || code == SAVE_EXPR)
+  /* We cannot ignore const expressions because it might be a reference
+     to a const array but whose index contains side-effects.  But we can
+     ignore things that are actual constant or that already have been
+     handled by this function.  */
+
+  if (TREE_CONSTANT (e) || code == SAVE_EXPR)
     return e;
 
   switch (TREE_CODE_CLASS (code))
This page took 0.07673 seconds and 5 git commands to generate.