This is the mail archive of the gcc-patches@gcc.gnu.org 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]

Fix PR debug/24444: incorrect frame base in IA64 prologues


The attached patches, for trunk and 4.1 branch respectively (only line
offset differences), fix the portion of the debug info regression
introduced in revision -r103983 that was not fixed with Jim Wilson's
patch for bug 24444.

With this patch, we switch to using the CFA as the frame base on all
targets, even those that do not use DWARF2 frame or unwind info (like
IA64).  The bug report says ARM might suffer from the same problem,
because it also has its own internal unwind info, but I could not find
any such problem on arm-linux-gnu or arm-eabi: the latter emits DWARF2
frame info in addition to its own unwind info, so debug info is
correct within the prologue as much as it is in steady state.

This was not the case of IA64, since it did not want frame info
either, given that its unwind info is sufficiently complete for
debuggers to use.

I had to tweak a little bit the definitions of DWARF2_FRAME_INFO, so
as to avoid emitting frame info for IA64 while still computing the
info needed to determine the CFA offsets.  I also arranged for
DWARF2_UNWIND_INFO's run-time value to be tested at places where we'd
formerly only test for a definition, so target could now switch it on
or off depending on command-line options.

We used to emit a separate region for the epilogue, between the SP
restore and the return, but that's mainly useless since they're
normally neighbors.  No other targets emit separate regions for that
part of the epilogue, so I left the code to do so disabled in my
patch, but it could be easily enabled, should someone want to restore
the ability to set a breakpoint on the return instruction and still
print the values of variables et al, by changing a simple macro
definition.

The patch also fixes the definition of ARG_POINTER_CFA_OFFSET for
IA64; it was not taking into account the fact that ARG_POINTER is past
the red zone, whereas CFA is not.

This patch is past stage2 on ia64 and x86_64, both trunk and 4.1
branches, and I've verified that the intended debug info regression
fix is present, namely, compiling with optimization a function with a
large number of arguments, some of which are passed on the stack, and
setting a breakpoint on the function's entry point, the values of all
arguments are printed correctly by gdb.  Before the patch, arguments
passed on the stack would not have the correct values.

Without optimization, the patch brings little to no improvement, since
the debug info we emit for the arguments refer to copies of the
incoming arguments, allocated in the function's own stack frame, so at
the prologue they are not initialized yet.  We get incorrect values
for *all* incoming arguments.

Ok for trunk and branch if bootstrap and testing completes
successfully on both platforms?

Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/24444
	* config/ia64/ia64.c: Include debug.h.
	(MAX_ARTIFICIAL_LABEL_BYTES): New.
	(ia64_label_after_insn, ia64_dwarf2out_def_steady_cfa): New.
	(IA64_CHANGE_CFA_IN_EPILOGUE): Define to 0.
	(process_epilogue, process_set, process_for_unwind_directive):
	Output unwind info only if requested.  Add CFA info if requested.
	Add new arguments as needed.  Adjust callers.
	* config/ia64/ia64.h (ARG_POINTER_CFA_OFFSET): Override
	incorrect default.
	(DWARF2_FRAME_INFO): Define to zero.
	* config/ia64/t-ia64 (ia64.o): Depend on debug.h.
	* dwarf2out.c (DWARF2_FRAME_INFO): Define default.
	(dwarf2out_do_frame): Require nonzero DWARF2_UNWIND_INFO for
	-funwind-tables and -fexceptions to enable frame info.
	(dwarf2out_frame_init): Define initial CFA even if
	DWARF2_UNWIND_INFO is disabled.  Call initial_return_save if
	DWARF2_UNWIND_INFO is nonzero, not just defined.
	(dwarf2out_frame_finish): Output non-EH call frame info only
	if DWARF2_FRAME_INFO is nonzero.
	(convert_cfa_to_loc_list,
	compute_frame_pointer_to_cfa_displacement): Define even if
	unwind info is not supported.
	(gen_subprogram_die): Use the above unconditionally.  Remove
	legacy alternate code.
	* toplev.c (compile_file): Compile in call to
	dwarf2out_frame_finish if DWARF2_DEBUGGING_INFO is defined.
	(lang_dependent_init): Ditto for dwarf2out_frame_init.

Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c.orig	2005-12-16 14:40:47.000000000 -0200
+++ gcc/config/ia64/ia64.c	2006-02-03 04:28:33.000000000 -0200
@@ -53,6 +53,7 @@ Boston, MA 02110-1301, USA.  */
 #include "cfglayout.h"
 #include "tree-gimple.h"
 #include "intl.h"
+#include "debug.h"
 
 /* This is used for communication between ASM_OUTPUT_LABEL and
    ASM_OUTPUT_LABELREF.  */
@@ -190,8 +191,8 @@ static void final_emit_insn_group_barrie
 static void emit_predicate_relation_info (void);
 static void ia64_reorg (void);
 static bool ia64_in_small_data_p (tree);
-static void process_epilogue (void);
-static int process_set (FILE *, rtx);
+static void process_epilogue (FILE *, rtx, bool, bool);
+static int process_set (FILE *, rtx, rtx, bool, bool);
 
 static bool ia64_assemble_integer (rtx, unsigned int, int);
 static void ia64_output_function_prologue (FILE *, HOST_WIDE_INT);
@@ -7971,29 +7972,84 @@ static bool last_block;
 
 static bool need_copy_state;
 
