OSDN Git Service

PR rtl-optimization/45394
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Oct 2010 14:25:04 +0000 (14:25 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 6 Oct 2010 14:25:04 +0000 (14:25 +0000)
* combine.c (cleanup_auto_inc_dec): Remove AFTER parameter and adjust.
(struct rtx_subst_pair): Remove AFTER field.
(propagate_for_debug_subst): Adjust call to cleanup_auto_inc_dec.
(propagate_for_debug): Remove MOVE parameter and adjust.
(try_combine): In the special case where I2 is a PARALLEL, combine only
destinations of SETs and set I2SRC to the I2 source.
Adjust calls to propagate_for_debug throughout.
* reload1.c (eliminate_regs_1) <ASM_OPERANDS>: Do not abort for debug
insns.

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

gcc/ChangeLog
gcc/combine.c
gcc/reload1.c
gcc/testsuite/ChangeLog
gcc/testsuite/gnat.dg/opt6.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/opt6.ads [new file with mode: 0644]

index 441293c..bcd9f89 100644 (file)
@@ -1,13 +1,27 @@
+2010-10-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR rtl-optimization/45394
+       * combine.c (cleanup_auto_inc_dec): Remove AFTER parameter and adjust.
+       (struct rtx_subst_pair): Remove AFTER field.
+       (propagate_for_debug_subst): Adjust call to cleanup_auto_inc_dec.
+       (propagate_for_debug): Remove MOVE parameter and adjust.
+       (try_combine): In the special case where I2 is a PARALLEL, combine only
+       destinations of SETs and set I2SRC to the I2 source.
+       Adjust calls to propagate_for_debug throughout.
+       * reload1.c (eliminate_regs_1) <ASM_OPERANDS>: Do not abort for debug
+       insns.
+
 2010-10-06  Olivier Hainque  <hainque@adacore.com>
 
        * config/rs6000/rs6000.c (rs6000_expand_ternop_builtin): Rewrite
        switch on insn codes as sequence of ifs.
 
-2010-10-06  Hariharan Sandanagobalane <hariharan@picochip.com>
+2010-10-06  Hariharan Sandanagobalane  <hariharan@picochip.com>
+
        * config/picochip/picochip.c (TARGET_EXCEPT_UNWIND_INFO): Define it to
        be UI_NONE for picochip.
        (picochip_option_override): Do not disable exception flags.
-       * config/picochip/picochip-protos.h (picochip_except_unwind_info)
+       * config/picochip/picochip-protos.h (picochip_except_unwind_info):
        Declare.
 
 2010-10-06  Richard Guenther  <rguenther@suse.de>
        * cgraphunit.c (assemble_function): Output thunks and aliases before
        the function itself.
 
-2010-09-29  Hariharan Sandanagobalane <hariharan@picochip.com>
+2010-09-29  Hariharan Sandanagobalane  <hariharan@picochip.com>
 
        * config/picochip/picochip.c (picochip_option_override): Disable
        exception flags for picochip.
        * sel-sched.c: Use HARD_FRAME_POINTER_IS_FRAME_POINTER
        * stmt.c: Use HARD_FRAME_POINTER_IS_ARG_POINTER.
 
-2010-09-29  Hariharan Sandanagobalane <hariharan@picochip.com>
+2010-09-29  Hariharan Sandanagobalane  <hariharan@picochip.com>
 
        * config/picochip/picochip.c (picochip_output_internal_label):
        This function can now be called for debug CFI labels, which can come
index 5bd4d6e..a5088b0 100644 (file)
@@ -2292,13 +2292,11 @@ reg_subword_p (rtx x, rtx reg)
 }
 
 #ifdef AUTO_INC_DEC
-/* Replace auto-increment addressing modes with explicit operations to
-   access the same addresses without modifying the corresponding
-   registers.  If AFTER holds, SRC is meant to be reused after the
-   side effect, otherwise it is to be reused before that.  */
+/* Replace auto-increment addressing modes with explicit operations to access
+   the same addresses without modifying the corresponding registers.  */
 
 static rtx
