OSDN Git Service

Add -std=c99 to avx-cmpsd-1.c and avx-cmpss-1.c.
[pf3gnuchains/gcc-fork.git] / gcc / lower-subreg.c
index ea14140..3301a9d 100644 (file)
@@ -1,5 +1,5 @@
 /* Decompose multiword subregs.
 /* Decompose multiword subregs.
-   Copyright (C) 2007 Free Software Foundation, Inc.
+   Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
    Contributed by Richard Henderson <rth@redhat.com>
                  Ian Lance Taylor <iant@google.com>
 
    Contributed by Richard Henderson <rth@redhat.com>
                  Ian Lance Taylor <iant@google.com>
 
@@ -7,7 +7,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
 
 #include "config.h"
 #include "system.h"
@@ -226,11 +225,9 @@ enum classify_move_insn
 {
   /* Not a simple move from one location to another.  */
   NOT_SIMPLE_MOVE,
 {
   /* Not a simple move from one location to another.  */
   NOT_SIMPLE_MOVE,
-  /* A simple move from one pseudo-register to another with no
-     REG_RETVAL note.  */
+  /* A simple move from one pseudo-register to another.  */
   SIMPLE_PSEUDO_REG_MOVE,
   SIMPLE_PSEUDO_REG_MOVE,
-  /* A simple move involving a non-pseudo-register, or from one
-     pseudo-register to another with a REG_RETVAL note.  */
+  /* A simple move involving a non-pseudo-register.  */
   SIMPLE_MOVE
 };
 
   SIMPLE_MOVE
 };
 
@@ -305,10 +302,10 @@ find_decomposable_subregs (rtx *px, void *data)
 
         If this is not a simple copy from one location to another,
         then we can not decompose this register.  If this is a simple
 
         If this is not a simple copy from one location to another,
         then we can not decompose this register.  If this is a simple
-        copy from one pseudo-register to another, with no REG_RETVAL
-        note, and the mode is right, then we mark the register as
-        decomposable.  Otherwise we don't say anything about this
-        register--it could be decomposed, but whether that would be
+        copy from one pseudo-register to another, and the mode is right
+        then we mark the register as decomposable.
+        Otherwise we don't say anything about this register --
+        it could be decomposed, but whether that would be
         profitable depends upon how it is used elsewhere.
 
         We only set bits in the bitmap for multi-word
         profitable depends upon how it is used elsewhere.
 
         We only set bits in the bitmap for multi-word
@@ -526,91 +523,40 @@ resolve_subreg_use (rtx *px, void *data)
     {
       /* Return 1 to the caller to indicate that we found a direct
         reference to a register which is being decomposed.  This can
     {
       /* Return 1 to the caller to indicate that we found a direct
         reference to a register which is being decomposed.  This can
-        happen inside notes.  */
-      gcc_assert (!insn);
+        happen inside notes, multiword shift or zero-extend
+        instructions.  */
       return 1;
     }
 
   return 0;
 }
 
       return 1;
     }
 
   return 0;
 }
 