+#ifndef MAX_ARTIFICIAL_LABEL_BYTES
+# define MAX_ARTIFICIAL_LABEL_BYTES 30
+#endif
+
+/* Emit a debugging label after a call-frame-related insn.  We'd
+   rather output the label right away, but we'd have to output it
+   after, not before, the instruction, and the instruction has not
+   been output yet.  So we emit the label after the insn, delete it to
+   avoid introducing basic blocks, and mark it as preserved, such that
+   it is still output, given that it is referenced in debug info.  */
+
+static const char *
+ia64_emit_deleted_label_after_insn (rtx insn)
+{
+  char label[MAX_ARTIFICIAL_LABEL_BYTES];
+  rtx lb = gen_label_rtx ();
+  rtx label_insn = emit_label_after (lb, insn);
+
+  LABEL_PRESERVE_P (lb) = 1;
+
+  delete_insn (label_insn);
+
+  ASM_GENERATE_INTERNAL_LABEL (label, "L", CODE_LABEL_NUMBER (label_insn));
+
+  return xstrdup (label);
+}
+
+/* Define the CFA after INSN with the steady-state definition.  */
+
+static void
+ia64_dwarf2out_def_steady_cfa (rtx insn)
+{
+  rtx fp = frame_pointer_needed
+    ? hard_frame_pointer_rtx
+    : stack_pointer_rtx;
+
+  dwarf2out_def_cfa
+    (ia64_emit_deleted_label_after_insn (insn),
+     REGNO (fp),
+     ia64_initial_elimination_offset
+     (REGNO (arg_pointer_rtx), REGNO (fp))
+     + ARG_POINTER_CFA_OFFSET (current_function_decl));
+}
+
+/* The generic dwarf2 frame debug info generator does not define a
+   separate region for the very end of the epilogue, so refrain from
+   doing so in the IA64-specific code as well.  */
+
+#define IA64_CHANGE_CFA_IN_EPILOGUE 0
+
 /* The function emits unwind directives for the start of an epilogue.  */
 
 static void
-process_epilogue (void)
+process_epilogue (FILE *asm_out_file, rtx insn, bool unwind, bool frame)
 {
   /* If this isn't the last block of the function, then we need to label the
      current state, and copy it back in at the start of the next block.  */
 
   if (!last_block)
     {
-      fprintf (asm_out_file, "\t.label_state %d\n",
-	       ++cfun->machine->state_num);
+      if (unwind)
+	fprintf (asm_out_file, "\t.label_state %d\n",
+		 ++cfun->machine->state_num);
       need_copy_state = true;
     }
 
-  fprintf (asm_out_file, "\t.restore sp\n");
+  if (unwind)
+    fprintf (asm_out_file, "\t.restore sp\n");
+  if (IA64_CHANGE_CFA_IN_EPILOGUE && frame)
+    dwarf2out_def_cfa (ia64_emit_deleted_label_after_insn (insn),
+		       STACK_POINTER_REGNUM, INCOMING_FRAME_SP_OFFSET);
 }
 
 /* This function processes a SET pattern looking for specific patterns
    which result in emitting an assembly directive required for unwinding.  */
 
 static int
-process_set (FILE *asm_out_file, rtx pat)
+process_set (FILE *asm_out_file, rtx pat, rtx insn, bool unwind, bool frame)
 {
   rtx src = SET_SRC (pat);
   rtx dest = SET_DEST (pat);
@@ -8009,8 +8065,11 @@ process_set (FILE *asm_out_file, rtx pat
       /* If this is the final destination for ar.pfs, then this must
 	 be the alloc in the prologue.  */
       if (dest_regno == current_frame_info.reg_save_ar_pfs)
-	fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
-		 ia64_dbx_register_number (dest_regno));
+	{
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
+		     ia64_dbx_register_number (dest_regno));
+	}
       else
 	{
 	  /* This must be an alloc before a sibcall.  We must drop the
@@ -8021,8 +8080,9 @@ process_set (FILE *asm_out_file, rtx pat
 	     sp" now.  */
 	  if (current_frame_info.total_size == 0 && !frame_pointer_needed)
 	    /* if haven't done process_epilogue() yet, do it now */
-	    process_epilogue ();
-	  fprintf (asm_out_file, "\t.prologue\n");
+	    process_epilogue (asm_out_file, insn, unwind, frame);
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.prologue\n");
 	}
       return 1;
     }
@@ -8038,16 +8098,22 @@ process_set (FILE *asm_out_file, rtx pat
 	  gcc_assert (op0 == dest && GET_CODE (op1) == CONST_INT);
 	  
 	  if (INTVAL (op1) < 0)
-	    fprintf (asm_out_file, "\t.fframe "HOST_WIDE_INT_PRINT_DEC"\n",
-		     -INTVAL (op1));
+	    {
+	      gcc_assert (!frame_pointer_needed);
+	      if (unwind)
+		fprintf (asm_out_file, "\t.fframe "HOST_WIDE_INT_PRINT_DEC"\n",
+			 -INTVAL (op1));
+	      if (frame)
+		ia64_dwarf2out_def_steady_cfa (insn);
+	    }
 	  else
-	    process_epilogue ();
+	    process_epilogue (asm_out_file, insn, unwind, frame);
 	}
       else
 	{
 	  gcc_assert (GET_CODE (src) == REG
 		      && REGNO (src) == HARD_FRAME_POINTER_REGNUM);
-	  process_epilogue ();
+	  process_epilogue (asm_out_file, insn, unwind, frame);
 	}
 
       return 1;
@@ -8064,33 +8130,40 @@ process_set (FILE *asm_out_file, rtx pat
 	case BR_REG (0):
 	  /* Saving return address pointer.  */
 	  gcc_assert (dest_regno == current_frame_info.reg_save_b0);
-	  fprintf (asm_out_file, "\t.save rp, r%d\n",
-		   ia64_dbx_register_number (dest_regno));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save rp, r%d\n",
+		     ia64_dbx_register_number (dest_regno));
 	  return 1;
 
 	case PR_REG (0):
 	  gcc_assert (dest_regno == current_frame_info.reg_save_pr);
-	  fprintf (asm_out_file, "\t.save pr, r%d\n",
-		   ia64_dbx_register_number (dest_regno));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save pr, r%d\n",
+		     ia64_dbx_register_number (dest_regno));
 	  return 1;
 
 	case AR_UNAT_REGNUM:
 	  gcc_assert (dest_regno == current_frame_info.reg_save_ar_unat);
-	  fprintf (asm_out_file, "\t.save ar.unat, r%d\n",
-		   ia64_dbx_register_number (dest_regno));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save ar.unat, r%d\n",
+		     ia64_dbx_register_number (dest_regno));
 	  return 1;
 
 	case AR_LC_REGNUM:
 	  gcc_assert (dest_regno == current_frame_info.reg_save_ar_lc);
-	  fprintf (asm_out_file, "\t.save ar.lc, r%d\n",
-		   ia64_dbx_register_number (dest_regno));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save ar.lc, r%d\n",
+		     ia64_dbx_register_number (dest_regno));
 	  return 1;
 
 	case STACK_POINTER_REGNUM:
 	  gcc_assert (dest_regno == HARD_FRAME_POINTER_REGNUM
 		      && frame_pointer_needed);
