OSDN Git Service

* alpha.c (final_prescan_insn): Gut, remove and transform to ...
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Oct 1997 01:23:23 +0000 (01:23 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 16 Oct 1997 01:23:23 +0000 (01:23 +0000)
        (alpha_handle_trap_shadows): ... a new function.  Handle the entire
        function in one go.  Emit RTL for trapb, instead of printf directly.
        (alpha_reorg): New function.  Call alpha_handle_trap_shadows.
        (trap_pending): Kill global variable.
        (output_epilog): Don't call final_prescan_insn.
        (struct shadow_summary): Elide $31 and $f31; now it fits in a word.
        * alpha.h (FINAL_PRESCAN_INSN): Remove.
        (MACHINE_DEPENENT_REORG): Define.
        * alpha.md (jsr patterns with trapb): Stupid and useless.  Kill.
        (trapb): New insn.

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

gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/alpha.md

index e20e7c3..368d212 100644 (file)
@@ -1,3 +1,17 @@
+Wed Oct 15 18:21:46 1997  Richard Henderson  <rth@cygnus.com>
+
+       * alpha.c (final_prescan_insn): Gut, remove and transform to ...
+       (alpha_handle_trap_shadows): ... a new function.  Handle the entire
+       function in one go.  Emit RTL for trapb, instead of printf directly.
+       (alpha_reorg): New function.  Call alpha_handle_trap_shadows.
+       (trap_pending): Kill global variable.
+       (output_epilog): Don't call final_prescan_insn.
+       (struct shadow_summary): Elide $31 and $f31; now it fits in a word.
+       * alpha.h (FINAL_PRESCAN_INSN): Remove.
+       (MACHINE_DEPENENT_REORG): Define.
+       * alpha.md (jsr patterns with trapb): Stupid and useless.  Kill.
+       (trapb): New insn.
+
 Wed Oct 15 18:16:05 1997  Richard Henderson  <rth@cygnus.com>
 
        Tune Haifa scheduler for Alpha:
index 8990c5b..28435f9 100644 (file)
@@ -75,10 +75,6 @@ char *alpha_function_name;
 
 static int inside_function = FALSE;
 
-/* Non-zero if an instruction that may cause a trap is pending.  */
-
-static int trap_pending = 0;
-
 /* Nonzero if the current function needs gp.  */
 
 int alpha_function_needs_gp;
@@ -2599,8 +2595,6 @@ output_epilog (file, size)
       int fp_offset = 0;
       int sa_reg;
 
-      final_prescan_insn (NULL_RTX, NULL_PTR, 0);
-
       /* If we have a frame pointer, restore SP from it.  */
       if (frame_pointer_needed)
        fprintf (file, "\tbis $15,$15,$30\n");
@@ -2791,8 +2785,8 @@ alpha_output_lineno (stream, line)
 struct shadow_summary
 {
   struct {
-    unsigned long i     : 32;  /* Mask of int regs */
-    unsigned long fp    : 32;  /* Mask of fp regs */
+    unsigned long i     : 31;  /* Mask of int regs */
+    unsigned long fp    : 31;  /* Mask of fp regs */
     unsigned long mem   :  1;  /* mem == imem | fpmem */
   } used, defd;
 };
@@ -2915,19 +2909,9 @@ summarize_insn (x, sum, set)
          }
     }
 }
-\f
-/* This function is executed just prior to the output of assembler code for
-   INSN to modify the extracted operands so they will be output differently.
-
-   OPVEC is the vector containing the operands extracted from INSN, and
-   NOPERANDS is the number of elements of the vector which contain meaningful
-   data for this insn.  The contents of this vector are what will be used to
-   convert the insn template into assembler code, so you can change the
-   assembler output by changing the contents of the vector.
 
-   We use this function to ensure a sufficient number of `trapb' instructions
-   are in the code when the user requests code with a trap precision of
-   functions or instructions.
+/* Ensure a sufficient number of `trapb' insns are in the code when the user
+   requests code with a trap precision of functions or instructions.
 
    In naive mode, when the user requests a trap-precision of "instruction", a
    trapb is needed after every instruction that may generate a trap (and after
@@ -2953,103 +2937,151 @@ summarize_insn (x, sum, set)
    (c) Within the trap shadow, no register may be used more than once as a
    destination register.  (This is to make life easier for the trap-handler.)
 
-   (d) The trap shadow may not include any branch instructions.
-
-     */
+   (d) The trap shadow may not include any branch instructions.  */
 