-/* We are deleting INSN.  Move any EH_REGION notes to INSNS.  */
+/* This is called via for_each_rtx.  Look for SUBREGs which can be
+   decomposed and decomposed REGs that need copying.  */
 
 
-static void
-move_eh_region_note (rtx insn, rtx insns)
+static int
+adjust_decomposed_uses (rtx *px, void *data ATTRIBUTE_UNUSED)
 {
 {
-  rtx note, p;
-
-  note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
-  if (note == NULL_RTX)
-    return;
+  rtx x = *px;
 
 
-  gcc_assert (CALL_P (insn)
-             || (flag_non_call_exceptions && may_trap_p (PATTERN (insn))));
+  if (x == NULL_RTX)
+    return 0;
 
 
-  for (p = insns; p != NULL_RTX; p = NEXT_INSN (p))
+  if (resolve_subreg_p (x))
     {
     {
-      if (CALL_P (p)
-         || (flag_non_call_exceptions
-             && INSN_P (p)
-             && may_trap_p (PATTERN (p))))
-       REG_NOTES (p) = gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (note, 0),
-                                          REG_NOTES (p));
-    }
-}
-
-/* If there is a REG_LIBCALL note on OLD_START, move it to NEW_START,
-   and link the corresponding REG_RETVAL note to NEW_START.  */
-
-static void
-move_libcall_note (rtx old_start, rtx new_start)
-{
-  rtx note0, note1, end;
-
-  note0 = find_reg_note (old_start, REG_LIBCALL, NULL);
-  if (note0 == NULL_RTX)
-    return;
-
-  remove_note (old_start, note0);
-  end = XEXP (note0, 0);
-  note1 = find_reg_note (end, REG_RETVAL, NULL);
-
-  XEXP (note0, 1) = REG_NOTES (new_start);
-  REG_NOTES (new_start) = note0;
-  XEXP (note1, 0) = new_start;
-}
-
-/* Remove any REG_RETVAL note, the corresponding REG_LIBCALL note, and
-   any markers for a no-conflict block.  We have decomposed the
-   registers so the non-conflict is now obvious.  */
-
-static void
-remove_retval_note (rtx insn1)
-{
-  rtx note0, insn0, note1, insn;
-
-  note1 = find_reg_note (insn1, REG_RETVAL, NULL);
-  if (note1 == NULL_RTX)
-    return;
-
-  insn0 = XEXP (note1, 0);
-  note0 = find_reg_note (insn0, REG_LIBCALL, NULL);
+      x = simplify_subreg_concatn (GET_MODE (x), SUBREG_REG (x),
+                                  SUBREG_BYTE (x));
 
 
-  remove_note (insn0, note0);
-  remove_note (insn1, note1);
+      if (x)
+       *px = x;
+      else
+       x = copy_rtx (*px);
+    }
 
 
-  for (insn = insn0; insn != insn1; insn = NEXT_INSN (insn))
-    {
-      while (1)
-       {
-         rtx note;
+  if (resolve_reg_p (x))
+    *px = copy_rtx (x);
 
 
-         note = find_reg_note (insn, REG_NO_CONFLICT, NULL);
-         if (note == NULL_RTX)
-           break;
-         remove_note (insn, note);
-       }
-    }
+  return 0;
 }
 
 /* Resolve any decomposed registers which appear in register notes on
 }
 
 /* Resolve any decomposed registers which appear in register notes on
@@ -626,10 +572,7 @@ resolve_reg_notes (rtx insn)
     {
       int old_count = num_validated_changes ();
       if (for_each_rtx (&XEXP (note, 0), resolve_subreg_use, NULL))
     {
       int old_count = num_validated_changes ();
       if (for_each_rtx (&XEXP (note, 0), resolve_subreg_use, NULL))
-       {
-         remove_note (insn, note);
-         remove_retval_note (insn);
-       }
+       remove_note (insn, note);
       else
        if (old_count != num_validated_changes ())
          df_notes_rescan (insn);
       else
        if (old_count != num_validated_changes ())
          df_notes_rescan (insn);
@@ -638,23 +581,22 @@ resolve_reg_notes (rtx insn)
   pnote = &REG_NOTES (insn);
   while (*pnote != NULL_RTX)
     {
   pnote = &REG_NOTES (insn);
   while (*pnote != NULL_RTX)
     {
-      bool delete = false;
+      bool del = false;
 
       note = *pnote;
       switch (REG_NOTE_KIND (note))
        {
 
       note = *pnote;
       switch (REG_NOTE_KIND (note))
        {
-       case REG_NO_CONFLICT:
        case REG_DEAD:
        case REG_UNUSED:
          if (resolve_reg_p (XEXP (note, 0)))
        case REG_DEAD:
        case REG_UNUSED:
          if (resolve_reg_p (XEXP (note, 0)))
-           delete = true;
+           del = true;
          break;
 
        default:
          break;
        }
 
          break;
 
        default:
          break;
        }
 
-      if (delete)
+      if (del)
        *pnote = XEXP (note, 1);
       else
        pnote = &XEXP (note, 1);
        *pnote = XEXP (note, 1);
       else
        pnote = &XEXP (note, 1);
@@ -851,7 +793,7 @@ resolve_simple_move (rtx set, rtx insn)
       unsigned int i;
 
       if (REG_P (dest) && !HARD_REGISTER_NUM_P (REGNO (dest)))
       unsigned int i;
 
       if (REG_P (dest) && !HARD_REGISTER_NUM_P (REGNO (dest)))
-       emit_insn (gen_rtx_CLOBBER (VOIDmode, dest));
+       emit_clobber (dest);
 
       for (i = 0; i < words; ++i)
        emit_move_insn (simplify_gen_subreg_concatn (word_mode, dest,
 
       for (i = 0; i < words; ++i)
        emit_move_insn (simplify_gen_subreg_concatn (word_mode, dest,
@@ -881,12 +823,10 @@ resolve_simple_move (rtx set, rtx insn)
   insns = get_insns ();
   end_sequence ();
 
   insns = get_insns ();
   end_sequence ();
 
-  move_eh_region_note (insn, insns);
+  copy_reg_eh_region_note_forward (insn, insns, NULL_RTX);
 
   emit_insn_before (insns, insn);
 
 
   emit_insn_before (insns, insn);
 
-  move_libcall_note (insn, insns);
-  remove_retval_note (insn);
   delete_insn (insn);
 
   return insns;
   delete_insn (insn);
 
   return insns;
@@ -928,6 +868,8 @@ resolve_clobber (rtx pat, rtx insn)
       emit_insn_after (x, insn);
     }
 
       emit_insn_after (x, insn);
     }
 
+  resolve_reg_notes (insn);
+
   return true;
 }
 
   return true;
 }
 
@@ -942,9 +884,174 @@ resolve_use (rtx pat, rtx insn)
       delete_insn (insn);
       return true;
     }
       delete_insn (insn);
       return true;
     }
+
+  resolve_reg_notes (insn);
+
   return false;
 }
 
   return false;
 }
 
+/* A VAR_LOCATION can be simplified.  */
+
+static void
+resolve_debug (rtx insn)
+{
+  for_each_rtx (&PATTERN (insn), adjust_decomposed_uses, NULL_RTX);
+
+  df_insn_rescan (insn);
+
+  resolve_reg_notes (insn);
+}
+
+/* Checks if INSN is a decomposable multiword-shift or zero-extend and
+   sets the decomposable_context bitmap accordingly.  A non-zero value
+   is returned if a decomposable insn has been found.  */
+
+static int
+find_decomposable_shift_zext (rtx insn)
+{
+  rtx set;
+  rtx op;
+  rtx op_operand;
+
+  set = single_set (insn);
+  if (!set)
+    return 0;
+
+  op = SET_SRC (set);
+  if (GET_CODE (op) != ASHIFT
+      && GET_CODE (op) != LSHIFTRT
+      && GET_CODE (op) != ZERO_EXTEND)
+    return 0;
+
+  op_operand = XEXP (op, 0);
+  if (!REG_P (SET_DEST (set)) || !REG_P (op_operand)
+      || HARD_REGISTER_NUM_P (REGNO (SET_DEST (set)))
+      || HARD_REGISTER_NUM_P (REGNO (op_operand))
+      || !SCALAR_INT_MODE_P (GET_MODE (op)))
+    return 0;
+
+  if (GET_CODE (op) == ZERO_EXTEND)
+    {
+      if (GET_MODE (op_operand) != word_mode
+         || GET_MODE_BITSIZE (GET_MODE (op)) != 2 * BITS_PER_WORD)
+       return 0;
+    }
+  else /* left or right shift */
+    {
+      if (!CONST_INT_P (XEXP (op, 1))
+         || INTVAL (XEXP (op, 1)) < BITS_PER_WORD
+         || GET_MODE_BITSIZE (GET_MODE (op_operand)) != 2 * BITS_PER_WORD)
+       return 0;
+    }
+
+  bitmap_set_bit (decomposable_context, REGNO (SET_DEST (set)));
+
+  if (GET_CODE (op) != ZERO_EXTEND)
+    bitmap_set_bit (decomposable_context, REGNO (op_operand));
+
+  return 1;
+}
+
+/* Decompose a more than word wide shift (in INSN) of a multiword
+   pseudo or a multiword zero-extend of a wordmode pseudo into a move
+   and 'set to zero' insn.  Return a pointer to the new insn when a
+   replacement was done.  */
+
+static rtx
+resolve_shift_zext (rtx insn)
+{
+  rtx set;
+  rtx op;
+  rtx op_operand;
+  rtx insns;
+  rtx src_reg, dest_reg, dest_zero;
+  int src_reg_num, dest_reg_num, offset1, offset2, src_offset;
+
+  set = single_set (insn);
+  if (!set)
+    return NULL_RTX;
+
+  op = SET_SRC (set);
+  if (GET_CODE (op) != ASHIFT
+      && GET_CODE (op) != LSHIFTRT
+      && GET_CODE (op) != ZERO_EXTEND)
+    return NULL_RTX;
+
+  op_operand = XEXP (op, 0);
+
+  if (!resolve_reg_p (SET_DEST (set)) && !resolve_reg_p (op_operand))
+    return NULL_RTX;
+
+  /* src_reg_num is the number of the word mode register which we
+     are operating on.  For a left shift and a zero_extend on little
+     endian machines this is register 0.  */
+  src_reg_num = GET_CODE (op) == LSHIFTRT ? 1 : 0;
+
+  if (WORDS_BIG_ENDIAN
+      && GET_MODE_SIZE (GET_MODE (op_operand)) > UNITS_PER_WORD)
+    src_reg_num = 1 - src_reg_num;
+
+  if (GET_CODE (op) == ZERO_EXTEND)
+    dest_reg_num = WORDS_BIG_ENDIAN ? 1 : 0;
+  else
+    dest_reg_num = 1 - src_reg_num;
+
+  offset1 = UNITS_PER_WORD * dest_reg_num;
+  offset2 = UNITS_PER_WORD * (1 - dest_reg_num);
+  src_offset = UNITS_PER_WORD * src_reg_num;
+
+  if (WORDS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
+    {
+      offset1 += UNITS_PER_WORD - 1;
+      offset2 += UNITS_PER_WORD - 1;
+      src_offset += UNITS_PER_WORD - 1;
+    }
+
+  start_sequence ();
+
+  dest_reg = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
+                                          GET_MODE (SET_DEST (set)),
+                                          offset1);
+  dest_zero = simplify_gen_subreg_concatn (word_mode, SET_DEST (set),
+                                           GET_MODE (SET_DEST (set)),
+                                           offset2);
+  src_reg = simplify_gen_subreg_concatn (word_mode, op_operand,
+                                         GET_MODE (op_operand),
+                                         src_offset);
+  if (GET_CODE (op) != ZERO_EXTEND)
+    {
+      int shift_count = INTVAL (XEXP (op, 1));
+      if (shift_count > BITS_PER_WORD)
+       src_reg = expand_shift (GET_CODE (op) == ASHIFT ?
+                               LSHIFT_EXPR : RSHIFT_EXPR,
+                               word_mode, src_reg,
+                               build_int_cst (NULL_TREE,
+                                              shift_count - BITS_PER_WORD),
+                               dest_reg, 1);
+    }
+
+  if (dest_reg != src_reg)
+    emit_move_insn (dest_reg, src_reg);
+  emit_move_insn (dest_zero, CONST0_RTX (word_mode));
+  insns = get_insns ();
+
+  end_sequence ();
+
+  emit_insn_before (insns, insn);
+
+  if (dump_file)
+    {
+      rtx in;
+      fprintf (dump_file, "; Replacing insn: %d with insns: ", INSN_UID (insn));
+      for (in = insns; in != insn; in = NEXT_INSN (in))
+       fprintf (dump_file, "%d ", INSN_UID (in));
+      fprintf (dump_file, "\n");
+    }
+
+  delete_insn (insn);
+  return insns;
+}
+
 /* Look for registers which are always accessed via word-sized SUBREGs
    or via copies.  Decompose these registers into several word-sized
    pseudo-registers.  */
 /* Look for registers which are always accessed via word-sized SUBREGs
    or via copies.  Decompose these registers into several word-sized
    pseudo-registers.  */
