re PR rtl-optimization/12142 (-fnon-call-exceptions generates incorrect code)
authorJohn David Anglin <dave.anglin@nrc-cnrc.gc.ca>
Wed, 8 Oct 2003 17:55:41 +0000 (17:55 +0000)
committerJohn David Anglin <danglin@gcc.gnu.org>
Wed, 8 Oct 2003 17:55:41 +0000 (17:55 +0000)
PR optimization/12142
* cse.c (count_reg_usage): In a SET with a REG SET_DEST, count the
uses of the register in the SET_SRC.  Remove unnecessary argument.
* pa.c (legitimize_pic_address): Before reload, use a scratch register
for the intermediate result in loading the address of a SYMBOL_REF.
Set the MEM_NOTRAP_P flag for the MEM.  Add a REG_EQUAL to the insn
which loads the SYMBOL_REF address.

From-SVN: r72234

gcc/ChangeLog
gcc/config/pa/pa.c
gcc/cse.c

index 72fd7ae..626e9aa 100644 (file)
@@ -1,3 +1,13 @@
+2003-10-08  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
+
+       PR optimization/12142
+       * cse.c (count_reg_usage): In a SET with a REG SET_DEST, count the
+       uses of the register in the SET_SRC.  Remove unnecessary argument.
+       * pa.c (legitimize_pic_address): Before reload, use a scratch register
+       for the intermediate result in loading the address of a SYMBOL_REF.
+       Set the MEM_NOTRAP_P flag for the MEM.  Add a REG_EQUAL to the insn
+       which loads the SYMBOL_REF address.
+
 2003-10-08  Timo Kokkonen  <tjko@iki.fi>
             Eric Botcazou  <ebotcazou@libertysurf.fr>
 
index a438ac4..366128c 100644 (file)
@@ -836,22 +836,35 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
     }
   if (GET_CODE (orig) == SYMBOL_REF)
     {
+      rtx insn, tmp_reg;
+
       if (reg == 0)
        abort ();
 
-      emit_move_insn (reg,
+      /* Before reload, allocate a temporary register for the intermediate
+        result.  This allows the sequence to be deleted when the final
+        result is unused and the insns are trivially dead.  */
+      tmp_reg = ((reload_in_progress || reload_completed)
+                ? reg : gen_reg_rtx (Pmode));
+
+      emit_move_insn (tmp_reg,
                      gen_rtx_PLUS (word_mode, pic_offset_table_rtx,
                                    gen_rtx_HIGH (word_mode, orig)));
       pic_ref
        = gen_rtx_MEM (Pmode,
-                      gen_rtx_LO_SUM (Pmode, reg,
+                      gen_rtx_LO_SUM (Pmode, tmp_reg,
                                       gen_rtx_UNSPEC (Pmode,
                                                       gen_rtvec (1, orig),
                                                       0)));
 
       current_function_uses_pic_offset_table = 1;
+      MEM_NOTRAP_P (pic_ref) = 1;
       RTX_UNCHANGING_P (pic_ref) = 1;
-      emit_move_insn (reg, pic_ref);
+      insn = emit_move_insn (reg, pic_ref);
+
+      /* Put a REG_EQUAL note on this insn, so that it can be optimized.  */
+      REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, orig, REG_NOTES (insn));
+
       return reg;
     }
   else if (GET_CODE (orig) == CONST)
index 30355df..8683f4a 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -647,7 +647,7 @@ static void invalidate_skipped_block (rtx);
 static void cse_check_loop_start (rtx, rtx, void *);
 static void cse_set_around_loop (rtx, rtx, rtx);
 static rtx cse_basic_block (rtx, rtx, struct branch_path *, int);
-static void count_reg_usage (rtx, int *, rtx, int);
+static void count_reg_usage (rtx, int *, int);
 static int check_for_label_ref (rtx *, void *);
 extern void dump_class (struct table_elt*);
 static struct cse_reg_info * get_cse_reg_info (unsigned int);
@@ -7301,14 +7301,10 @@ check_for_label_ref (rtx *rtl, void *data)
 \f
 /* Count the number of times registers are used (not set) in X.
    COUNTS is an array in which we accumulate the count, INCR is how much
-   we count each register usage.
-
-   Don't count a usage of DEST, which is the SET_DEST of a SET which
-   contains X in its SET_SRC.  This is because such a SET does not
-   modify the liveness of DEST.  */
+   we count each register usage.  */
 
 static void
-count_reg_usage (rtx x, int *counts, rtx dest, int incr)
+count_reg_usage (rtx x, int *counts, int incr)
 {
   enum rtx_code code;
   rtx note;
@@ -7321,8 +7317,7 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr)
   switch (code = GET_CODE (x))
     {
     case REG:
-      if (x != dest)
-       counts[REGNO (x)] += incr;
+      counts[REGNO (x)] += incr;
       return;
 
     case PC:
@@ -7339,25 +7334,23 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr)
       /* If we are clobbering a MEM, mark any registers inside the address
          as being used.  */
       if (GET_CODE (XEXP (x, 0)) == MEM)
-       count_reg_usage (XEXP (XEXP (x, 0), 0), counts, NULL_RTX, incr);
+       count_reg_usage (XEXP (XEXP (x, 0), 0), counts, incr);
       return;
 
     case SET:
       /* Unless we are setting a REG, count everything in SET_DEST.  */
       if (GET_CODE (SET_DEST (x)) != REG)
-       count_reg_usage (SET_DEST (x), counts, NULL_RTX, incr);
-      count_reg_usage (SET_SRC (x), counts,
-                      SET_DEST (x),
-                      incr);
+       count_reg_usage (SET_DEST (x), counts, incr);
+      count_reg_usage (SET_SRC (x), counts, incr);
       return;
 
     case CALL_INSN:
-      count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, NULL_RTX, incr);
+      count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, incr);
       /* Fall through.  */
 
     case INSN:
     case JUMP_INSN:
-      count_reg_usage (PATTERN (x), counts, NULL_RTX, incr);
+      count_reg_usage (PATTERN (x), counts, incr);
 
       /* Things used in a REG_EQUAL note aren't dead since loop may try to
         use them.  */
@@ -7372,12 +7365,12 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr)
             Process all the arguments.  */
            do
              {
-               count_reg_usage (XEXP (eqv, 0), counts, NULL_RTX, incr);
+               count_reg_usage (XEXP (eqv, 0), counts, incr);
                eqv = XEXP (eqv, 1);
              }
            while (eqv && GET_CODE (eqv) == EXPR_LIST);
          else
-           count_reg_usage (eqv, counts, NULL_RTX, incr);
+           count_reg_usage (eqv, counts, incr);
        }
       return;
 
@@ -7387,19 +7380,15 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr)
          /* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)),
             involving registers in the address.  */
          || GET_CODE (XEXP (x, 0)) == CLOBBER)
-       count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr);
+       count_reg_usage (XEXP (x, 0), counts, incr);
 
-      count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr);
+      count_reg_usage (XEXP (x, 1), counts, incr);
       return;
 
     case ASM_OPERANDS:
-      /* If the asm is volatile, then this insn cannot be deleted,
-        and so the inputs *must* be live.  */
-      if (MEM_VOLATILE_P (x))
-       dest = NULL_RTX;
       /* Iterate over just the inputs, not the constraints as well.  */
       for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
-       count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, dest, incr);
+       count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, incr);
       return;
 
     case INSN_LIST:
@@ -7413,10 +7402,10 @@ count_reg_usage (rtx x, int *counts, rtx dest, int incr)
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     {
       if (fmt[i] == 'e')
-       count_reg_usage (XEXP (x, i), counts, dest, incr);
+       count_reg_usage (XEXP (x, i), counts, incr);
       else if (fmt[i] == 'E')
        for (j = XVECLEN (x, i) - 1; j >= 0; j--)
-         count_reg_usage (XVECEXP (x, i, j), counts, dest, incr);
+         count_reg_usage (XVECEXP (x, i, j), counts, incr);
     }
 }
 \f
@@ -7508,11 +7497,11 @@ dead_libcall_p (rtx insn, int *counts)
     new = XEXP (note, 0);
 
   /* While changing insn, we must update the counts accordingly.  */
-  count_reg_usage (insn, counts, NULL_RTX, -1);
+  count_reg_usage (insn, counts, -1);
 
   if (validate_change (insn, &SET_SRC (set), new, 0))
     {
-      count_reg_usage (insn, counts, NULL_RTX, 1);
+      count_reg_usage (insn, counts, 1);
       remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
       remove_note (insn, note);
       return true;
@@ -7523,14 +7512,14 @@ dead_libcall_p (rtx insn, int *counts)
       new = force_const_mem (GET_MODE (SET_DEST (set)), new);
       if (new && validate_change (insn, &SET_SRC (set), new, 0))
        {
-         count_reg_usage (insn, counts, NULL_RTX, 1);
+         count_reg_usage (insn, counts, 1);
          remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
          remove_note (insn, note);
          return true;
        }
     }
 
-  count_reg_usage (insn, counts, NULL_RTX, 1);
+  count_reg_usage (insn, counts, 1);
   return false;
 }
 
@@ -7554,7 +7543,7 @@ delete_trivially_dead_insns (rtx insns, int nreg)
   /* First count the number of times each register is used.  */
   counts = xcalloc (nreg, sizeof (int));
   for (insn = next_real_insn (insns); insn; insn = next_real_insn (insn))
-    count_reg_usage (insn, counts, NULL_RTX, 1);
+    count_reg_usage (insn, counts, 1);
 
   do
     {
@@ -7598,7 +7587,7 @@ delete_trivially_dead_insns (rtx insns, int nreg)
 
          if (! live_insn)
            {
-             count_reg_usage (insn, counts, NULL_RTX, -1);
+             count_reg_usage (insn, counts, -1);
              delete_insn_and_edges (insn);
              ndead++;
            }