-void
-final_prescan_insn (insn, opvec, noperands)
-     rtx insn;
-     rtx *opvec;
-     int noperands;
+static void
+alpha_handle_trap_shadows (insns)
+     rtx insns;
 {
-  static struct shadow_summary shadow = {0, 0, 0, 0, 0};
+  struct shadow_summary shadow;
+  int trap_pending, exception_nesting;
+  rtx i;
 
-#define CLOSE_SHADOW                           \
-  do                                           \
-    {                                          \
-      fputs ("\ttrapb\n", asm_out_file);       \
-      trap_pending = 0;                                \
-      bzero ((char *) &shadow,  sizeof shadow);        \
-    }                                          \
-  while (0)
-
-  if (alpha_tp == ALPHA_TP_PROG)
+  if (alpha_tp == ALPHA_TP_PROG && !flag_exceptions)
     return;
 
-  if (trap_pending)
-    switch (alpha_tp)
-      {
-      case ALPHA_TP_FUNC:
-       /* Generate one trapb before epilogue (indicated by INSN==0) */
-       if (insn == 0)
-         CLOSE_SHADOW;
-       break;
-
-      case ALPHA_TP_INSN:
-       if (optimize && insn != 0)
-         {
-           struct shadow_summary sum = {0, 0, 0};
-
-           switch (GET_CODE(insn))
-             {
-             case INSN:
-               summarize_insn (PATTERN (insn), &sum, 0);
-
-               if ((sum.defd.i & shadow.defd.i)
-                   || (sum.defd.fp & shadow.defd.fp))
-                 {
-                   /* (c) would be violated */
-                   CLOSE_SHADOW;
-                   break;
-                 }
-
-               /* Combine shadow with summary of current insn: */
-               shadow.used.i     |= sum.used.i;
-               shadow.used.fp    |= sum.used.fp;
-               shadow.used.mem   |= sum.used.mem;
-               shadow.defd.i     |= sum.defd.i;
-               shadow.defd.fp    |= sum.defd.fp;
-               shadow.defd.mem   |= sum.defd.mem;
-
-               if ((sum.defd.i & shadow.used.i)
-                   || (sum.defd.fp & shadow.used.fp)
-                   || (sum.defd.mem & shadow.used.mem))
-                 {
-                   /* (a) would be violated (also takes care of (b)).  */
-                   if (get_attr_trap (insn) == TRAP_YES
-                       && ((sum.defd.i & sum.used.i)
-                           || (sum.defd.fp & sum.used.fp)))
+  trap_pending = 0;
+  exception_nesting = 0;
+  shadow.used.i = 0;
+  shadow.used.fp = 0;
+  shadow.used.mem = 0;
+  shadow.defd = shadow.used;
+  
+  for (i = insns; i ; i = NEXT_INSN (i))
+    {
+      if (GET_CODE (i) == NOTE)
+       {
+         switch (NOTE_LINE_NUMBER (i))
+           {
+           case NOTE_INSN_EH_REGION_BEG:
+             exception_nesting++;
+             if (trap_pending)
+               goto close_shadow;
+             break;
+
+           case NOTE_INSN_EH_REGION_END:
+             exception_nesting--;
+             if (trap_pending)
+               goto close_shadow;
+             break;
+
+           case NOTE_INSN_EPILOGUE_BEG:
+             if (trap_pending && alpha_tp >= ALPHA_TP_FUNC)
+               goto close_shadow;
+             break;
+           }
+       }
+      else if (trap_pending)
+       {
+         if (alpha_tp == ALPHA_TP_FUNC)
+           {
+             if (GET_CODE (i) == JUMP_INSN
+                 && GET_CODE (PATTERN (i)) == RETURN)
+               goto close_shadow;
+           }
+         else if (alpha_tp == ALPHA_TP_INSN)
+           {
+             if (optimize > 0)
+               {
+                 struct shadow_summary sum;
+
+                 sum.used.i = 0;
+                 sum.used.fp = 0;
+                 sum.used.mem = 0;
+                 sum.defd = shadow.used;
+
+                 switch (GET_CODE (i))
+                   {
+                   case INSN:
+                     /* Annoyingly, get_attr_trap will abort on USE.  */
+                     if (GET_CODE (PATTERN (i)) == USE)
+                       break;
+
+                     summarize_insn (PATTERN (i), &sum, 0);
+
+                     if ((sum.defd.i & shadow.defd.i)
+                         || (sum.defd.fp & shadow.defd.fp))
+                       {
+                         /* (c) would be violated */
+                         goto close_shadow;
+                       }
+
+                     /* Combine shadow with summary of current insn: */
+                     shadow.used.i   |= sum.used.i;
+                     shadow.used.fp  |= sum.used.fp;
+                     shadow.used.mem |= sum.used.mem;
+                     shadow.defd.i   |= sum.defd.i;
+                     shadow.defd.fp  |= sum.defd.fp;
+                     shadow.defd.mem |= sum.defd.mem;
+
+                     if ((sum.defd.i & shadow.used.i)
+                         || (sum.defd.fp & shadow.used.fp)
+                         || (sum.defd.mem & shadow.used.mem))
+                       {
+                         /* (a) would be violated (also takes care of (b))  */
+                         if (get_attr_trap (i) == TRAP_YES
+                             && ((sum.defd.i & sum.used.i)
+                                 || (sum.defd.fp & sum.used.fp)))
+                           abort ();
+
+                         goto close_shadow;
+                       }
+                     break;
+
+                   case JUMP_INSN:
+                   case CALL_INSN:
+                   case CODE_LABEL:
+                     goto close_shadow;
+
+                   default:
                      abort ();
+                   }
+               }
+             else
+               {
+               close_shadow:
+                 emit_insn_before (gen_trapb (), i);
+                 trap_pending = 0;
+                 shadow.used.i = 0;
+                 shadow.used.fp = 0;
+                 shadow.used.mem = 0;
+                 shadow.defd = shadow.used;
+               }
+           }
+       }
 
-                   CLOSE_SHADOW;
-                   break;
-                 }
-               break;
-
-             case JUMP_INSN:
-             case CALL_INSN:
-             case CODE_LABEL:
-               CLOSE_SHADOW;
-               break;
-
-             default:
-               abort ();
-             }
+      if (exception_nesting > 0 || alpha_tp >= ALPHA_TP_FUNC)
+       if (GET_CODE (i) == INSN
+           && GET_CODE (PATTERN (i)) != USE
+           && get_attr_trap (i) == TRAP_YES)
+         {
+           if (optimize && !trap_pending)
+             summarize_insn (PATTERN (i), &shadow, 0);
+           trap_pending = 1;
          }
-       else
-         CLOSE_SHADOW;
-       break;
-      }
-
-  if (insn != 0 && get_attr_trap (insn) == TRAP_YES)
-    {
-      if (optimize && !trap_pending && GET_CODE (insn) == INSN)
-       summarize_insn (PATTERN (insn), &shadow, 0);
-      trap_pending = 1;
     }
 }
 
+/* Machine dependant reorg pass.  */
+
+void
+alpha_reorg (insns)
+     rtx insns;
+{
+  alpha_handle_trap_shadows (insns);
+}
+
+\f
 /* Check a floating-point value for validity for a particular machine mode.  */
 
 static char *float_strings[] =
index 0829c07..8c8cf5c 100644 (file)
@@ -1463,15 +1463,8 @@ __enable_execute_stack (addr)                                            \
 
 #define ADDRESS_COST(X)  0
 
-/* Define this if some processing needs to be done immediately before
-   emitting code for an insn.  */
-
-extern void final_prescan_insn ();
-#define FINAL_PRESCAN_INSN(INSN,OPERANDS,NOPERANDS) \
-  final_prescan_insn ((INSN), (OPERANDS), (NOPERANDS))
-
-/* Define this if FINAL_PRESCAN_INSN should be called for a CODE_LABEL.  */
-#define FINAL_PRESCAN_LABEL
+/* Machine-dependent reorg pass.   */
+#define MACHINE_DEPENDENT_REORG(X)     alpha_reorg(X)
 \f
 /* Specify the machine mode that this machine uses
    for the index in the tablejump instruction.  */
index 5f760a5..1240d56 100644 (file)
         (match_operand 1 "" ""))
    (clobber (reg:DI 27))
    (clobber (reg:DI 26))]
