This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] spu: fix broken debug info
- From: "Ulrich Weigand" <uweigand at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 15 Dec 2006 00:38:38 +0100 (CET)
- Subject: [PATCH] spu: fix broken debug info
Hello,
mainline GCC creates rather broken debug info for SPU, causing dozens of
GDB testsuite failures. The reason ultimately is incorrect DWARF-2 CFI
data -- note that this matters even though we don't use CFI for unwinding
(and GDB doesn't explicitly use CFI on SPU either), because the common
DWARF-2 GCC code derives a location list for the "frame base" from
the CFI. If this is broken, basically all local variables cannot be
properly accessed by the debugger.
There were two main reasons for the broken CFI:
- ARG_POINTER_CFA_OFFSET was not defined, which caused common code to
place the CFA at the arg pointer location. This is off by 32.
- The prolog expander didn't use RTX_FRAME_RELATED_P quite the way
the common code expects. We need to mark the insn that sets up
the frame pointer as RTX_FRAME_RELATED_P, or else the CFA is broken
in routines that need a frame pointer.
However, the current SPU back-end code did mark some insns that
simply load a scratch register from the stack pointer as frame-
related, causing common code to consider the scratch register
as frame pointer!
Fortunately, it appears the reason for this is simply that the
scratch registers in question were related to storing the stack
backchain, and the existing code attempts to track that in CFI.
However, it is not actually necessary to do that. Unwinding
the stack pointer is special-cased anyway, it is always unwound
to the CFA value. Thus, there is no need to mark storing the
backchain or anything related to it as frame-related.
With those changes (which are already in our SDK build), the GDB
test suite passes without problems. (Except for some scope.exp
issues which appear to be test case bugs triggered by improved
optimizers in GCC 4.3.)
Tested on spu-elf. OK for mainline?
Bye,
Ulrich
ChangeLog:
* config/spu/spu.h (ARG_POINTER_CFA_OFFSET): Define.
* config/spu/spu.c (spu_expand_prologue): Set RTX_FRAME_RELATED_P
for insn setting up the frame pointer. Do not set it for insns
setting up scratch registers or storing the backchain.
Index: gcc/config/spu/spu.c
===================================================================
--- gcc/config/spu/spu.c (revision 119825)
+++ gcc/config/spu/spu.c (working copy)
@@ -1617,21 +1617,18 @@
{
/* In this case we save the back chain first. */
insn = frame_emit_store (STACK_POINTER_REGNUM, sp_reg, -total_size);
- RTX_FRAME_RELATED_P (insn) = 1;
insn =
frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_0);
}
else if (satisfies_constraint_K (GEN_INT (-total_size)))
{
insn = emit_move_insn (scratch_reg_0, sp_reg);
- RTX_FRAME_RELATED_P (insn) = 1;
insn =
emit_insn (gen_addsi3 (sp_reg, sp_reg, GEN_INT (-total_size)));
}
else
{
insn = emit_move_insn (scratch_reg_0, sp_reg);
- RTX_FRAME_RELATED_P (insn) = 1;
insn =
frame_emit_add_imm (sp_reg, sp_reg, -total_size, scratch_reg_1);
}
@@ -1644,7 +1641,6 @@
{
/* Save the back chain ptr */
insn = frame_emit_store (REGNO (scratch_reg_0), sp_reg, 0);
- RTX_FRAME_RELATED_P (insn) = 1;
}
if (frame_pointer_needed)
@@ -1653,7 +1649,12 @@
HOST_WIDE_INT fp_offset = STACK_POINTER_OFFSET
+ current_function_outgoing_args_size;
/* Set the new frame_pointer */
- frame_emit_add_imm (fp_reg, sp_reg, fp_offset, scratch_reg_0);
+ insn = frame_emit_add_imm (fp_reg, sp_reg, fp_offset, scratch_reg_0);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ real = gen_addsi3 (fp_reg, sp_reg, GEN_INT (fp_offset));
+ REG_NOTES (insn) =
+ gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
+ real, REG_NOTES (insn));
}
}
Index: gcc/config/spu/spu.h
===================================================================
--- gcc/config/spu/spu.h (revision 119825)
+++ gcc/config/spu/spu.h (working copy)
@@ -265,6 +265,8 @@
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG(Pmode, LINK_REGISTER_REGNUM)
+#define ARG_POINTER_CFA_OFFSET(FNDECL) (-STACK_POINTER_OFFSET)
+
/* Stack Checking */
--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com