-cleanup_auto_inc_dec (rtx src, bool after, enum machine_mode mem_mode)
+cleanup_auto_inc_dec (rtx src, enum machine_mode mem_mode)
 {
   rtx x = src;
   const RTX_CODE code = GET_CODE (x);
@@ -2335,26 +2333,20 @@ cleanup_auto_inc_dec (rtx src, bool after, enum machine_mode mem_mode)
 
     case PRE_INC:
     case PRE_DEC:
-    case POST_INC:
-    case POST_DEC:
       gcc_assert (mem_mode != VOIDmode && mem_mode != BLKmode);
-      if (after == (code == PRE_INC || code == PRE_DEC))
-       x = cleanup_auto_inc_dec (XEXP (x, 0), after, mem_mode);
-      else
-       x = gen_rtx_PLUS (GET_MODE (x),
-                         cleanup_auto_inc_dec (XEXP (x, 0), after, mem_mode),
-                         GEN_INT ((code == PRE_INC || code == POST_INC)
-                                  ? GET_MODE_SIZE (mem_mode)
-                                  : -GET_MODE_SIZE (mem_mode)));
-      return x;
+      return gen_rtx_PLUS (GET_MODE (x),
+                          cleanup_auto_inc_dec (XEXP (x, 0), mem_mode),
+                          GEN_INT (code == PRE_INC
+                                   ? GET_MODE_SIZE (mem_mode)
+                                   : -GET_MODE_SIZE (mem_mode)));
 
+    case POST_INC:
+    case POST_DEC:
     case PRE_MODIFY:
     case POST_MODIFY:
-      if (after == (code == PRE_MODIFY))
-       x = XEXP (x, 0);
-      else
-       x = XEXP (x, 1);
-      return cleanup_auto_inc_dec (x, after, mem_mode);
+      return cleanup_auto_inc_dec (code == PRE_MODIFY
+                                  ? XEXP (x, 1) : XEXP (x, 0),
+                                  mem_mode);
 
     default:
       break;
@@ -2377,14 +2369,14 @@ cleanup_auto_inc_dec (rtx src, bool after, enum machine_mode mem_mode)
   fmt = GET_RTX_FORMAT (code);
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
     if (fmt[i] == 'e')
-      XEXP (x, i) = cleanup_auto_inc_dec (XEXP (x, i), after, mem_mode);
+      XEXP (x, i) = cleanup_auto_inc_dec (XEXP (x, i), mem_mode);
     else if (fmt[i] == 'E' || fmt[i] == 'V')
       {
        int j;
        XVEC (x, i) = rtvec_alloc (XVECLEN (x, i));
        for (j = 0; j < XVECLEN (x, i); j++)
          XVECEXP (x, i, j)
-           = cleanup_auto_inc_dec (XVECEXP (src, i, j), after, mem_mode);
+           = cleanup_auto_inc_dec (XVECEXP (src, i, j), mem_mode);
       }
 
   return x;
@@ -2397,7 +2389,6 @@ struct rtx_subst_pair
 {
   rtx to;
   bool adjusted;
-  bool after;
 };
 
 /* DATA points to an rtx_subst_pair.  Return the value that should be
@@ -2414,7 +2405,7 @@ propagate_for_debug_subst (rtx from, const_rtx old_rtx, void *data)
     {
       pair->adjusted = true;
 #ifdef AUTO_INC_DEC
-      pair->to = cleanup_auto_inc_dec (pair->to, pair->after, VOIDmode);
+      pair->to = cleanup_auto_inc_dec (pair->to, VOIDmode);
 #else
       pair->to = copy_rtx (pair->to);
 #endif
@@ -2424,19 +2415,17 @@ propagate_for_debug_subst (rtx from, const_rtx old_rtx, void *data)
   return copy_rtx (pair->to);
 }
 
-/* Replace occurrences of DEST with SRC in DEBUG_INSNs between INSN
-   and LAST.  If MOVE holds, debug insns must also be moved past
-   LAST.  */
+/* Replace all the occurrences of DEST with SRC in DEBUG_INSNs between INSN
+   and LAST.  */
 
 static void
-propagate_for_debug (rtx insn, rtx last, rtx dest, rtx src, bool move)
+propagate_for_debug (rtx insn, rtx last, rtx dest, rtx src)
 {
-  rtx next, move_pos = move ? last : NULL_RTX, loc;
+  rtx next, loc;
 
   struct rtx_subst_pair p;
   p.to = src;
   p.adjusted = false;
-  p.after = move;
 
   next = NEXT_INSN (insn);
   while (next != last)
@@ -2450,14 +2439,7 @@ propagate_for_debug (rtx insn, rtx last, rtx dest, rtx src, bool move)
          if (loc == INSN_VAR_LOCATION_LOC (insn))
            continue;
          INSN_VAR_LOCATION_LOC (insn) = loc;
-         if (move_pos)
-           {
-             remove_insn (insn);
-             PREV_INSN (insn) = NEXT_INSN (insn) = NULL_RTX;
-             move_pos = emit_debug_insn_after (insn, move_pos);
-           }
-         else
-           df_insn_rescan (insn);
+         df_insn_rescan (insn);
        }
     }
 }