-	  fprintf (asm_out_file, "\t.vframe r%d\n",
-		   ia64_dbx_register_number (dest_regno));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.vframe r%d\n",
+		     ia64_dbx_register_number (dest_regno));
+	  if (frame)
+	    ia64_dwarf2out_def_steady_cfa (insn);
 	  return 1;
 
 	default:
@@ -8135,35 +8208,41 @@ process_set (FILE *asm_out_file, rtx pat
 	{
 	case BR_REG (0):
 	  gcc_assert (!current_frame_info.reg_save_b0);
-	  fprintf (asm_out_file, "\t%s rp, %ld\n", saveop, off);
+	  if (unwind)
+	    fprintf (asm_out_file, "\t%s rp, %ld\n", saveop, off);
 	  return 1;
 
 	case PR_REG (0):
 	  gcc_assert (!current_frame_info.reg_save_pr);
-	  fprintf (asm_out_file, "\t%s pr, %ld\n", saveop, off);
+	  if (unwind)
+	    fprintf (asm_out_file, "\t%s pr, %ld\n", saveop, off);
 	  return 1;
 
 	case AR_LC_REGNUM:
 	  gcc_assert (!current_frame_info.reg_save_ar_lc);
-	  fprintf (asm_out_file, "\t%s ar.lc, %ld\n", saveop, off);
+	  if (unwind)
+	    fprintf (asm_out_file, "\t%s ar.lc, %ld\n", saveop, off);
 	  return 1;
 
 	case AR_PFS_REGNUM:
 	  gcc_assert (!current_frame_info.reg_save_ar_pfs);
-	  fprintf (asm_out_file, "\t%s ar.pfs, %ld\n", saveop, off);
+	  if (unwind)
+	    fprintf (asm_out_file, "\t%s ar.pfs, %ld\n", saveop, off);
 	  return 1;
 
 	case AR_UNAT_REGNUM:
 	  gcc_assert (!current_frame_info.reg_save_ar_unat);
-	  fprintf (asm_out_file, "\t%s ar.unat, %ld\n", saveop, off);
+	  if (unwind)
+	    fprintf (asm_out_file, "\t%s ar.unat, %ld\n", saveop, off);
 	  return 1;
 
 	case GR_REG (4):
 	case GR_REG (5):
 	case GR_REG (6):
 	case GR_REG (7):
-	  fprintf (asm_out_file, "\t.save.g 0x%x\n",
-		   1 << (src_regno - GR_REG (4)));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save.g 0x%x\n",
+		     1 << (src_regno - GR_REG (4)));
 	  return 1;
 
 	case BR_REG (1):
@@ -8171,24 +8250,27 @@ process_set (FILE *asm_out_file, rtx pat
 	case BR_REG (3):
 	case BR_REG (4):
 	case BR_REG (5):
-	  fprintf (asm_out_file, "\t.save.b 0x%x\n",
-		   1 << (src_regno - BR_REG (1)));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save.b 0x%x\n",
+		     1 << (src_regno - BR_REG (1)));
 	  return 1;
 
 	case FR_REG (2):
 	case FR_REG (3):
 	case FR_REG (4):
 	case FR_REG (5):
-	  fprintf (asm_out_file, "\t.save.f 0x%x\n",
-		   1 << (src_regno - FR_REG (2)));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save.f 0x%x\n",
+		     1 << (src_regno - FR_REG (2)));
 	  return 1;
 
 	case FR_REG (16): case FR_REG (17): case FR_REG (18): case FR_REG (19):
 	case FR_REG (20): case FR_REG (21): case FR_REG (22): case FR_REG (23):
 	case FR_REG (24): case FR_REG (25): case FR_REG (26): case FR_REG (27):
 	case FR_REG (28): case FR_REG (29): case FR_REG (30): case FR_REG (31):
-	  fprintf (asm_out_file, "\t.save.gf 0x0, 0x%x\n",
-		   1 << (src_regno - FR_REG (12)));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save.gf 0x0, 0x%x\n",
+		     1 << (src_regno - FR_REG (12)));
 	  return 1;
 
 	default:
@@ -8205,8 +8287,11 @@ process_set (FILE *asm_out_file, rtx pat
 void
 process_for_unwind_directive (FILE *asm_out_file, rtx insn)
 {
-  if (flag_unwind_tables
-      || (flag_exceptions && !USING_SJLJ_EXCEPTIONS))
+  bool unwind = (flag_unwind_tables
+		 || (flag_exceptions && !USING_SJLJ_EXCEPTIONS));
+  bool frame = dwarf2out_do_frame ();
+
+  if (unwind || frame)
     {
       rtx pat;
 
@@ -8218,9 +8303,14 @@ process_for_unwind_directive (FILE *asm_
 	  /* Restore unwind state from immediately before the epilogue.  */
 	  if (need_copy_state)
 	    {
-	      fprintf (asm_out_file, "\t.body\n");
-	      fprintf (asm_out_file, "\t.copy_state %d\n",
-		       cfun->machine->state_num);
+	      if (unwind)
+		{
+		  fprintf (asm_out_file, "\t.body\n");
+		  fprintf (asm_out_file, "\t.copy_state %d\n",
+			   cfun->machine->state_num);
+		}
+	      if (IA64_CHANGE_CFA_IN_EPILOGUE && frame)
+		ia64_dwarf2out_def_steady_cfa (insn);
 	      need_copy_state = false;
 	    }
 	}
@@ -8237,7 +8327,7 @@ process_for_unwind_directive (FILE *asm_
       switch (GET_CODE (pat))
         {
 	case SET:
-	  process_set (asm_out_file, pat);
+	  process_set (asm_out_file, pat, insn, unwind, frame);
 	  break;
 
 	case PARALLEL:
@@ -8248,7 +8338,7 @@ process_for_unwind_directive (FILE *asm_
 	      {
 		rtx x = XVECEXP (pat, 0, par_index);
 		if (GET_CODE (x) == SET)
-		  process_set (asm_out_file, x);
+		  process_set (asm_out_file, x, insn, unwind, frame);
 	      }
 	    break;
 	  }
Index: gcc/config/ia64/ia64.h
===================================================================
--- gcc/config/ia64/ia64.h.orig	2006-02-03 03:09:18.000000000 -0200
+++ gcc/config/ia64/ia64.h	2006-02-03 04:04:03.000000000 -0200
@@ -981,6 +981,12 @@ enum reg_class
    On some machines it may depend on the data type of the function.  */
 #define FIRST_PARM_OFFSET(FUNDECL) 0
 
+/* The CFA is defined as the SP at the call site, so we have to take
+   into account that the first argument pointer is
+   STACK_POINTER_OFFSET bytes off the stack pointer.  */
+#define ARG_POINTER_CFA_OFFSET(FNDECL) \
+  (FIRST_PARM_OFFSET (FNDECL) - STACK_POINTER_OFFSET)
+
 /* A C expression whose value is RTL representing the value of the return
    address for the frame COUNT steps up from the current frame, after the
    prologue.  */
@@ -1867,6 +1873,12 @@ do {									\
 
 #define DWARF2_DEBUGGING_INFO 1
 
+/* We do not want call-frame info to be output, since debuggers are
+   supposed to use the target unwind info.  Leave this undefined it
+   TARGET_UNWIND_INFO might ever be false.  */
+
+#define DWARF2_FRAME_INFO 0
+
 #define DWARF2_ASM_LINE_DEBUG_INFO (TARGET_DWARF2_ASM)
 
 /* Use tags for debug info labels, so that they don't break instruction
Index: gcc/config/ia64/t-ia64
===================================================================
--- gcc/config/ia64/t-ia64.orig	2006-02-03 03:09:18.000000000 -0200
+++ gcc/config/ia64/t-ia64	2006-02-03 04:04:03.000000000 -0200
@@ -50,3 +50,5 @@ ia64-c.o: $(srcdir)/config/ia64/ia64-c.c
 
 # genattrtab generates very long string literals.
 insn-attrtab.o-warn = -Wno-error
+
+ia64.o: debug.h
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c.orig	2006-02-03 03:45:15.000000000 -0200
+++ gcc/dwarf2out.c	2006-02-03 05:41:31.000000000 -0200
@@ -90,20 +90,31 @@ static void dwarf2out_source_line (unsig
    DW_CFA_... = DWARF2 CFA call frame instruction
    DW_TAG_... = DWARF2 DIE tag */
 
+#ifndef DWARF2_FRAME_INFO
+# ifdef DWARF2_DEBUGGING_INFO
+#  define DWARF2_FRAME_INFO \
+  (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
+# else
+#  define DWARF2_FRAME_INFO 0
+# endif
+#endif
+
 /* Decide whether we want to emit frame unwind information for the current
    translation unit.  */
 
 int
 dwarf2out_do_frame (void)
 {
+  /* We want to emit correct CFA location expressions or lists, so we
+     have to return true if we're going to output debug info, even if
+     we're not going to output frame or unwind info.  */
   return (write_symbols == DWARF2_DEBUG
 	  || write_symbols == VMS_AND_DWARF2_DEBUG
-#ifdef DWARF2_FRAME_INFO
 	  || DWARF2_FRAME_INFO
-#endif
 #ifdef DWARF2_UNWIND_INFO
-	  || flag_unwind_tables
-	  || (flag_exceptions && ! USING_SJLJ_EXCEPTIONS)
+	  || (DWARF2_UNWIND_INFO
+	      && (flag_unwind_tables
+		  || (flag_exceptions && ! USING_SJLJ_EXCEPTIONS)))
 #endif
 	  );
 }
@@ -2586,10 +2597,12 @@ dwarf2out_frame_init (void)
   /* Generate the CFA instructions common to all FDE's.  Do it now for the
      sake of lookup_cfa.  */
 
-#ifdef DWARF2_UNWIND_INFO
   /* On entry, the Canonical Frame Address is at SP.  */
   dwarf2out_def_cfa (NULL, STACK_POINTER_REGNUM, INCOMING_FRAME_SP_OFFSET);
-  initial_return_save (INCOMING_RETURN_ADDR_RTX);
+
+#ifdef DWARF2_UNWIND_INFO
+  if (DWARF2_UNWIND_INFO)
+    initial_return_save (INCOMING_RETURN_ADDR_RTX);
 #endif
 }
 
@@ -2597,12 +2610,7 @@ void
 dwarf2out_frame_finish (void)
 {
   /* Output call frame information.  */
-  if (write_symbols == DWARF2_DEBUG
-      || write_symbols == VMS_AND_DWARF2_DEBUG
-#ifdef DWARF2_FRAME_INFO
-      || DWARF2_FRAME_INFO
-#endif
-      )
+  if (DWARF2_FRAME_INFO)
     output_call_frame_info (0);
 
 #ifndef TARGET_UNWIND_INFO
@@ -10326,7 +10334,6 @@ tree_add_const_value_attribute (dw_die_r
     add_const_value_attribute (var_die, rtl);
 }
 
-#ifdef DWARF2_UNWIND_INFO
 /* Convert the CFI instructions for the current function into a location
    list.  This is used for DW_AT_frame_base when we targeting a dwarf2
    consumer that does not support the dwarf3 DW_OP_call_frame_cfa.  */
@@ -10433,7 +10440,6 @@ compute_frame_pointer_to_cfa_displacemen
 
   frame_pointer_cfa_offset = -offset;
 }
-#endif
 
 /* Generate a DW_AT_name attribute given some string value to be included as
    the value of the attribute.  */
@@ -11668,7 +11674,6 @@ gen_subprogram_die (tree decl, dw_die_re
       add_AT_fde_ref (subr_die, DW_AT_MIPS_fde, current_funcdef_fde);
 #endif
 
-#ifdef DWARF2_UNWIND_INFO
       /* We define the "frame base" as the function's CFA.  This is more
 	 convenient for several reasons: (1) It's stable across the prologue
 	 and epilogue, which makes it better than just a frame pointer,
@@ -11695,17 +11700,6 @@ gen_subprogram_die (tree decl, dw_die_re
 	 debugger about.  We'll need to adjust all frame_base references
 	 by this displacement.  */
       compute_frame_pointer_to_cfa_displacement ();
-#else
-      /* For targets which support DWARF2, but not DWARF2 call-frame info,
-	 we just use the stack pointer or frame pointer.  */
-      /* ??? Should investigate getting better info via callbacks, or else
-	 by interpreting the IA-64 unwind info.  */
-      {
-	rtx fp_reg
-	  = frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx;
-	add_AT_loc (subr_die, DW_AT_frame_base, reg_loc_descriptor (fp_reg));
-      }
-#endif
 
       if (cfun->static_chain_decl)
 	add_AT_location_description (subr_die, DW_AT_static_link,
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c.orig	2006-02-03 03:45:15.000000000 -0200
+++ gcc/toplev.c	2006-02-03 04:04:03.000000000 -0200
@@ -1028,7 +1028,7 @@ compile_file (void)
   /* Do dbx symbols.  */
   timevar_push (TV_SYMOUT);
 
-#ifdef DWARF2_UNWIND_INFO
+#if defined DWARF2_DEBUGGING_INFO || defined DWARF2_UNWIND_INFO
   if (dwarf2out_do_frame ())
     dwarf2out_frame_finish ();
 #endif
@@ -1868,7 +1868,7 @@ lang_dependent_init (const char *name)
      predefined types.  */
   timevar_push (TV_SYMOUT);
 
-#ifdef DWARF2_UNWIND_INFO
+#if defined DWARF2_DEBUGGING_INFO || defined DWARF2_UNWIND_INFO
   if (dwarf2out_do_frame ())
     dwarf2out_frame_init ();
 #endif
Index: gcc/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	PR debug/24444
	* config/ia64/ia64.c: Include debug.h.
	(MAX_ARTIFICIAL_LABEL_BYTES): New.
	(ia64_label_after_insn, ia64_dwarf2out_def_steady_cfa): New.
	(IA64_CHANGE_CFA_IN_EPILOGUE): Define to 0.
	(process_epilogue, process_set, process_for_unwind_directive):
	Output unwind info only if requested.  Add CFA info if requested.
	Add new arguments as needed.  Adjust callers.
	* config/ia64/ia64.h (ARG_POINTER_CFA_OFFSET): Override
	incorrect default.
	(DWARF2_FRAME_INFO): Define to zero.
	* config/ia64/t-ia64 (ia64.o): Depend on debug.h.
	* dwarf2out.c (DWARF2_FRAME_INFO): Define default.
	(dwarf2out_do_frame): Require nonzero DWARF2_UNWIND_INFO for
	-funwind-tables and -fexceptions to enable frame info.
	(dwarf2out_frame_init): Define initial CFA even if
	DWARF2_UNWIND_INFO is disabled.  Call initial_return_save if
	DWARF2_UNWIND_INFO is nonzero, not just defined.
	(dwarf2out_frame_finish): Output non-EH call frame info only
	if DWARF2_FRAME_INFO is nonzero.
	(convert_cfa_to_loc_list,
	compute_frame_pointer_to_cfa_displacement): Define even if
	unwind info is not supported.
	(gen_subprogram_die): Use the above unconditionally.  Remove
	legacy alternate code.
	* toplev.c (compile_file): Compile in call to
	dwarf2out_frame_finish if DWARF2_DEBUGGING_INFO is defined.
	(lang_dependent_init): Ditto for dwarf2out_frame_init.

Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c.orig	2005-12-02 18:13:36.000000000 -0200
+++ gcc/config/ia64/ia64.c	2006-02-03 04:35:36.000000000 -0200
@@ -53,6 +53,7 @@ Boston, MA 02110-1301, USA.  */
 #include "cfglayout.h"
 #include "tree-gimple.h"
 #include "intl.h"
+#include "debug.h"
 
 /* This is used for communication between ASM_OUTPUT_LABEL and
    ASM_OUTPUT_LABELREF.  */
@@ -190,8 +191,8 @@ static void final_emit_insn_group_barrie
 static void emit_predicate_relation_info (void);
 static void ia64_reorg (void);
 static bool ia64_in_small_data_p (tree);
-static void process_epilogue (void);
-static int process_set (FILE *, rtx);
+static void process_epilogue (FILE *, rtx, bool, bool);
+static int process_set (FILE *, rtx, rtx, bool, bool);
 
 static bool ia64_assemble_integer (rtx, unsigned int, int);
 static void ia64_output_function_prologue (FILE *, HOST_WIDE_INT);
@@ -7971,29 +7972,84 @@ static bool last_block;
 
 static bool need_copy_state;
 
+#ifndef MAX_ARTIFICIAL_LABEL_BYTES
+# define MAX_ARTIFICIAL_LABEL_BYTES 30
+#endif
+
+/* Emit a debugging label after a call-frame-related insn.  We'd
+   rather output the label right away, but we'd have to output it
+   after, not before, the instruction, and the instruction has not
+   been output yet.  So we emit the label after the insn, delete it to
+   avoid introducing basic blocks, and mark it as preserved, such that
+   it is still output, given that it is referenced in debug info.  */
+
+static const char *
+ia64_emit_deleted_label_after_insn (rtx insn)
+{
+  char label[MAX_ARTIFICIAL_LABEL_BYTES];
+  rtx lb = gen_label_rtx ();
+  rtx label_insn = emit_label_after (lb, insn);
+
+  LABEL_PRESERVE_P (lb) = 1;
+
+  delete_insn (label_insn);
+
+  ASM_GENERATE_INTERNAL_LABEL (label, "L", CODE_LABEL_NUMBER (label_insn));
+
+  return xstrdup (label);
+}
+
+/* Define the CFA after INSN with the steady-state definition.  */
+
+static void
+ia64_dwarf2out_def_steady_cfa (rtx insn)
+{
+  rtx fp = frame_pointer_needed
+    ? hard_frame_pointer_rtx
+    : stack_pointer_rtx;
+
+  dwarf2out_def_cfa
+    (ia64_emit_deleted_label_after_insn (insn),
+     REGNO (fp),
+     ia64_initial_elimination_offset
+     (REGNO (arg_pointer_rtx), REGNO (fp))
+     + ARG_POINTER_CFA_OFFSET (current_function_decl));
+}
+
+/* The generic dwarf2 frame debug info generator does not define a
+   separate region for the very end of the epilogue, so refrain from
+   doing so in the IA64-specific code as well.  */
+
+#define IA64_CHANGE_CFA_IN_EPILOGUE 0
+
 /* The function emits unwind directives for the start of an epilogue.  */
 
 static void
-process_epilogue (void)
+process_epilogue (FILE *asm_out_file, rtx insn, bool unwind, bool frame)
 {
   /* If this isn't the last block of the function, then we need to label the
      current state, and copy it back in at the start of the next block.  */
 
   if (!last_block)
     {
-      fprintf (asm_out_file, "\t.label_state %d\n",
-	       ++cfun->machine->state_num);
+      if (unwind)
+	fprintf (asm_out_file, "\t.label_state %d\n",
+		 ++cfun->machine->state_num);
       need_copy_state = true;
     }
 
-  fprintf (asm_out_file, "\t.restore sp\n");
+  if (unwind)
+    fprintf (asm_out_file, "\t.restore sp\n");
+  if (IA64_CHANGE_CFA_IN_EPILOGUE && frame)
+    dwarf2out_def_cfa (ia64_emit_deleted_label_after_insn (insn),
+		       STACK_POINTER_REGNUM, INCOMING_FRAME_SP_OFFSET);
 }
 
 /* This function processes a SET pattern looking for specific patterns
    which result in emitting an assembly directive required for unwinding.  */
 
 static int
-process_set (FILE *asm_out_file, rtx pat)
+process_set (FILE *asm_out_file, rtx pat, rtx insn, bool unwind, bool frame)
 {
   rtx src = SET_SRC (pat);
   rtx dest = SET_DEST (pat);
@@ -8009,8 +8065,11 @@ process_set (FILE *asm_out_file, rtx pat
       /* If this is the final destination for ar.pfs, then this must
 	 be the alloc in the prologue.  */
       if (dest_regno == current_frame_info.reg_save_ar_pfs)
-	fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
-		 ia64_dbx_register_number (dest_regno));
+	{
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save ar.pfs, r%d\n",
+		     ia64_dbx_register_number (dest_regno));
+	}
       else
 	{
 	  /* This must be an alloc before a sibcall.  We must drop the
@@ -8021,8 +8080,9 @@ process_set (FILE *asm_out_file, rtx pat
 	     sp" now.  */
 	  if (current_frame_info.total_size == 0 && !frame_pointer_needed)
 	    /* if haven't done process_epilogue() yet, do it now */
-	    process_epilogue ();
-	  fprintf (asm_out_file, "\t.prologue\n");
+	    process_epilogue (asm_out_file, insn, unwind, frame);
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.prologue\n");
 	}
       return 1;
     }
@@ -8038,16 +8098,22 @@ process_set (FILE *asm_out_file, rtx pat
 	  gcc_assert (op0 == dest && GET_CODE (op1) == CONST_INT);
 	  
 	  if (INTVAL (op1) < 0)
-	    fprintf (asm_out_file, "\t.fframe "HOST_WIDE_INT_PRINT_DEC"\n",
-		     -INTVAL (op1));
+	    {
+	      gcc_assert (!frame_pointer_needed);
+	      if (unwind)
+		fprintf (asm_out_file, "\t.fframe "HOST_WIDE_INT_PRINT_DEC"\n",
+			 -INTVAL (op1));
+	      if (frame)
+		ia64_dwarf2out_def_steady_cfa (insn);
+	    }
 	  else
-	    process_epilogue ();
+	    process_epilogue (asm_out_file, insn, unwind, frame);
 	}
       else
 	{
 	  gcc_assert (GET_CODE (src) == REG
 		      && REGNO (src) == HARD_FRAME_POINTER_REGNUM);
-	  process_epilogue ();
+	  process_epilogue (asm_out_file, insn, unwind, frame);
 	}
 
       return 1;
@@ -8064,33 +8130,40 @@ process_set (FILE *asm_out_file, rtx pat
 	case BR_REG (0):
 	  /* Saving return address pointer.  */
 	  gcc_assert (dest_regno == current_frame_info.reg_save_b0);
-	  fprintf (asm_out_file, "\t.save rp, r%d\n",
-		   ia64_dbx_register_number (dest_regno));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save rp, r%d\n",
+		     ia64_dbx_register_number (dest_regno));
 	  return 1;
 
 	case PR_REG (0):
 	  gcc_assert (dest_regno == current_frame_info.reg_save_pr);
-	  fprintf (asm_out_file, "\t.save pr, r%d\n",
-		   ia64_dbx_register_number (dest_regno));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save pr, r%d\n",
+		     ia64_dbx_register_number (dest_regno));
 	  return 1;
 
 	case AR_UNAT_REGNUM:
 	  gcc_assert (dest_regno == current_frame_info.reg_save_ar_unat);
-	  fprintf (asm_out_file, "\t.save ar.unat, r%d\n",
-		   ia64_dbx_register_number (dest_regno));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save ar.unat, r%d\n",
+		     ia64_dbx_register_number (dest_regno));
 	  return 1;
 
 	case AR_LC_REGNUM:
 	  gcc_assert (dest_regno == current_frame_info.reg_save_ar_lc);
-	  fprintf (asm_out_file, "\t.save ar.lc, r%d\n",
-		   ia64_dbx_register_number (dest_regno));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save ar.lc, r%d\n",
+		     ia64_dbx_register_number (dest_regno));
 	  return 1;
 
 	case STACK_POINTER_REGNUM:
 	  gcc_assert (dest_regno == HARD_FRAME_POINTER_REGNUM
 		      && frame_pointer_needed);
-	  fprintf (asm_out_file, "\t.vframe r%d\n",
-		   ia64_dbx_register_number (dest_regno));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.vframe r%d\n",
+		     ia64_dbx_register_number (dest_regno));
+	  if (frame)
+	    ia64_dwarf2out_def_steady_cfa (insn);
 	  return 1;
 
 	default:
@@ -8135,35 +8208,41 @@ process_set (FILE *asm_out_file, rtx pat
 	{
 	case BR_REG (0):
 	  gcc_assert (!current_frame_info.reg_save_b0);
-	  fprintf (asm_out_file, "\t%s rp, %ld\n", saveop, off);
+	  if (unwind)
+	    fprintf (asm_out_file, "\t%s rp, %ld\n", saveop, off);
 	  return 1;
 
 	case PR_REG (0):
 	  gcc_assert (!current_frame_info.reg_save_pr);
-	  fprintf (asm_out_file, "\t%s pr, %ld\n", saveop, off);
+	  if (unwind)
+	    fprintf (asm_out_file, "\t%s pr, %ld\n", saveop, off);
 	  return 1;
 
 	case AR_LC_REGNUM:
 	  gcc_assert (!current_frame_info.reg_save_ar_lc);
-	  fprintf (asm_out_file, "\t%s ar.lc, %ld\n", saveop, off);
+	  if (unwind)
+	    fprintf (asm_out_file, "\t%s ar.lc, %ld\n", saveop, off);
 	  return 1;
 
 	case AR_PFS_REGNUM:
 	  gcc_assert (!current_frame_info.reg_save_ar_pfs);
-	  fprintf (asm_out_file, "\t%s ar.pfs, %ld\n", saveop, off);
+	  if (unwind)
+	    fprintf (asm_out_file, "\t%s ar.pfs, %ld\n", saveop, off);
 	  return 1;
 
 	case AR_UNAT_REGNUM:
 	  gcc_assert (!current_frame_info.reg_save_ar_unat);
-	  fprintf (asm_out_file, "\t%s ar.unat, %ld\n", saveop, off);
+	  if (unwind)
+	    fprintf (asm_out_file, "\t%s ar.unat, %ld\n", saveop, off);
 	  return 1;
 
 	case GR_REG (4):
 	case GR_REG (5):
 	case GR_REG (6):
 	case GR_REG (7):
-	  fprintf (asm_out_file, "\t.save.g 0x%x\n",
-		   1 << (src_regno - GR_REG (4)));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save.g 0x%x\n",
+		     1 << (src_regno - GR_REG (4)));
 	  return 1;
 
 	case BR_REG (1):
@@ -8171,24 +8250,27 @@ process_set (FILE *asm_out_file, rtx pat
 	case BR_REG (3):
 	case BR_REG (4):
 	case BR_REG (5):
-	  fprintf (asm_out_file, "\t.save.b 0x%x\n",
-		   1 << (src_regno - BR_REG (1)));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save.b 0x%x\n",
+		     1 << (src_regno - BR_REG (1)));
 	  return 1;
 
 	case FR_REG (2):
 	case FR_REG (3):
 	case FR_REG (4):
 	case FR_REG (5):
-	  fprintf (asm_out_file, "\t.save.f 0x%x\n",
-		   1 << (src_regno - FR_REG (2)));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save.f 0x%x\n",
+		     1 << (src_regno - FR_REG (2)));
 	  return 1;
 
 	case FR_REG (16): case FR_REG (17): case FR_REG (18): case FR_REG (19):
 	case FR_REG (20): case FR_REG (21): case FR_REG (22): case FR_REG (23):
 	case FR_REG (24): case FR_REG (25): case FR_REG (26): case FR_REG (27):
 	case FR_REG (28): case FR_REG (29): case FR_REG (30): case FR_REG (31):
-	  fprintf (asm_out_file, "\t.save.gf 0x0, 0x%x\n",
-		   1 << (src_regno - FR_REG (12)));
+	  if (unwind)
+	    fprintf (asm_out_file, "\t.save.gf 0x0, 0x%x\n",
+		     1 << (src_regno - FR_REG (12)));
 	  return 1;
 
 	default:
@@ -8205,8 +8287,11 @@ process_set (FILE *asm_out_file, rtx pat
 void
 process_for_unwind_directive (FILE *asm_out_file, rtx insn)
 {
-  if (flag_unwind_tables
-      || (flag_exceptions && !USING_SJLJ_EXCEPTIONS))
+  bool unwind = (flag_unwind_tables
+		 || (flag_exceptions && !USING_SJLJ_EXCEPTIONS));
+  bool frame = dwarf2out_do_frame ();
+
+  if (unwind || frame)
     {
       rtx pat;
 
@@ -8218,9 +8303,14 @@ process_for_unwind_directive (FILE *asm_
 	  /* Restore unwind state from immediately before the epilogue.  */
 	  if (need_copy_state)
 	    {
-	      fprintf (asm_out_file, "\t.body\n");
-	      fprintf (asm_out_file, "\t.copy_state %d\n",
-		       cfun->machine->state_num);
+	      if (unwind)
+		{
+		  fprintf (asm_out_file, "\t.body\n");
+		  fprintf (asm_out_file, "\t.copy_state %d\n",
+			   cfun->machine->state_num);
+		}
+	      if (IA64_CHANGE_CFA_IN_EPILOGUE && frame)
+		ia64_dwarf2out_def_steady_cfa (insn);
 	      need_copy_state = false;
 	    }
 	}
@@ -8237,7 +8327,7 @@ process_for_unwind_directive (FILE *asm_
       switch (GET_CODE (pat))
         {
 	case SET:
-	  process_set (asm_out_file, pat);
+	  process_set (asm_out_file, pat, insn, unwind, frame);
 	  break;
 
 	case PARALLEL:
@@ -8248,7 +8338,7 @@ process_for_unwind_directive (FILE *asm_
 	      {
 		rtx x = XVECEXP (pat, 0, par_index);
 		if (GET_CODE (x) == SET)
-		  process_set (asm_out_file, x);
+		  process_set (asm_out_file, x, insn, unwind, frame);
 	      }
 	    break;
 	  }
Index: gcc/config/ia64/ia64.h
===================================================================
--- gcc/config/ia64/ia64.h.orig	2006-02-03 03:09:18.000000000 -0200
+++ gcc/config/ia64/ia64.h	2006-02-03 04:18:50.000000000 -0200
@@ -981,6 +981,12 @@ enum reg_class
    On some machines it may depend on the data type of the function.  */
 #define FIRST_PARM_OFFSET(FUNDECL) 0
 
+/* The CFA is defined as the SP at the call site, so we have to take
+   into account that the first argument pointer is
+   STACK_POINTER_OFFSET bytes off the stack pointer.  */
+#define ARG_POINTER_CFA_OFFSET(FNDECL) \
+  (FIRST_PARM_OFFSET (FNDECL) - STACK_POINTER_OFFSET)
+
 /* A C expression whose value is RTL representing the value of the return
    address for the frame COUNT steps up from the current frame, after the
    prologue.  */
@@ -1867,6 +1873,12 @@ do {									\
 
 #define DWARF2_DEBUGGING_INFO 1
 
+/* We do not want call-frame info to be output, since debuggers are
+   supposed to use the target unwind info.  Leave this undefined it
+   TARGET_UNWIND_INFO might ever be false.  */
+
+#define DWARF2_FRAME_INFO 0
+
 #define DWARF2_ASM_LINE_DEBUG_INFO (TARGET_DWARF2_ASM)
 
 /* Use tags for debug info labels, so that they don't break instruction
Index: gcc/config/ia64/t-ia64
===================================================================
--- gcc/config/ia64/t-ia64.orig	2006-02-03 03:09:18.000000000 -0200
+++ gcc/config/ia64/t-ia64	2006-02-03 04:18:50.000000000 -0200
@@ -50,3 +50,5 @@ ia64-c.o: $(srcdir)/config/ia64/ia64-c.c
 
 # genattrtab generates very long string literals.
 insn-attrtab.o-warn = -Wno-error
+
+ia64.o: debug.h
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c.orig	2006-01-25 15:04:42.000000000 -0200
+++ gcc/dwarf2out.c	2006-02-03 05:41:57.000000000 -0200
@@ -90,20 +90,31 @@ static void dwarf2out_source_line (unsig
    DW_CFA_... = DWARF2 CFA call frame instruction
    DW_TAG_... = DWARF2 DIE tag */
 
+#ifndef DWARF2_FRAME_INFO
+# ifdef DWARF2_DEBUGGING_INFO
+#  define DWARF2_FRAME_INFO \
+  (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG)
+# else
+#  define DWARF2_FRAME_INFO 0
+# endif
+#endif
+
 /* Decide whether we want to emit frame unwind information for the current
    translation unit.  */
 
 int
 dwarf2out_do_frame (void)
 {
+  /* We want to emit correct CFA location expressions or lists, so we
+     have to return true if we're going to output debug info, even if
+     we're not going to output frame or unwind info.  */
   return (write_symbols == DWARF2_DEBUG
 	  || write_symbols == VMS_AND_DWARF2_DEBUG
-#ifdef DWARF2_FRAME_INFO
 	  || DWARF2_FRAME_INFO
-#endif
 #ifdef DWARF2_UNWIND_INFO
-	  || flag_unwind_tables
-	  || (flag_exceptions && ! USING_SJLJ_EXCEPTIONS)
+	  || (DWARF2_UNWIND_INFO
+	      && (flag_unwind_tables
+		  || (flag_exceptions && ! USING_SJLJ_EXCEPTIONS)))
 #endif
 	  );
 }
@@ -2575,10 +2586,12 @@ dwarf2out_frame_init (void)
   /* Generate the CFA instructions common to all FDE's.  Do it now for the
      sake of lookup_cfa.  */
 
-#ifdef DWARF2_UNWIND_INFO
   /* On entry, the Canonical Frame Address is at SP.  */
   dwarf2out_def_cfa (NULL, STACK_POINTER_REGNUM, INCOMING_FRAME_SP_OFFSET);
-  initial_return_save (INCOMING_RETURN_ADDR_RTX);
+
+#ifdef DWARF2_UNWIND_INFO
+  if (DWARF2_UNWIND_INFO)
+    initial_return_save (INCOMING_RETURN_ADDR_RTX);
 #endif
 }
 
@@ -2586,12 +2599,7 @@ void
 dwarf2out_frame_finish (void)
 {
   /* Output call frame information.  */
-  if (write_symbols == DWARF2_DEBUG
-      || write_symbols == VMS_AND_DWARF2_DEBUG
-#ifdef DWARF2_FRAME_INFO
-      || DWARF2_FRAME_INFO
-#endif
-      )
+  if (DWARF2_FRAME_INFO)
     output_call_frame_info (0);
 
 #ifndef TARGET_UNWIND_INFO
@@ -10332,7 +10340,6 @@ tree_add_const_value_attribute (dw_die_r
     add_const_value_attribute (var_die, rtl);
 }
 
-#ifdef DWARF2_UNWIND_INFO
 /* Convert the CFI instructions for the current function into a location
    list.  This is used for DW_AT_frame_base when we targeting a dwarf2
    consumer that does not support the dwarf3 DW_OP_call_frame_cfa.  */
@@ -10439,7 +10446,6 @@ compute_frame_pointer_to_cfa_displacemen
 
   frame_pointer_cfa_offset = -offset;
 }
-#endif
 
 /* Generate a DW_AT_name attribute given some string value to be included as
    the value of the attribute.  */
@@ -11674,7 +11680,6 @@ gen_subprogram_die (tree decl, dw_die_re
       add_AT_fde_ref (subr_die, DW_AT_MIPS_fde, current_funcdef_fde);
 #endif
 
-#ifdef DWARF2_UNWIND_INFO
       /* We define the "frame base" as the function's CFA.  This is more
 	 convenient for several reasons: (1) It's stable across the prologue
 	 and epilogue, which makes it better than just a frame pointer,
@@ -11701,17 +11706,6 @@ gen_subprogram_die (tree decl, dw_die_re
 	 debugger about.  We'll need to adjust all frame_base references
 	 by this displacement.  */
       compute_frame_pointer_to_cfa_displacement ();
-#else
-      /* For targets which support DWARF2, but not DWARF2 call-frame info,
-	 we just use the stack pointer or frame pointer.  */
-      /* ??? Should investigate getting better info via callbacks, or else
-	 by interpreting the IA-64 unwind info.  */
-      {
-	rtx fp_reg
-	  = frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx;
-	add_AT_loc (subr_die, DW_AT_frame_base, reg_loc_descriptor (fp_reg));
-      }
-#endif
 
       if (cfun->static_chain_decl)
 	add_AT_location_description (subr_die, DW_AT_static_link,
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c.orig	2006-01-26 16:20:39.000000000 -0200
+++ gcc/toplev.c	2006-02-03 04:18:51.000000000 -0200
@@ -1020,7 +1020,7 @@ compile_file (void)
   /* Do dbx symbols.  */
   timevar_push (TV_SYMOUT);
 
-#ifdef DWARF2_UNWIND_INFO
+#if defined DWARF2_DEBUGGING_INFO || defined DWARF2_UNWIND_INFO
   if (dwarf2out_do_frame ())
     dwarf2out_frame_finish ();
 #endif
@@ -1860,7 +1860,7 @@ lang_dependent_init (const char *name)
      predefined types.  */
   timevar_push (TV_SYMOUT);
 
-#ifdef DWARF2_UNWIND_INFO
+#if defined DWARF2_DEBUGGING_INFO || defined DWARF2_UNWIND_INFO
   if (dwarf2out_do_frame ())
     dwarf2out_frame_init ();
 #endif
-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
Secretary for FSF Latin America        http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

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