2006-03-01 Alexandre Oliva * 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. --- gcc/dwarf2out.c.orig 2006-03-01 05:13:50.000000000 -0300 +++ gcc/dwarf2out.c 2006-03-01 05:41:38.000000000 -0300 @@ -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);