@@ -2619,7 +2601,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
   added_links_insn = 0;
 
-  /* First check for one important special-case that the code below will
+  /* First check for one important special case that the code below will
      not handle.  Namely, the case where I1 is zero, I2 is a PARALLEL
      and I3 is a SET whose SET_SRC is a SET_DEST in I2.  In that case,
      we may be able to replace that destination with the destination of I3.
@@ -2627,8 +2609,8 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
      remainder into a structure, in which case we want to do the computation
      directly into the structure to avoid register-register copies.
 
-     Note that this case handles both multiple sets in I2 and also
-     cases where I2 has a number of CLOBBER or PARALLELs.
+     Note that this case handles both multiple sets in I2 and also cases
+     where I2 has a number of CLOBBERs inside the PARALLEL.
 
      We make very conservative checks below and only try to handle the
      most common cases of this.  For example, we only handle the case
@@ -2672,8 +2654,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
 
       if (i == XVECLEN (p2, 0))
        for (i = 0; i < XVECLEN (p2, 0); i++)
-         if ((GET_CODE (XVECEXP (p2, 0, i)) == SET
-              || GET_CODE (XVECEXP (p2, 0, i)) == CLOBBER)
+         if (GET_CODE (XVECEXP (p2, 0, i)) == SET
              && SET_DEST (XVECEXP (p2, 0, i)) == SET_SRC (PATTERN (i3)))
            {
              combine_merges++;
@@ -2682,16 +2663,14 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
              subst_low_luid = DF_INSN_LUID (i2);
 
              added_sets_2 = added_sets_1 = added_sets_0 = 0;
-             i2src = SET_DEST (PATTERN (i3));
-             i2dest = SET_SRC (PATTERN (i3));
+             i2src = SET_SRC (XVECEXP (p2, 0, i));
+             i2dest = SET_DEST (XVECEXP (p2, 0, i));
              i2dest_killed = dead_or_set_p (i2, i2dest);
 
              /* Replace the dest in I2 with our dest and make the resulting
-                insn the new pattern for I3.  Then skip to where we
-                validate the pattern.  Everything was set up above.  */
-             SUBST (SET_DEST (XVECEXP (p2, 0, i)),
-                    SET_DEST (PATTERN (i3)));
-
+                insn the new pattern for I3.  Then skip to where we validate
+                the pattern.  Everything was set up above.  */
+             SUBST (SET_DEST (XVECEXP (p2, 0, i)), SET_DEST (PATTERN (i3)));
              newpat = p2;
              i3_subst_into_i2 = 1;
              goto validate_replacement;
@@ -3820,7 +3799,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
                   i2src while its original mode is temporarily
                   restored, and then clear i2scratch so that we don't
                   do it again later.  */
-               propagate_for_debug (i2, i3, reg, i2src, false);
+               propagate_for_debug (i2, i3, reg, i2src);
                i2scratch = false;
                /* Put back the new mode.  */
                adjust_reg_mode (reg, new_mode);
@@ -3851,11 +3830,10 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
                   with this copy we have created; then, replace the
                   copy with the SUBREG of the original shared reg,
                   once again changed to the new mode.  */
