OSDN Git Service

* decContext.h: Include gstdint.h instead of <stdint.h>.
[pf3gnuchains/gcc-fork.git] / gcc / cfgexpand.c
index e0c328f..695e4ef 100644 (file)
@@ -1,5 +1,6 @@
 /* A pass for lowering trees to RTL.
-   Copyright (C) 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -487,8 +488,7 @@ get_decl_align_unit (tree decl)
 {
   unsigned int align;
 
-  align = DECL_ALIGN (decl);
-  align = LOCAL_ALIGNMENT (TREE_TYPE (decl), align);
+  align = LOCAL_DECL_ALIGNMENT (decl);
 
   if (align > MAX_SUPPORTED_STACK_ALIGNMENT)
     align = MAX_SUPPORTED_STACK_ALIGNMENT;
@@ -866,7 +866,8 @@ dump_stack_var_partition (void)
 static void
 expand_one_stack_var_at (tree decl, HOST_WIDE_INT offset)
 {
-  HOST_WIDE_INT align;
+  /* Alignment is unsigned.   */
+  unsigned HOST_WIDE_INT align;
   rtx x;
 
   /* If this fails, we've overflowed the stack frame.  Error nicely?  */
@@ -879,8 +880,10 @@ expand_one_stack_var_at (tree decl, HOST_WIDE_INT offset)
   offset -= frame_phase;
   align = offset & -offset;
   align *= BITS_PER_UNIT;
-  if (align > STACK_BOUNDARY || align == 0)
+  if (align == 0)
     align = STACK_BOUNDARY;
+  else if (align > MAX_SUPPORTED_STACK_ALIGNMENT)
+    align = MAX_SUPPORTED_STACK_ALIGNMENT;
   DECL_ALIGN (decl) = align;
   DECL_USER_ALIGN (decl) = 0;
 
@@ -1970,7 +1973,7 @@ expand_gimple_basic_block (basic_block bb)
                    return new_bb;
                }
            }
-         else
+         else if (gimple_code (stmt) != GIMPLE_CHANGE_DYNAMIC_TYPE)
            {
              tree stmt_tree = gimple_to_tree (stmt);
              last = get_last_insn ();
@@ -2215,7 +2218,7 @@ static void
 expand_stack_alignment (void)
 {
   rtx drap_rtx;
-  unsigned int preferred_stack_boundary, incoming_stack_boundary;
+  unsigned int preferred_stack_boundary;
 
   if (! SUPPORTS_STACK_ALIGNMENT)
     return;
@@ -2228,10 +2231,6 @@ expand_stack_alignment (void)
   gcc_assert (crtl->stack_alignment_needed
              <= crtl->stack_alignment_estimated);
 
-  /* Update stack boundary if needed.  */
-  if (targetm.calls.update_stack_boundary)
-    targetm.calls.update_stack_boundary (); 
-
   /* Update crtl->stack_alignment_estimated and use it later to align
      stack.  We check PREFERRED_STACK_BOUNDARY if there may be non-call
      exceptions since callgraph doesn't collect incoming stack alignment
@@ -2246,15 +2245,8 @@ expand_stack_alignment (void)
   if (preferred_stack_boundary > crtl->stack_alignment_needed)
     crtl->stack_alignment_needed = preferred_stack_boundary;
 
-  /* The incoming stack frame has to be aligned at least at
-     parm_stack_boundary.  */
-  if (crtl->parm_stack_boundary > INCOMING_STACK_BOUNDARY)
-    incoming_stack_boundary = crtl->parm_stack_boundary;
-  else
-    incoming_stack_boundary = INCOMING_STACK_BOUNDARY;
-
   crtl->stack_realign_needed
-    = incoming_stack_boundary < crtl->stack_alignment_estimated;
+    = INCOMING_STACK_BOUNDARY < crtl->stack_alignment_estimated;
   crtl->stack_realign_tried = crtl->stack_realign_needed;
 
   crtl->stack_realign_processed = true;
@@ -2359,6 +2351,23 @@ gimple_expand_cfg (void)
   if (crtl->stack_protect_guard)
     stack_protect_prologue ();
 
+  /* Update stack boundary if needed.  */
+  if (SUPPORTS_STACK_ALIGNMENT)
+    {
+      /* Call update_stack_boundary here to update incoming stack
+        boundary before TARGET_FUNCTION_OK_FOR_SIBCALL is called.
+        TARGET_FUNCTION_OK_FOR_SIBCALL needs to know the accurate
+        incoming stack alignment to check if it is OK to perform
+        sibcall optimization since sibcall optimization will only
+        align the outgoing stack to incoming stack boundary.  */
+      if (targetm.calls.update_stack_boundary)
+       targetm.calls.update_stack_boundary ();
+      
+      /* The incoming stack frame has to be aligned at least at
+        parm_stack_boundary.  */
+      gcc_assert (crtl->parm_stack_boundary <= INCOMING_STACK_BOUNDARY);
+    }
+
   /* Register rtl specific functions for cfg.  */
   rtl_register_cfg_hooks ();