OSDN Git Service

Use PIP to determine the integer feasibility of a constraint system.
[pf3gnuchains/gcc-fork.git] / gcc / combine-stack-adj.c
index babd6d2..76c175c 100644 (file)
@@ -1,7 +1,7 @@
 /* Combine stack adjustments.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+   2010 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -57,7 +57,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "basic-block.h"
 #include "df.h"
 #include "except.h"
-#include "toplev.h"
 #include "reload.h"
 #include "timevar.h"
 #include "tree-pass.h"
@@ -206,7 +205,12 @@ try_apply_stack_adjustment (rtx insn, struct csa_reflist *reflist,
   rtx set;
 
   set = single_set_for_csa (insn);
-  validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1);
+  if (MEM_P (SET_DEST (set)))
+    validate_change (insn, &SET_DEST (set),
+                    replace_equiv_address (SET_DEST (set), stack_pointer_rtx),
+                    1);
+  else
+    validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1);
 
   for (ml = reflist; ml ; ml = ml->next)
     {
@@ -468,28 +472,33 @@ combine_stack_adjustments_for_block (basic_block bb)
              continue;
            }
 
-         /* Find a predecrement of exactly the previous adjustment and
-            turn it into a direct store.  Obviously we can't do this if
-            there were any intervening uses of the stack pointer.  */
-         if (reflist == NULL
-             && MEM_P (dest)
-             && ((GET_CODE (XEXP (dest, 0)) == PRE_DEC
-                  && (last_sp_adjust
-                      == (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (dest))))
-                 || (GET_CODE (XEXP (dest, 0)) == PRE_MODIFY
+         /* Find a store with pre-(dec|inc)rement or pre-modify of exactly
+            the previous adjustment and turn it into a simple store.  This
+            is equivalent to anticipating the stack adjustment so this must
+            be an allocation.  */
+         if (MEM_P (dest)
+             && ((STACK_GROWS_DOWNWARD
+                  ? (GET_CODE (XEXP (dest, 0)) == PRE_DEC
+                     && last_sp_adjust
+                        == (HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (dest)))
+                  : (GET_CODE (XEXP (dest, 0)) == PRE_INC
+                     && last_sp_adjust
+                        == -(HOST_WIDE_INT) GET_MODE_SIZE (GET_MODE (dest))))
+                 || ((STACK_GROWS_DOWNWARD
+                      ? last_sp_adjust >= 0 : last_sp_adjust <= 0)
+                     && GET_CODE (XEXP (dest, 0)) == PRE_MODIFY
                      && GET_CODE (XEXP (XEXP (dest, 0), 1)) == PLUS
-                     && XEXP (XEXP (XEXP (dest, 0), 1), 0) == stack_pointer_rtx
-                     && (GET_CODE (XEXP (XEXP (XEXP (dest, 0), 1), 1))
-                         == CONST_INT)
-                     && (INTVAL (XEXP (XEXP (XEXP (dest, 0), 1), 1))
-                         == -last_sp_adjust)))
+                     && XEXP (XEXP (XEXP (dest, 0), 1), 0)
+                        == stack_pointer_rtx
+                     && GET_CODE (XEXP (XEXP (XEXP (dest, 0), 1), 1))
+                        == CONST_INT
+                     && INTVAL (XEXP (XEXP (XEXP (dest, 0), 1), 1))
+                        == -last_sp_adjust))
              && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx
-             && ! reg_mentioned_p (stack_pointer_rtx, src)
+             && !reg_mentioned_p (stack_pointer_rtx, src)
              && memory_address_p (GET_MODE (dest), stack_pointer_rtx)
-             && validate_change (insn, &SET_DEST (set),
-                                 replace_equiv_address (dest,
-                                                        stack_pointer_rtx),
-                                 0))
+             && try_apply_stack_adjustment (insn, reflist, 0,
+                                            -last_sp_adjust))
            {
              delete_insn (last_sp_set);
              free_csa_reflist (reflist);
@@ -536,7 +545,7 @@ combine_stack_adjustments_for_block (basic_block bb)
 static bool
 gate_handle_stack_adjustments (void)
 {
-  return (optimize > 0);
+  return flag_combine_stack_adjustments;
 }
 
 static unsigned int
@@ -545,7 +554,7 @@ rest_of_handle_stack_adjustments (void)
   cleanup_cfg (flag_crossjumping ? CLEANUP_CROSSJUMP : 0);
 
   /* This is kind of a heuristic.  We need to run combine_stack_adjustments
-     even for machines with possibly nonzero RETURN_POPS_ARGS
+     even for machines with possibly nonzero TARGET_RETURN_POPS_ARGS
      and ACCUMULATE_OUTGOING_ARGS.  We expect that only ports having
      push instructions will have popping returns.  */
 #ifndef PUSH_ROUNDING