@@ -1004,6 +1111,9 @@ decompose_multiword_subregs (void)
              || GET_CODE (PATTERN (insn)) == USE)
            continue;
 
              || GET_CODE (PATTERN (insn)) == USE)
            continue;
 
+         if (find_decomposable_shift_zext (insn))
+           continue;
+
          recog_memoized (insn);
          extract_insn (insn);
 
          recog_memoized (insn);
          extract_insn (insn);
 
@@ -1013,34 +1123,8 @@ decompose_multiword_subregs (void)
            cmi = NOT_SIMPLE_MOVE;
          else
            {
            cmi = NOT_SIMPLE_MOVE;
          else
            {
-             bool retval;
-
-             retval = find_reg_note (insn, REG_RETVAL, NULL_RTX) != NULL_RTX;
-
-             if (find_pseudo_copy (set) && !retval)
+             if (find_pseudo_copy (set))
                cmi = SIMPLE_PSEUDO_REG_MOVE;
                cmi = SIMPLE_PSEUDO_REG_MOVE;
-             else if (retval
-                      && REG_P (SET_SRC (set))
-                      && HARD_REGISTER_P (SET_SRC (set)))
-               {
-                 rtx note;
-
-                 /* We don't want to decompose an assignment which
-                    copies the value returned by a libcall to a
-                    pseudo-register.  Doing that will lose the RETVAL
-                    note with no real gain.  */
-                 cmi = NOT_SIMPLE_MOVE;
-
-                 /* If we have a RETVAL note, there should be an
-                    EQUAL note.  We don't want to decompose any
-                    registers which that EQUAL note refers to
-                    directly.  If we do, we will no longer know the
-                    value of the libcall.  */
-                 note = find_reg_equal_equiv_note (insn);
-                 if (note != NULL_RTX)
-                   for_each_rtx (&XEXP (note, 0), find_decomposable_subregs,
-                                 &cmi);
-               }
              else
                cmi = SIMPLE_MOVE;
            }
              else
                cmi = SIMPLE_MOVE;
            }
