OSDN Git Service

Changlog libcpp
[pf3gnuchains/gcc-fork.git] / gcc / lower-subreg.c
index 67a9598..3ff20eb 100644 (file)
@@ -1,5 +1,5 @@
 /* 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>
 
@@ -531,6 +531,34 @@ resolve_subreg_use (rtx *px, void *data)
   return 0;
 }
 
+/* This is called via for_each_rtx.  Look for SUBREGs which can be
+   decomposed and decomposed REGs that need copying.  */
+
+static int
+adjust_decomposed_uses (rtx *px, void *data ATTRIBUTE_UNUSED)
+{
+  rtx x = *px;
+
+  if (x == NULL_RTX)
+    return 0;
+
+  if (resolve_subreg_p (x))
+    {
+      x = simplify_subreg_concatn (GET_MODE (x), SUBREG_REG (x),
+                                  SUBREG_BYTE (x));
+
+      if (x)
+       *px = x;
+      else
+       x = copy_rtx (*px);
+    }
+
+  if (resolve_reg_p (x))
+    *px = copy_rtx (x);
+
+  return 0;
+}
+
 /* We are deleting INSN.  Move any EH_REGION notes to INSNS.  */
 
 static void
@@ -551,8 +579,7 @@ move_eh_region_note (rtx insn, rtx insns)
          || (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));
+       add_reg_note (p, REG_EH_REGION, XEXP (note, 0));
     }
 }
 
@@ -578,7 +605,7 @@ resolve_reg_notes (rtx insn)
   pnote = &REG_NOTES (insn);
   while (*pnote != NULL_RTX)
     {
-      bool delete = false;
+      bool del = false;
 
       note = *pnote;
       switch (REG_NOTE_KIND (note))
@@ -586,14 +613,14 @@ resolve_reg_notes (rtx insn)
        case REG_DEAD:
        case REG_UNUSED:
          if (resolve_reg_p (XEXP (note, 0)))
-           delete = true;
+           del = true;
          break;
 
        default:
          break;
        }
 
-      if (delete)
+      if (del)
        *pnote = XEXP (note, 1);
       else
        pnote = &XEXP (note, 1);
@@ -887,6 +914,18 @@ resolve_use (rtx pat, rtx insn)
   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.  */
@@ -923,7 +962,7 @@ find_decomposable_shift_zext (rtx insn)
     }
   else /* left or right shift */
     {
-      if (GET_CODE (XEXP (op, 1)) != CONST_INT
+      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;
@@ -1171,6 +1210,8 @@ decompose_multiword_subregs (void)
                resolve_clobber (pat, insn);
              else if (GET_CODE (pat) == USE)
                resolve_use (pat, insn);
+             else if (DEBUG_INSN_P (insn))
+               resolve_debug (insn);
              else
                {
                  rtx set;
@@ -1326,7 +1367,7 @@ struct rtl_opt_pass pass_lower_subreg =
 {
  {
   RTL_PASS,
-  "subreg",                            /* name */
+  "subreg1",                           /* name */
   gate_handle_lower_subreg,             /* gate */
   rest_of_handle_lower_subreg,          /* execute */
   NULL,                                 /* sub */