aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2006-03-17 06:08:49 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2006-03-17 06:08:49 +0000
commit6a03730827b4347e69202e7414a7abe48d9eaead (patch)
tree0f26026fd36a604d0cd5d16bb4e1df5a2aa21e8a
parentd97c12956f0d920c2a2cd617a2c7c08db7d0cfa7 (diff)
downloadgcc-6a03730827b4347e69202e7414a7abe48d9eaead.zip
gcc-6a03730827b4347e69202e7414a7abe48d9eaead.tar.gz
gcc-6a03730827b4347e69202e7414a7abe48d9eaead.tar.bz2
dwarf2out.c (dwarf2out_stack_adjust): Always track the stack pointer...
* 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. From-SVN: r112170
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/dwarf2out.c49
2 files changed, 29 insertions, 26 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a568a02..a63b7d0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2006-03-17 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.
+
2006-03-16 Jan-Benedict Glaw <jbglaw@lug-owl.de>
* rtl.h (CONST_INT_P): Define.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 9308cce..ccfb5df 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -1072,7 +1072,7 @@ stack_adjust_offset (rtx pattern)
much extra space it needs to pop off the stack. */
static void
-dwarf2out_stack_adjust (rtx insn, bool after_p)
+dwarf2out_stack_adjust (rtx insn, bool after_p ATTRIBUTE_UNUSED)
{
HOST_WIDE_INT offset;
const char *label;
@@ -1085,31 +1085,7 @@ dwarf2out_stack_adjust (rtx insn, bool after_p)
if (prologue_epilogue_contains (insn) || sibcall_epilogue_contains (insn))
return;
- /* If only calls can throw, and we have a frame pointer,
- save up adjustments until we see the CALL_INSN. */
- if (!flag_asynchronous_unwind_tables && cfa.reg != STACK_POINTER_REGNUM)
- {
- if (CALL_P (insn) && !after_p)
- {
- /* 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);
- gcc_assert (GET_CODE (insn) == CALL);
- dwarf2out_args_size ("", INTVAL (XEXP (insn, 1)));
- }
- return;
- }
-
- if (CALL_P (insn) && !after_p)
- {
- if (!flag_asynchronous_unwind_tables)
- dwarf2out_args_size ("", args_size);
- return;
- }
- else if (BARRIER_P (insn))
+ if (BARRIER_P (insn))
{
/* When we see a BARRIER, we know to reset args_size to 0. Usually
the compiler will have already emitted a stack adjustment, but
@@ -1131,9 +1107,20 @@ dwarf2out_stack_adjust (rtx insn, bool after_p)
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;
@@ -1148,6 +1135,16 @@ dwarf2out_stack_adjust (rtx insn, bool after_p)
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);
if (flag_asynchronous_unwind_tables)