This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] use REG_FRAME_RELATED_EXPR notes in var-tracking
- From: Bob Wilson <bwilson at tensilica dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 21 Oct 2008 10:47:59 -0700
- Subject: [PATCH] use REG_FRAME_RELATED_EXPR notes in var-tracking
The code in var-tracking.c relies on a simple analysis of stack pointer
adjustments to find stack offset values. If a stack adjustment is too big for
an immediate operand and needs a temporary register, or if the machine
description uses an UNSPEC pattern to set the stack pointer, the var-tracking
analysis fails and the variable locations described in DWARF are wrong. This is
especially bad for Xtensa, where the ENTRY opcode is described as an UNSPEC
because of the way it rotates the register windows. I could probably find
another way around that, but it still wouldn't solve the problem for large stack
frames, where the stack adjustment has to go in a temporary register.
This same problem is handled elsewhere using REG_FRAME_RELATED_EXPR notes, so
that is what this patch does.
I tested it by manually examining the debug info for an xtensa-elf build and for
a mips-elf build with a large stack frame testcase. I also bootstrapped an
i686-pc-linux-gnu native build and ran the testsuite to make sure there were no
regressions.
OK?
2008-10-21 Bob Wilson <bob.wilson@acm.org>
* var-tracking.c (insn_stack_adjust_offset_pre_post): If insn has a
REG_FRAME_RELATED_EXPR note, examine the pattern from the note instead
of from insn.
Index: var-tracking.c
===================================================================
--- var-tracking.c (revision 141246)
+++ var-tracking.c (working copy)
@@ -466,22 +466,31 @@
insn_stack_adjust_offset_pre_post (rtx insn, HOST_WIDE_INT *pre,
HOST_WIDE_INT *post)
{
+ rtx pattern;
+
*pre = 0;
*post = 0;
- if (GET_CODE (PATTERN (insn)) == SET)
- stack_adjust_offset_pre_post (PATTERN (insn), pre, post);
- else if (GET_CODE (PATTERN (insn)) == PARALLEL
- || GET_CODE (PATTERN (insn)) == SEQUENCE)
+ pattern = PATTERN (insn);
+ if (RTX_FRAME_RELATED_P (insn))
+ {
+ rtx expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX);
+ if (expr)
+ pattern = XEXP (expr, 0);
+ }
+
+ if (GET_CODE (pattern) == SET)
+ stack_adjust_offset_pre_post (pattern, pre, post);
+ else if (GET_CODE (pattern) == PARALLEL
+ || GET_CODE (pattern) == SEQUENCE)
{
int i;
/* There may be stack adjustments inside compound insns. Search
for them. */
- for ( i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
- if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET)
- stack_adjust_offset_pre_post (XVECEXP (PATTERN (insn), 0, i),
- pre, post);
+ for ( i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
+ if (GET_CODE (XVECEXP (pattern, 0, i)) == SET)
+ stack_adjust_offset_pre_post (XVECEXP (pattern, 0, i), pre, post);
}
}