@@ -1070,7 +1154,6 @@ decompose_multiword_subregs (void)
   bitmap_and_compl_into (decomposable_context, non_decomposable_context);
   if (!bitmap_empty_p (decomposable_context))
     {
   bitmap_and_compl_into (decomposable_context, non_decomposable_context);
   if (!bitmap_empty_p (decomposable_context))
     {
-      int hold_no_new_pseudos = no_new_pseudos;
       sbitmap sub_blocks;
       unsigned int i;
       sbitmap_iterator sbi;
       sbitmap sub_blocks;
       unsigned int i;
       sbitmap_iterator sbi;
@@ -1079,7 +1162,6 @@ decompose_multiword_subregs (void)
 
       propagate_pseudo_copies ();
 
 
       propagate_pseudo_copies ();
 
-      no_new_pseudos = 0;
       sub_blocks = sbitmap_alloc (last_basic_block);
       sbitmap_zero (sub_blocks);
 
       sub_blocks = sbitmap_alloc (last_basic_block);
       sbitmap_zero (sub_blocks);
 
@@ -1092,26 +1174,18 @@ decompose_multiword_subregs (void)
 
          FOR_BB_INSNS (bb, insn)
            {
 
          FOR_BB_INSNS (bb, insn)
            {
-             rtx next, pat;
-             bool changed;
+             rtx pat;
 
              if (!INSN_P (insn))
                continue;
 
 
              if (!INSN_P (insn))
                continue;
 
-             next = NEXT_INSN (insn);
-             changed = false;
-
              pat = PATTERN (insn);
              if (GET_CODE (pat) == CLOBBER)
              pat = PATTERN (insn);
              if (GET_CODE (pat) == CLOBBER)
-               {
-                 if (resolve_clobber (pat, insn))
-                   changed = true;
-               }
+               resolve_clobber (pat, insn);
              else if (GET_CODE (pat) == USE)
              else if (GET_CODE (pat) == USE)
-               {
-                 if (resolve_use (pat, insn))
-                   changed = true;
-               }
+               resolve_use (pat, insn);
+             else if (DEBUG_INSN_P (insn))
+               resolve_debug (insn);
              else
                {
                  rtx set;
              else
                {
                  rtx set;
@@ -1144,10 +1218,6 @@ decompose_multiword_subregs (void)
                      insn = resolve_simple_move (set, insn);
                      if (insn != orig_insn)
                        {
                      insn = resolve_simple_move (set, insn);
                      if (insn != orig_insn)
                        {
-                         changed = true;
-
-                         remove_retval_note (insn);
-
                          recog_memoized (insn);
                          extract_insn (insn);
 
                          recog_memoized (insn);
                          extract_insn (insn);
 
@@ -1155,6 +1225,18 @@ decompose_multiword_subregs (void)
                            SET_BIT (sub_blocks, bb->index);
                        }
                    }
                            SET_BIT (sub_blocks, bb->index);
                        }
                    }
+                 else
+                   {
+                     rtx decomposed_shift;
+
+                     decomposed_shift = resolve_shift_zext (insn);
+                     if (decomposed_shift != NULL_RTX)
+                       {
+                         insn = decomposed_shift;
+                         recog_memoized (insn);
+                         extract_insn (insn);
+                       }
+                   }
 
                  for (i = recog_data.n_operands - 1; i >= 0; --i)
                    for_each_rtx (recog_data.operand_loc[i],
 
                  for (i = recog_data.n_operands - 1; i >= 0; --i)
                    for_each_rtx (recog_data.operand_loc[i],
@@ -1171,22 +1253,16 @@ decompose_multiword_subregs (void)
                          int dup_num = recog_data.dup_num[i];
                          rtx *px = recog_data.operand_loc[dup_num];
 
                          int dup_num = recog_data.dup_num[i];
                          rtx *px = recog_data.operand_loc[dup_num];
 
-                         validate_change (insn, pl, *px, 1);
+                         validate_unshare_change (insn, pl, *px, 1);
                        }
 
                      i = apply_change_group ();
                      gcc_assert (i);
                        }
 
                      i = apply_change_group ();
                      gcc_assert (i);
-
-                     remove_retval_note (insn);
-
-                     changed = true;
                    }
                }
            }
        }
 
                    }
                }
            }
        }
 