-               propagate_for_debug (first, last, reg, tempreg, false);
+               propagate_for_debug (first, last, reg, tempreg);
                adjust_reg_mode (reg, new_mode);
                propagate_for_debug (first, last, tempreg,
-                                    lowpart_subreg (old_mode, reg, new_mode),
-                                    false);
+                                    lowpart_subreg (old_mode, reg, new_mode));
              }
          }
     }
@@ -4069,14 +4047,14 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
     if (newi2pat)
       {
        if (MAY_HAVE_DEBUG_INSNS && i2scratch)
-         propagate_for_debug (i2, i3, i2dest, i2src, false);
+         propagate_for_debug (i2, i3, i2dest, i2src);
        INSN_CODE (i2) = i2_code_number;
        PATTERN (i2) = newi2pat;
       }
     else
       {
        if (MAY_HAVE_DEBUG_INSNS && i2src)
-         propagate_for_debug (i2, i3, i2dest, i2src, i3_subst_into_i2);
+         propagate_for_debug (i2, i3, i2dest, i2src);
        SET_INSN_DELETED (i2);
       }
 
@@ -4085,7 +4063,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
        LOG_LINKS (i1) = 0;
        REG_NOTES (i1) = 0;
        if (MAY_HAVE_DEBUG_INSNS)
-         propagate_for_debug (i1, i3, i1dest, i1src, false);
+         propagate_for_debug (i1, i3, i1dest, i1src);
        SET_INSN_DELETED (i1);
       }
 
@@ -4094,7 +4072,7 @@ try_combine (rtx i3, rtx i2, rtx i1, rtx i0, int *new_direct_jump_p)
        LOG_LINKS (i0) = 0;
        REG_NOTES (i0) = 0;
        if (MAY_HAVE_DEBUG_INSNS)
-         propagate_for_debug (i0, i3, i0dest, i0src, false);
+         propagate_for_debug (i0, i3, i0dest, i0src);
        SET_INSN_DELETED (i0);
       }
 
index 202b757..40098b3 100644 (file)
@@ -2882,10 +2882,10 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
       return x;
 
     case CLOBBER:
+    case ASM_OPERANDS:
       gcc_assert (insn && DEBUG_INSN_P (insn));
       break;
 
-    case ASM_OPERANDS:
     case SET:
       gcc_unreachable ();
 
index 7f2de61..8cab44c 100644 (file)
@@ -1,3 +1,7 @@
+2010-10-06  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gnat.dg/opt6.ad[sb]: New test.
+
 2010-10-06  Nicola Pero  <nicola.pero@meta-innovation.com>
 
        Implemented fast enumeration for Objective-C.
diff --git a/gcc/testsuite/gnat.dg/opt6.adb b/gcc/testsuite/gnat.dg/opt6.adb
new file mode 100644 (file)
index 0000000..44dc047
--- /dev/null
@@ -0,0 +1,28 @@
+-- PR rtl-optimization/45394
+
+-- { dg-do compile }
+-- { dg-options "-O2 -g" }
+
+package body Opt6 is
+
+   function Current_Parameter (Iter : Command_Line_Iterator) return String is
+   begin
+      if Iter.Params = null
+        or else Iter.Current > Iter.Params'Last
+        or else Iter.Params (Iter.Current) = null
+      then
+         return "";
+
+      else
+         declare
+            P : constant String := Iter.Params (Iter.Current).all;
+
+         begin
+            --  Skip separator
+
+            return P (P'First + 1 .. P'Last);
+         end;
+      end if;
+   end Current_Parameter;
+
+end Opt6;
diff --git a/gcc/testsuite/gnat.dg/opt6.ads b/gcc/testsuite/gnat.dg/opt6.ads
new file mode 100644 (file)
index 0000000..f049853
--- /dev/null
@@ -0,0 +1,14 @@
+package Opt6 is
+
+   type String_Access is access all String;
+   type String_List is array (Positive range <>) of String_Access;
+   type String_List_Access is access all String_List;
+
+   type Command_Line_Iterator is record
+      Params   : String_List_Access;
+      Current  : Natural;
+   end record;
+
+   function Current_Parameter (Iter : Command_Line_Iterator) return String;
+
+end Opt6;