This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] spu: fix broken debug info


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?



	* 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)));
 	  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 @@
 	    + 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) = 
+			       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 @@
 /* Stack Checking */
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]