-      no_new_pseudos = hold_no_new_pseudos;
-
       /* If we had insns to split that caused control flow insns in the middle
         of a basic block, split those blocks now.  Note that we only handle
         the case where splitting a load has caused multiple possibly trapping
       /* If we had insns to split that caused control flow insns in the middle
         of a basic block, split those blocks now.  Note that we only handle
         the case where splitting a load has caused multiple possibly trapping
@@ -1229,7 +1305,7 @@ decompose_multiword_subregs (void)
        BITMAP_FREE (b);
   }
 
        BITMAP_FREE (b);
   }
 
-  VEC_free (bitmap, heap, reg_copy_graph);  
+  VEC_free (bitmap, heap, reg_copy_graph);
 
   BITMAP_FREE (decomposable_context);
   BITMAP_FREE (non_decomposable_context);
 
   BITMAP_FREE (decomposable_context);
   BITMAP_FREE (non_decomposable_context);
@@ -1261,9 +1337,11 @@ rest_of_handle_lower_subreg2 (void)
   return 0;
 }
 
   return 0;
 }
 
-struct tree_opt_pass pass_lower_subreg =
+struct rtl_opt_pass pass_lower_subreg =
 {
 {
-  "subreg",                            /* name */
+ {
+  RTL_PASS,
+  "subreg1",                           /* name */
   gate_handle_lower_subreg,             /* gate */
   rest_of_handle_lower_subreg,          /* execute */
   NULL,                                 /* sub */
   gate_handle_lower_subreg,             /* gate */
   rest_of_handle_lower_subreg,          /* execute */
   NULL,                                 /* sub */
@@ -1276,12 +1354,14 @@ struct tree_opt_pass pass_lower_subreg =
   0,                                    /* todo_flags_start */
   TODO_dump_func |
   TODO_ggc_collect |
   0,                                    /* todo_flags_start */
   TODO_dump_func |
   TODO_ggc_collect |
-  TODO_verify_flow,                     /* todo_flags_finish */
-  'u'                                   /* letter */
+  TODO_verify_flow                      /* todo_flags_finish */
+ }
 };
 
 };
 
-struct tree_opt_pass pass_lower_subreg2 =
+struct rtl_opt_pass pass_lower_subreg2 =
 {
 {
+ {
+  RTL_PASS,
   "subreg2",                           /* name */
   gate_handle_lower_subreg,             /* gate */
   rest_of_handle_lower_subreg2,          /* execute */
   "subreg2",                           /* name */
   gate_handle_lower_subreg,             /* gate */
   rest_of_handle_lower_subreg2,          /* execute */
@@ -1293,9 +1373,9 @@ struct tree_opt_pass pass_lower_subreg2 =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_df_finish |
+  TODO_df_finish | TODO_verify_rtl_sharing |
   TODO_dump_func |
   TODO_ggc_collect |
   TODO_dump_func |
   TODO_ggc_collect |
-  TODO_verify_flow,                     /* todo_flags_finish */
-  'U'                                   /* letter */
+  TODO_verify_flow                      /* todo_flags_finish */
+ }
 };
 };