1b4105c
2006-03-01  Alexandre Oliva  <aoliva@redhat.com>
1b4105c
1b4105c
	* dwarf2out.c (dwarf2out_stack_adjust): Always track the stack
1b4105c
	pointer, instead of assuming it is possible to derive the
1b4105c
	correct args size from a call insn.
1b4105c
1b4105c
--- gcc/dwarf2out.c.orig	2006-03-01 05:13:50.000000000 -0300
1b4105c
+++ gcc/dwarf2out.c	2006-03-01 05:41:38.000000000 -0300
1b4105c
@@ -1069,26 +1069,6 @@ dwarf2out_stack_adjust (rtx insn)
1b4105c
   if (prologue_epilogue_contains (insn) || sibcall_epilogue_contains (insn))
1b4105c
     return;
1b4105c
 
1b4105c
-  if (!flag_asynchronous_unwind_tables && GET_CODE (insn) == CALL_INSN)
1b4105c
-    {
1b4105c
-      /* Extract the size of the args from the CALL rtx itself.  */
1b4105c
-      insn = PATTERN (insn);
1b4105c
-      if (GET_CODE (insn) == PARALLEL)
1b4105c
-	insn = XVECEXP (insn, 0, 0);
1b4105c
-      if (GET_CODE (insn) == SET)
1b4105c
-	insn = SET_SRC (insn);
1b4105c
-      if (GET_CODE (insn) != CALL)
1b4105c
-	abort ();
1b4105c
-
1b4105c
-      dwarf2out_args_size ("", INTVAL (XEXP (insn, 1)));
1b4105c
-      return;
1b4105c
-    }
1b4105c
-
1b4105c
-  /* If only calls can throw, and we have a frame pointer,
1b4105c
-     save up adjustments until we see the CALL_INSN.  */
1b4105c
-  else if (!flag_asynchronous_unwind_tables && cfa.reg != STACK_POINTER_REGNUM)
1b4105c
-    return;
1b4105c
-
1b4105c
   if (GET_CODE (insn) == BARRIER)
1b4105c
     {
1b4105c
       /* When we see a BARRIER, we know to reset args_size to 0.  Usually
1b4105c
@@ -1111,9 +1091,20 @@ dwarf2out_stack_adjust (rtx insn)
1b4105c
 	if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
1b4105c
 	  offset += stack_adjust_offset (XVECEXP (PATTERN (insn), 0, i));
1b4105c
     }
1b4105c
+  else if (GET_CODE (insn) == CALL_INSN)
1b4105c
+    offset = 0;
1b4105c
   else
1b4105c
     return;
1b4105c
 
1b4105c
+  /* We handle this separately because we want stack adjustments in a
1b4105c
+     CALL_INSN to be handled.  */;
1b4105c
+  if (GET_CODE (insn) == CALL_INSN)
1b4105c
+    {
1b4105c
+      /* If only calls can throw, adjust args_size only at call sites.  */
1b4105c
+      if (!flag_asynchronous_unwind_tables)
1b4105c
+	dwarf2out_args_size ("", args_size);
1b4105c
+    }
1b4105c
+
1b4105c
   if (offset == 0)
1b4105c
     return;
1b4105c
 
1b4105c
@@ -1128,6 +1119,16 @@ dwarf2out_stack_adjust (rtx insn)
1b4105c
   if (args_size < 0)
1b4105c
     args_size = 0;
1b4105c
 
1b4105c
+  /* If only calls can throw and we have a frame pointer, we'll save
1b4105c
+     up adjustments until we see the CALL_INSN.  We used to return
1b4105c
+     early and derive args_size from NARGS in the CALL_INSN itself,
1b4105c
+     but that doesn't compute the right value if we have nested call
1b4105c
+     expansions, e.g., stack adjustments for a call have already been
1b4105c
+     emitted, and then we issue another call to compute an argument
1b4105c
+     for the enclosing call (i.e., bar (foo ())).  */
1b4105c
+  if (!flag_asynchronous_unwind_tables && cfa.reg != STACK_POINTER_REGNUM)
1b4105c
+    return;
1b4105c
+
1b4105c
   label = dwarf2out_cfi_label ();
1b4105c
   def_cfa_1 (label, &cfa;;
1b4105c
   dwarf2out_args_size (label, args_size);