]> gcc.gnu.org Git - gcc.git/commitdiff
(reg_to_stack): Use GET_RTX_CLASS.
authorRichard Kenner <kenner@gcc.gnu.org>
Mon, 28 Feb 1994 11:30:24 +0000 (06:30 -0500)
committerRichard Kenner <kenner@gcc.gnu.org>
Mon, 28 Feb 1994 11:30:24 +0000 (06:30 -0500)
Clear LABEL_REFs here.
(find_blocks): Make algorithm identical to that inreg_to_stack.
Use GET_RTX_CLASS.
Don't clear LABEL_REFs here.
Build a list of labels referenced by other than jumps.
If computed jump, mark using that list and forced_labels.
(uses_reg_or_mem): New function, copied from flow.c.

From-SVN: r6671

gcc/reg-stack.c

index 005f55493ea0dadad62e81ca5fa0bf9f8caf2198..14c5d346318d91820407087f56738ee99e958f9a 100644 (file)
@@ -1,5 +1,5 @@
 /* Register to Stack convert for GNU compiler.
-   Copyright (C) 1992, 1993 Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -229,6 +229,7 @@ static rtx FP_mode_reg[FIRST_PSEUDO_REGISTER][(int) MAX_MACHINE_MODE];
     ? (int *)(abort() , 0)             \
     : block_number)[INSN_UID (INSN)])
 
+extern rtx forced_labels;
 extern rtx gen_jump ();
 extern rtx gen_movdf (), gen_movxf ();
 extern rtx find_regno_note ();
@@ -238,6 +239,7 @@ extern rtx emit_label_after ();
 /* Forward declarations */
 
 static void find_blocks ();
+static uses_reg_or_mem ();
 static void stack_reg_life_analysis ();
 static void change_stack ();
 static void convert_regs ();
@@ -311,7 +313,8 @@ reg_to_stack (first, file)
     for (insn = first; insn; insn = NEXT_INSN (insn))
       {
        /* Note that this loop must select the same block boundaries
-          as code in find_blocks. */
+          as code in find_blocks.  Also note that this code is not the
+          same as that used in flow.c.  */
 
        if (INSN_UID (insn) > max_uid)
          max_uid = INSN_UID (insn);
@@ -322,14 +325,13 @@ reg_to_stack (first, file)
            || (prev_code != INSN
                && prev_code != CALL_INSN
                && prev_code != CODE_LABEL
-               && (code == INSN || code == CALL_INSN || code == JUMP_INSN)))
+               && GET_RTX_CLASS (code) == 'i'))
          blocks++;
 
        /* Remember whether or not this insn mentions an FP regs.
           Check JUMP_INSNs too, in case someone creates a funny PARALLEL. */
 
-       if ((GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
-            || GET_CODE (insn) == JUMP_INSN)
+       if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
            && stack_regs_mentioned_p (PATTERN (insn)))
          {
            stack_reg_seen = 1;
@@ -338,6 +340,9 @@ reg_to_stack (first, file)
        else
          PUT_MODE (insn, VOIDmode);
 
+       if (code == CODE_LABEL)
+         LABEL_REFS (insn) = insn; /* delete old chain */
+
        if (code != NOTE)
          prev_code = code;
       }
@@ -1171,8 +1176,9 @@ find_blocks (first)
 {
   register rtx insn;
   register int block;
-  register RTX_CODE prev_code = BARRIER;
+  register RTX_CODE prev_code = JUMP_INSN;
   register RTX_CODE code;
+  rtx label_value_list = 0;
 
   /* Record where all the blocks start and end.
      Record which basic blocks control can drop in to. */
@@ -1181,7 +1187,8 @@ find_blocks (first)
   for (insn = first; insn; insn = NEXT_INSN (insn))
     {
       /* Note that this loop must select the same block boundaries
-        as code in reg_to_stack. */
+        as code in reg_to_stack, but that these are not the same
+        as those selected in flow.c.  */
 
       code = GET_CODE (insn);
 
@@ -1189,19 +1196,27 @@ find_blocks (first)
          || (prev_code != INSN
              && prev_code != CALL_INSN
              && prev_code != CODE_LABEL
-             && (code == INSN || code == CALL_INSN || code == JUMP_INSN)))
+             && GET_RTX_CLASS (code) == 'i'))
        {
          block_begin[++block] = insn;
          block_end[block] = insn;
          block_drops_in[block] = prev_code != BARRIER;
        }
