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