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