-  "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && alpha_tp == ALPHA_TP_INSN"
-  "@
-   jsr $26,($27),0\;trapb\;ldgp $29,4($26)
-   bsr $26,%0..ng\;trapb
-   jsr $26,%0\;trapb\;ldgp $29,4($26)"
-  [(set_attr "type" "jsr,jsr,ibr")])
-      
-(define_insn ""
-  [(call (mem:DI (match_operand:DI 0 "call_operand" "r,R,i"))
-        (match_operand 1 "" ""))
-   (clobber (reg:DI 27))
-   (clobber (reg:DI 26))]
   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
   "@
    jsr $26,($27),0\;ldgp $29,0($26)
              (match_operand 2 "" "")))
    (clobber (reg:DI 27))
    (clobber (reg:DI 26))]
-  "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS && alpha_tp == ALPHA_TP_INSN"
-  "@
-   jsr $26,($27),0\;trapb\;ldgp $29,4($26)
-   bsr $26,%1..ng\;trapb
-   jsr $26,%1\;trapb\;ldgp $29,4($26)"
-  [(set_attr "type" "jsr,jsr,ibr")])
-
-(define_insn ""
-  [(set (match_operand 0 "register_operand" "=rf,rf,rf")
-       (call (mem:DI (match_operand:DI 1 "call_operand" "r,R,i"))
-             (match_operand 2 "" "")))
-   (clobber (reg:DI 27))
-   (clobber (reg:DI 26))]
   "! TARGET_WINDOWS_NT && ! TARGET_OPEN_VMS"
   "@
    jsr $26,($27),0\;ldgp $29,0($26)
    (clobber (reg:DI 0))]
   "TARGET_OPEN_VMS"
   "lda $0,ots$home_args\;ldq $0,8($0)\;jsr $0,ots$home_args")
+
+;; Close the trap shadow of preceeding instructions.  This is generated
+;; by alpha_reorg.
+
+(define_insn "trapb"
+  [(unspec_volatile [(const_int 0)] 3)]
+  ""
+  "trapb"
+  [(set_attr "type" "misc")])