-      else if (code == INSN || code == CALL_INSN || code == JUMP_INSN)
+      else if (GET_RTX_CLASS (code) == 'i')
        block_end[block] = insn;
 
-      BLOCK_NUM (insn) = block;
+      if (GET_RTX_CLASS (code) == 'i')
+       {
+         rtx note;
+
+         /* Make a list of all labels referred to other than by jumps.  */
+         for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
+           if (REG_NOTE_KIND (note) == REG_LABEL)
+             label_value_list = gen_rtx (EXPR_LIST, VOIDmode, XEXP (note, 0),
+                                         label_value_list);
+       }
 
-      if (code == CODE_LABEL)
-       LABEL_REFS (insn) = insn; /* delete old chain */
+      BLOCK_NUM (insn) = block;
 
       if (code != NOTE)
        prev_code = code;
@@ -1216,8 +1231,82 @@ find_blocks (first)
       insn = block_end[block];
 
       if (GET_CODE (insn) == JUMP_INSN)
-       record_label_references (insn, PATTERN (insn));
+       {
+         rtx pat = PATTERN (insn);
+         int computed_jump = 0;
+         rtx x;
+
+         if (GET_CODE (pat) == PARALLEL)
+           {
+             int len = XVECLEN (pat, 0);
+             int has_use_labelref = 0;
+             int i;
+
+             for (i = len - 1; i >= 0; i--)
+               if (GET_CODE (XVECEXP (pat, 0, i)) == USE
+                   && GET_CODE (XEXP (XVECEXP (pat, 0, i), 0)) == LABEL_REF)
+                 has_use_labelref = 1;
+
+             if (! has_use_labelref)
+               for (i = len - 1; i >= 0; i--)
+                 if (GET_CODE (XVECEXP (pat, 0, i)) == SET
+                     && SET_DEST (XVECEXP (pat, 0, i)) == pc_rtx
+                     && uses_reg_or_mem (SET_SRC (XVECEXP (pat, 0, i))))
+                   computed_jump = 1;
+           }
+         else if (GET_CODE (pat) == SET
+                  && SET_DEST (pat) == pc_rtx
+                  && uses_reg_or_mem (SET_SRC (pat)))
+           computed_jump = 1;
+                   
+         if (computed_jump)
+           {
+             for (x = label_value_list; x; x = XEXP (x, 1))
+               record_label_references (insn,
+                                        gen_rtx (LABEL_REF, VOIDmode,
+                                                 XEXP (x, 0)));
+
+             for (x = forced_labels; x; x = XEXP (x, 1))
+               record_label_references (insn,
+                                        gen_rtx (LABEL_REF, VOIDmode,
+                                                 XEXP (x, 0)));
+           }
+
+         record_label_references (insn, pat);
+       }
+    }
+}
+
+/* Return 1 if X contain a REG or MEM that is not in the constant pool.  */
+
+static int
+uses_reg_or_mem (x)
+     rtx x;
+{
+  enum rtx_code code = GET_CODE (x);
+  int i, j;
+  char *fmt;
+
+  if (code == REG
+      || (code == MEM
+         && ! (GET_CODE (XEXP (x, 0)) == SYMBOL_REF
+               && CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)))))
+    return 1;
+
+  fmt = GET_RTX_FORMAT (code);
+  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+    {
+      if (fmt[i] == 'e'
+         && uses_reg_or_mem (XEXP (x, i)))
+       return 1;
+
+      if (fmt[i] == 'E')
+       for (j = 0; j < XVECLEN (x, i); j++)
+         if (uses_reg_or_mem (XVECEXP (x, i, j)))
+           return 1;
     }
+
+  return 0;
 }
 
 /* If current function returns its result in an fp stack register,
This page took 0.0670770000000001 seconds and 5 git commands to generate.