Blame SOURCES/gcc34-dwarf2-frame_base.patch

6693b3
2005-08-22  Richard Henderson  <rth@redhat.com>
6693b3
6693b3
	* function.c (ARG_POINTER_CFA_OFFSET): Move ...
6693b3
	* defaults.h (ARG_POINTER_CFA_OFFSET): ... here.
6693b3
	(INCOMING_FRAME_SP_OFFSET): Moved from ...
6693b3
	* dwarf2out.c (INCOMING_FRAME_SP_OFFSET): ... here.
6693b3
	(struct cfa_loc): Change reg to unsigned int,
6693b3
	rearrange for better packing.
6693b3
	(lookup_cfa_1): Remove inline marker.
6693b3
	(cfa_equal_p): Split out of ...
6693b3
	(def_cfa_1): ... here.  Use INVALID_REGNUM.
6693b3
	(build_cfa_loc): Handle !cfa->indirect.
6693b3
	(frame_pointer_cfa_offset): New.
6693b3
	(dbx_reg_number): Assert register elimination performed; do
6693b3
	leaf register remapping.
6693b3
	(reg_loc_descriptor): Avoid calling dbx_reg_number when unused.
6693b3
	(eliminate_reg_to_offset): New.
6693b3
	(based_loc_descr): Remove can_use_fbreg argument.  Use fbreg only
6693b3
	for verifiably local stack frame addresses; re-base to CFA.
6693b3
	(mem_loc_descriptor): Remove can_use_fbreg argument.
6693b3
	(concat_loc_descriptor, loc_descriptor): Likewise.
6693b3
	(containing_function_has_frame_base): Remove.
6693b3
	(rtl_for_decl_location): Don't do register elimination or
6693b3
	leaf register remapping here.
6693b3
	(secname_for_decl): Split out from ..
6693b3
	(add_location_or_const_value_attribute): ... here.
6693b3
	(convert_cfa_to_loc_list): New.
6693b3
	(compute_frame_pointer_to_cfa_displacement): New.
6693b3
	(gen_subprogram_die): Use them.
6693b3
	* tree.h (frame_base_decl): Remove.
6693b3
	* var-tracking.c (frame_base_decl, frame_stack_adjust): Remove.
6693b3
	(prologue_stack_adjust): Remove.
6693b3
	(vt_stack_adjustments): Use INCOMING_FRAME_SP_OFFSET.
6693b3
	(adjust_stack_reference): Re-base memories to arg_pointer_rtx.
6693b3
	(set_frame_base_location): Remove.
6693b3
	(compute_bb_dataflow, emit_notes_in_bb): Don't call it.
6693b3
	(dump_attrs_list, dump_dataflow_set): Use string concatenation.
6693b3
	(vt_add_function_parameters): Don't eliminate_regs.
6693b3
	(vt_initialize): Don't create frame_base_decl.
6693b3
6693b3
--- gcc/defaults.h.orig	2005-11-17 23:01:55.000000000 -0200
6693b3
+++ gcc/defaults.h	2005-11-17 23:07:55.000000000 -0200
6693b3
@@ -715,4 +715,15 @@
6693b3
 #define EXIT_IGNORE_STACK 0
6693b3
 #endif
6693b3
 
6693b3
+/* On most machines, the CFA coincides with the first incoming parm.  */
6693b3
+#ifndef ARG_POINTER_CFA_OFFSET
6693b3
+#define ARG_POINTER_CFA_OFFSET(FNDECL) FIRST_PARM_OFFSET (FNDECL)
6693b3
+#endif
6693b3
+
6693b3
+/* The offset from the incoming value of %sp to the top of the stack frame
6693b3
+   for the current function.  */
6693b3
+#ifndef INCOMING_FRAME_SP_OFFSET
6693b3
+#define INCOMING_FRAME_SP_OFFSET 0
6693b3
+#endif
6693b3
+
6693b3
 #endif  /* ! GCC_DEFAULTS_H */
6693b3
--- gcc/dwarf2out.c.orig	2005-11-17 23:07:20.000000000 -0200
6693b3
+++ gcc/dwarf2out.c	2005-11-17 23:07:55.000000000 -0200
6693b3
@@ -228,9 +228,9 @@ dw_cfi_node;
6693b3
    of this structure.  */
6693b3
 typedef struct cfa_loc GTY(())
6693b3
 {
6693b3
-  unsigned long reg;
6693b3
   HOST_WIDE_INT offset;
6693b3
   HOST_WIDE_INT base_offset;
6693b3
+  unsigned int reg;
6693b3
   int indirect;            /* 1 if CFA is accessed via a dereference.  */
6693b3
 } dw_cfa_location;
6693b3
 
6693b3
@@ -418,12 +418,6 @@ static void def_cfa_1 (const char *, dw_
6693b3
 #ifndef DWARF_FRAME_REGNUM
6693b3
 #define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG)
6693b3
 #endif
6693b3
-
6693b3
-/* The offset from the incoming value of %sp to the top of the stack frame
6693b3
-   for the current function.  */
6693b3
-#ifndef INCOMING_FRAME_SP_OFFSET
6693b3
-#define INCOMING_FRAME_SP_OFFSET 0
6693b3
-#endif
6693b3
 
6693b3
 /* Hook used by __throw.  */
6693b3
 
6693b3
@@ -651,7 +645,7 @@ add_fde_cfi (const char *label, dw_cfi_r
6693b3
 
6693b3
 /* Subroutine of lookup_cfa.  */
6693b3
 
6693b3
-static inline void
6693b3
+static void
6693b3
 lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc)
6693b3
 {
6693b3
   switch (cfi->dw_cfi_opc)
6693b3
@@ -681,7 +675,7 @@ lookup_cfa (dw_cfa_location *loc)
6693b3
 {
6693b3
   dw_cfi_ref cfi;
6693b3
 
6693b3
-  loc->reg = (unsigned long) -1;
6693b3
+  loc->reg = INVALID_REGNUM;
6693b3
   loc->offset = 0;
6693b3
   loc->indirect = 0;
6693b3
   loc->base_offset = 0;
6693b3
@@ -725,6 +719,18 @@ dwarf2out_def_cfa (const char *label, un
6693b3
   def_cfa_1 (label, &loc;;
6693b3
 }
6693b3
 
6693b3
+/* Determine if two dw_cfa_location structures define the same data.  */
6693b3
+
6693b3
+static bool
6693b3
+cfa_equal_p (const dw_cfa_location *loc1, const dw_cfa_location *loc2)
6693b3
+{
6693b3
+  return (loc1->reg == loc2->reg
6693b3
+	  && loc1->offset == loc2->offset
6693b3
+	  && loc1->indirect == loc2->indirect
6693b3
+	  && (loc1->indirect == 0
6693b3
+	      || loc1->base_offset == loc2->base_offset));
6693b3
+}
6693b3
+
6693b3
 /* This routine does the actual work.  The CFA is now calculated from
6693b3
    the dw_cfa_location structure.  */
6693b3
 
6693b3
@@ -744,9 +750,7 @@ def_cfa_1 (const char *label, dw_cfa_loc
6693b3
   lookup_cfa (&old_cfa);
6693b3
 
6693b3
   /* If nothing changed, no need to issue any call frame instructions.  */
6693b3
-  if (loc.reg == old_cfa.reg && loc.offset == old_cfa.offset
6693b3
-      && loc.indirect == old_cfa.indirect
6693b3
-      && (loc.indirect == 0 || loc.base_offset == old_cfa.base_offset))
6693b3
+  if (cfa_equal_p (&loc, &old_cfa))
6693b3
     return;
6693b3
 
6693b3
   cfi = new_cfi ();
6693b3
@@ -761,7 +765,8 @@ def_cfa_1 (const char *label, dw_cfa_loc
6693b3
     }
6693b3
 
6693b3
 #ifndef MIPS_DEBUGGING_INFO  /* SGI dbx thinks this means no offset.  */
6693b3
-  else if (loc.offset == old_cfa.offset && old_cfa.reg != (unsigned long) -1
6693b3
+  else if (loc.offset == old_cfa.offset
6693b3
+	   && old_cfa.reg != INVALID_REGNUM
6693b3
 	   && !loc.indirect)
6693b3
     {
6693b3
       /* Construct a "DW_CFA_def_cfa_register <register>" instruction,
6693b3
@@ -3098,28 +3103,40 @@ build_cfa_loc (dw_cfa_location *cfa)
6693b3
 {
6693b3
   struct dw_loc_descr_struct *head, *tmp;
6693b3
 
6693b3
-  if (cfa->indirect == 0)
6693b3
-    abort ();
6693b3
-
6693b3
-  if (cfa->base_offset)
6693b3
+  if (cfa->indirect)
6693b3
     {
6693b3
-      if (cfa->reg <= 31)
6693b3
-	head = new_loc_descr (DW_OP_breg0 + cfa->reg, cfa->base_offset, 0);
6693b3
+      if (cfa->base_offset)
6693b3
+	{
6693b3
+	  if (cfa->reg <= 31)
6693b3
+	    head = new_loc_descr (DW_OP_breg0 + cfa->reg, cfa->base_offset, 0);
6693b3
+	  else
6693b3
+	    head = new_loc_descr (DW_OP_bregx, cfa->reg, cfa->base_offset);
6693b3
+	}
6693b3
+      else if (cfa->reg <= 31)
6693b3
+	head = new_loc_descr (DW_OP_reg0 + cfa->reg, 0, 0);
6693b3
       else
6693b3
-	head = new_loc_descr (DW_OP_bregx, cfa->reg, cfa->base_offset);
6693b3
+	head = new_loc_descr (DW_OP_regx, cfa->reg, 0);
6693b3
+
6693b3
+      head->dw_loc_oprnd1.val_class = dw_val_class_const;
6693b3
+      tmp = new_loc_descr (DW_OP_deref, 0, 0);
6693b3
+      add_loc_descr (&head, tmp);
6693b3
+      if (cfa->offset != 0)
6693b3
+	{
6693b3
+	  tmp = new_loc_descr (DW_OP_plus_uconst, cfa->offset, 0);
6693b3
+	  add_loc_descr (&head, tmp);
6693b3
+	}
6693b3
     }
6693b3
-  else if (cfa->reg <= 31)
6693b3
-    head = new_loc_descr (DW_OP_reg0 + cfa->reg, 0, 0);
6693b3
   else
6693b3
-    head = new_loc_descr (DW_OP_regx, cfa->reg, 0);
6693b3
-
6693b3
-  head->dw_loc_oprnd1.val_class = dw_val_class_const;
6693b3
-  tmp = new_loc_descr (DW_OP_deref, 0, 0);
6693b3
-  add_loc_descr (&head, tmp);
6693b3
-  if (cfa->offset != 0)
6693b3
     {
6693b3
-      tmp = new_loc_descr (DW_OP_plus_uconst, cfa->offset, 0);
6693b3
-      add_loc_descr (&head, tmp);
6693b3
+      if (cfa->offset == 0)
6693b3
+	if (cfa->reg <= 31)
6693b3
+	  head = new_loc_descr (DW_OP_reg0 + cfa->reg, 0, 0);
6693b3
+	else
6693b3
+	  head = new_loc_descr (DW_OP_regx, cfa->reg, 0);
6693b3
+      else if (cfa->reg <= 31)
6693b3
+	head = new_loc_descr (DW_OP_breg0 + cfa->reg, cfa->offset, 0);
6693b3
+      else
6693b3
+	head = new_loc_descr (DW_OP_bregx, cfa->reg, cfa->offset);
6693b3
     }
6693b3
 
6693b3
   return head;
6693b3
@@ -3607,6 +3624,10 @@ static GTY(()) int label_num;
6693b3
 
6693b3
 #ifdef DWARF2_DEBUGGING_INFO
6693b3
 
6693b3
+/* Offset from the "steady-state frame pointer" to the CFA,
6693b3
+   within the current function.  */
6693b3
+static HOST_WIDE_INT frame_pointer_cfa_offset;
6693b3
+
6693b3
 /* Forward declarations for functions defined in this file.  */
6693b3
 
6693b3
 static int is_pseudo_reg (rtx);
6693b3
@@ -3752,11 +3773,11 @@ static dw_loc_descr_ref reg_loc_descript
6693b3
 static dw_loc_descr_ref one_reg_loc_descriptor (unsigned int);
6693b3
 static dw_loc_descr_ref multiple_reg_loc_descriptor (rtx, rtx);
6693b3
 static dw_loc_descr_ref int_loc_descriptor (HOST_WIDE_INT);
6693b3
-static dw_loc_descr_ref based_loc_descr (unsigned, HOST_WIDE_INT, bool);
6693b3
+static dw_loc_descr_ref based_loc_descr (rtx, HOST_WIDE_INT);
6693b3
 static int is_based_loc (rtx);
6693b3
-static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode, bool);
6693b3
-static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx, bool);
6693b3
-static dw_loc_descr_ref loc_descriptor (rtx, bool);
6693b3
+static dw_loc_descr_ref mem_loc_descriptor (rtx, enum machine_mode mode);
6693b3
+static dw_loc_descr_ref concat_loc_descriptor (rtx, rtx);
6693b3
+static dw_loc_descr_ref loc_descriptor (rtx);
6693b3
 static dw_loc_descr_ref loc_descriptor_from_tree (tree, int);
6693b3
 static HOST_WIDE_INT ceiling (HOST_WIDE_INT, unsigned int);
6693b3
 static tree field_type (tree);
6693b3
@@ -8171,9 +8192,20 @@ dbx_reg_number (rtx rtl)
6693b3
 {
6693b3
   unsigned regno = REGNO (rtl);
6693b3
 
6693b3
+  if (! (HARD_FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM
6693b3
+	 || rtl != arg_pointer_rtx))
6693b3
+    abort ();
6693b3
+  if (! (HARD_FRAME_POINTER_REGNUM == FRAME_POINTER_REGNUM
6693b3
+	 || rtl != frame_pointer_rtx))
6693b3
+    abort ();
6693b3
+
6693b3
   if (regno >= FIRST_PSEUDO_REGISTER)
6693b3
     abort ();
6693b3
 
6693b3
+#ifdef LEAF_REG_REMAP
6693b3
+  regno = LEAF_REG_REMAP (regno);
6693b3
+#endif
6693b3
+
6693b3
   return DBX_REGISTER_NUMBER (regno);
6693b3
 }
6693b3
 
6693b3
@@ -8203,20 +8235,17 @@ add_loc_descr_op_piece (dw_loc_descr_ref
6693b3
 static dw_loc_descr_ref
6693b3
 reg_loc_descriptor (rtx rtl)
6693b3
 {
6693b3
-  unsigned reg;
6693b3
   rtx regs;
6693b3
 
6693b3
   if (REGNO (rtl) >= FIRST_PSEUDO_REGISTER)
6693b3
     return 0;
6693b3
 
6693b3
-  reg = dbx_reg_number (rtl);
6693b3
   regs = (*targetm.dwarf_register_span) (rtl);
6693b3
 
6693b3
-  if (HARD_REGNO_NREGS (REGNO (rtl), GET_MODE (rtl)) > 1
6693b3
-      || regs)
6693b3
+  if (HARD_REGNO_NREGS(REGNO (rtl), GET_MODE (rtl)) > 1 || regs)
6693b3
     return multiple_reg_loc_descriptor (rtl, regs);
6693b3
   else
6693b3
-    return one_reg_loc_descriptor (reg);
6693b3
+    return one_reg_loc_descriptor (dbx_reg_number (rtl));
6693b3
 }
6693b3
 
6693b3
 /* Return a location descriptor that designates a machine register for
6693b3
@@ -8321,25 +8350,54 @@ int_loc_descriptor (HOST_WIDE_INT i)
6693b3
   return new_loc_descr (op, i, 0);
6693b3
 }
6693b3
 
6693b3
+/* Return an offset from an eliminable register to the post-prologue
6693b3
+   frame pointer.  */
6693b3
+
6693b3
+static HOST_WIDE_INT
6693b3
+eliminate_reg_to_offset (rtx reg)
6693b3
+{
6693b3
+  HOST_WIDE_INT offset = 0;
6693b3
+
6693b3
+  reg = eliminate_regs (reg, VOIDmode, NULL_RTX);
6693b3
+  if (GET_CODE (reg) == PLUS)
6693b3
+    {
6693b3
+      offset = INTVAL (XEXP (reg, 1));
6693b3
+      reg = XEXP (reg, 0);
6693b3
+    }
6693b3
+  if (! (reg == (frame_pointer_needed ? hard_frame_pointer_rtx
6693b3
+		 : stack_pointer_rtx)))
6693b3
+    abort ();
6693b3
+
6693b3
+  return offset;
6693b3
+}
6693b3
+
6693b3
 /* Return a location descriptor that designates a base+offset location.  */
6693b3
 
6693b3
 static dw_loc_descr_ref
6693b3
-based_loc_descr (unsigned int reg, HOST_WIDE_INT offset, bool can_use_fbreg)
6693b3
+based_loc_descr (rtx reg, HOST_WIDE_INT offset)
6693b3
 {
6693b3
   dw_loc_descr_ref loc_result;
6693b3
-  /* For the "frame base", we use the frame pointer or stack pointer
6693b3
-     registers, since the RTL for local variables is relative to one of
6693b3
-     them.  */
6693b3
-  unsigned fp_reg = DBX_REGISTER_NUMBER (frame_pointer_needed
6693b3
-					 ? HARD_FRAME_POINTER_REGNUM
6693b3
-					 : STACK_POINTER_REGNUM);
6693b3
-
6693b3
-  if (reg == fp_reg && can_use_fbreg)
6693b3
-    loc_result = new_loc_descr (DW_OP_fbreg, offset, 0);
6693b3
-  else if (reg <= 31)
6693b3
-    loc_result = new_loc_descr (DW_OP_breg0 + reg, offset, 0);
6693b3
+
6693b3
+  /* We only use "frame base" when we're sure we're talking about the
6693b3
+     post-prologue local stack frame.  We do this by *not* running
6693b3
+     register elimination until this point, and recognizing the special
6693b3
+     argument pointer and soft frame pointer rtx's.  */
6693b3
+  if (reg == arg_pointer_rtx || reg == frame_pointer_rtx)
6693b3
+    {
6693b3
+      offset += eliminate_reg_to_offset (reg);
6693b3
+      offset += frame_pointer_cfa_offset;
6693b3
+
6693b3
+      loc_result = new_loc_descr (DW_OP_fbreg, offset, 0);
6693b3
+    }
6693b3
   else
6693b3
-    loc_result = new_loc_descr (DW_OP_bregx, reg, offset);
6693b3
+    {
6693b3
+      unsigned int regno = dbx_reg_number (reg);
6693b3
+
6693b3
+      if (regno <= 31)
6693b3
+	loc_result = new_loc_descr (DW_OP_breg0 + regno, offset, 0);
6693b3
+      else
6693b3
+	loc_result = new_loc_descr (DW_OP_bregx, regno, offset);
6693b3
+    }
6693b3
 
6693b3
   return loc_result;
6693b3
 }
6693b3
@@ -8368,15 +8426,13 @@ is_based_loc (rtx rtl)
6693b3
    MODE is the mode of the memory reference, needed to handle some
6693b3
    autoincrement addressing modes.
6693b3
 
6693b3
-   CAN_USE_FBREG is a flag whether we can use DW_AT_frame_base in the location
6693b3
-   list for RTL. We can't use it when we are emitting location list for
6693b3
-   virtual variable frame_base_decl (i.e. a location list for DW_AT_frame_base)
6693b3
-   which describes how frame base changes when !frame_pointer_needed.
6693b3
+   CAN_USE_FBREG is a flag whether we can use DW_AT_frame_base in the
6693b3
+   location list for RTL.
6693b3
 
6693b3
    Return 0 if we can't represent the location.  */
6693b3
 
6693b3
 static dw_loc_descr_ref
6693b3
-mem_loc_descriptor (rtx rtl, enum machine_mode mode, bool can_use_fbreg)
6693b3
+mem_loc_descriptor (rtx rtl, enum machine_mode mode)
6693b3
 {
6693b3
   dw_loc_descr_ref mem_loc_result = NULL;
6693b3
 
6693b3
@@ -8422,13 +8478,11 @@ mem_loc_descriptor (rtx rtl, enum machin
6693b3
 	 memory) so DWARF consumers need to be aware of the subtle
6693b3
 	 distinction between OP_REG and OP_BASEREG.  */
6693b3
       if (REGNO (rtl) < FIRST_PSEUDO_REGISTER)
6693b3
-	mem_loc_result = based_loc_descr (dbx_reg_number (rtl), 0,
6693b3
-					  can_use_fbreg);
6693b3
+	mem_loc_result = based_loc_descr (rtl, 0);
6693b3
       break;
6693b3
 
6693b3
     case MEM:
6693b3
-      mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl),
6693b3
-					   can_use_fbreg);
6693b3
+      mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
6693b3
       if (mem_loc_result != 0)
6693b3
 	add_loc_descr (&mem_loc_result, new_loc_descr (DW_OP_deref, 0, 0));
6693b3
       break;
6693b3
@@ -8494,13 +8548,11 @@ mem_loc_descriptor (rtx rtl, enum machin
6693b3
     case PLUS:
6693b3
     plus:
6693b3
       if (is_based_loc (rtl))
6693b3
-	mem_loc_result = based_loc_descr (dbx_reg_number (XEXP (rtl, 0)),
6693b3
-					  INTVAL (XEXP (rtl, 1)),
6693b3
-					  can_use_fbreg);
6693b3
+	mem_loc_result = based_loc_descr (XEXP (rtl, 0),
6693b3
+					  INTVAL (XEXP (rtl, 1)));
6693b3
       else
6693b3
 	{
6693b3
-	  mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode,
6693b3
-					       can_use_fbreg);
6693b3
+	  mem_loc_result = mem_loc_descriptor (XEXP (rtl, 0), mode);
6693b3
 	  if (mem_loc_result == 0)
6693b3
 	    break;
6693b3
 
6693b3
@@ -8512,8 +8564,7 @@ mem_loc_descriptor (rtx rtl, enum machin
6693b3
 	  else
6693b3
 	    {
6693b3
 	      add_loc_descr (&mem_loc_result,
6693b3
-			     mem_loc_descriptor (XEXP (rtl, 1), mode,
6693b3
-						 can_use_fbreg));
6693b3
+			     mem_loc_descriptor (XEXP (rtl, 1), mode));
6693b3
 	      add_loc_descr (&mem_loc_result,
6693b3
 			     new_loc_descr (DW_OP_plus, 0, 0));
6693b3
 	    }
6693b3
@@ -8524,10 +8575,8 @@ mem_loc_descriptor (rtx rtl, enum machin
6693b3
       {
6693b3
 	/* If a pseudo-reg is optimized away, it is possible for it to
6693b3
 	   be replaced with a MEM containing a multiply.  */
6693b3
-	dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode,
6693b3
-						   can_use_fbreg);
6693b3
-	dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode,
6693b3
-						   can_use_fbreg);
6693b3
+	dw_loc_descr_ref op0 = mem_loc_descriptor (XEXP (rtl, 0), mode);
6693b3
+	dw_loc_descr_ref op1 = mem_loc_descriptor (XEXP (rtl, 1), mode);
6693b3
 
6693b3
 	if (op0 == 0 || op1 == 0)
6693b3
 	  break;
6693b3
@@ -8546,8 +8595,7 @@ mem_loc_descriptor (rtx rtl, enum machin
6693b3
       /* If this is a MEM, return its address.  Otherwise, we can't
6693b3
 	 represent this.  */
6693b3
       if (GET_CODE (XEXP (rtl, 0)) == MEM)
6693b3
-	return mem_loc_descriptor (XEXP (XEXP (rtl, 0), 0), mode,
6693b3
-				   can_use_fbreg);
6693b3
+	return mem_loc_descriptor (XEXP (XEXP (rtl, 0), 0), mode);
6693b3
       else
6693b3
 	return 0;
6693b3
 
6693b3
@@ -8562,11 +8610,11 @@ mem_loc_descriptor (rtx rtl, enum machin
6693b3
    This is typically a complex variable.  */
6693b3
 
6693b3
 static dw_loc_descr_ref
6693b3
-concat_loc_descriptor (rtx x0, rtx x1, bool can_use_fbreg)
6693b3
+concat_loc_descriptor (rtx x0, rtx x1)
6693b3
 {
6693b3
   dw_loc_descr_ref cc_loc_result = NULL;
6693b3
-  dw_loc_descr_ref x0_ref = loc_descriptor (x0, can_use_fbreg);
6693b3
-  dw_loc_descr_ref x1_ref = loc_descriptor (x1, can_use_fbreg);
6693b3
+  dw_loc_descr_ref x0_ref = loc_descriptor (x0);
6693b3
+  dw_loc_descr_ref x1_ref = loc_descriptor (x1);
6693b3
 
6693b3
   if (x0_ref == 0 || x1_ref == 0)
6693b3
     return 0;
6693b3
@@ -8580,29 +8628,6 @@ concat_loc_descriptor (rtx x0, rtx x1, b
6693b3
   return cc_loc_result;
6693b3
 }
6693b3
 
6693b3
-/* Return true if DECL's containing function has a frame base attribute.
6693b3
-   Return false otherwise.  */
6693b3
-
6693b3
-static bool
6693b3
-containing_function_has_frame_base (tree decl)
6693b3
-{
6693b3
-  tree declcontext = decl_function_context (decl);
6693b3
-  dw_die_ref context;
6693b3
-  dw_attr_ref attr;
6693b3
-
6693b3
-  if (!declcontext)
6693b3
-    return false;
6693b3
-
6693b3
-  context = lookup_decl_die (declcontext);
6693b3
-  if (!context)
6693b3
-    return false;
6693b3
-
6693b3
-  for (attr = context->die_attr; attr; attr = attr->dw_attr_next)
6693b3
-    if (attr->dw_attr == DW_AT_frame_base)
6693b3
-      return true;
6693b3
-  return false;
6693b3
-}
6693b3
-
6693b3
 /* Output a proper Dwarf location descriptor for a variable or parameter
6693b3
    which is either allocated in a register or in a memory location.  For a
6693b3
    register, we just generate an OP_REG and the register number.  For a
6693b3
@@ -8612,7 +8637,7 @@ containing_function_has_frame_base (tree
6693b3
    If we don't know how to describe it, return 0.  */
6693b3
 
6693b3
 static dw_loc_descr_ref
6693b3
-loc_descriptor (rtx rtl, bool can_use_fbreg)
6693b3
+loc_descriptor (rtx rtl)
6693b3
 {
6693b3
   dw_loc_descr_ref loc_result = NULL;
6693b3
 
6693b3
@@ -8633,20 +8658,18 @@ loc_descriptor (rtx rtl, bool can_use_fb
6693b3
       break;
6693b3
 
6693b3
     case MEM:
6693b3
-      loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl),
6693b3
-				       can_use_fbreg);
6693b3
+      loc_result = mem_loc_descriptor (XEXP (rtl, 0), GET_MODE (rtl));
6693b3
       break;
6693b3
 
6693b3
     case CONCAT:
6693b3
-      loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1),
6693b3
-					  can_use_fbreg);
6693b3
+      loc_result = concat_loc_descriptor (XEXP (rtl, 0), XEXP (rtl, 1));
6693b3
       break;
6693b3
 
6693b3
     case VAR_LOCATION:
6693b3
       /* Single part.  */
6693b3
       if (GET_CODE (XEXP (rtl, 1)) != PARALLEL)
6693b3
 	{
6693b3
-	  loc_result = loc_descriptor (XEXP (XEXP (rtl, 1), 0), can_use_fbreg);
6693b3
+	  loc_result = loc_descriptor (XEXP (XEXP (rtl, 1), 0));
6693b3
 	}
6693b3
       /* Multiple parts.  */
6693b3
       else
6693b3
@@ -8657,16 +8680,14 @@ loc_descriptor (rtx rtl, bool can_use_fb
6693b3
 	  int i;
6693b3
 
6693b3
 	  /* Create the first one, so we have something to add to.  */
6693b3
-	  loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0),
6693b3
-				       can_use_fbreg);
6693b3
+	  loc_result = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0));
6693b3
 	  mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
6693b3
 	  add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
6693b3
 	  for (i = 1; i < num_elem; i++)
6693b3
 	    {
6693b3
 	      dw_loc_descr_ref temp;
6693b3
 
6693b3
-	      temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0),
6693b3
-				     can_use_fbreg);
6693b3
+	      temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0));
6693b3
 	      add_loc_descr (&loc_result, temp);
6693b3
 	      mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
6693b3
 	      add_loc_descr_op_piece (&loc_result, GET_MODE_SIZE (mode));
6693b3
@@ -8789,7 +8810,6 @@ loc_descriptor_from_tree (tree loc, int 
6693b3
 	else
6693b3
 	  {
6693b3
 	    enum machine_mode mode = GET_MODE (rtl);
6693b3
-	    bool can_use_fb = containing_function_has_frame_base (loc);
6693b3
 
6693b3
 	    if (GET_CODE (rtl) == MEM)
6693b3
 	      {
6693b3
@@ -8797,7 +8817,7 @@ loc_descriptor_from_tree (tree loc, int 
6693b3
 		rtl = XEXP (rtl, 0);
6693b3
 	      }
6693b3
 
6693b3
-	    ret = mem_loc_descriptor (rtl, mode, can_use_fb);
6693b3
+	    ret = mem_loc_descriptor (rtl, mode);
6693b3
 	  }
6693b3
       }
6693b3
       break;
6693b3
@@ -8872,18 +8892,16 @@ loc_descriptor_from_tree (tree loc, int 
6693b3
 	/* Get an RTL for this, if something has been emitted.  */
6693b3
 	rtx rtl = lookup_constant_def (loc);
6693b3
 	enum machine_mode mode;
6693b3
-	bool can_use_fb;
6693b3
 
6693b3
 	if (GET_CODE (rtl) != MEM)
6693b3
 	  return 0;
6693b3
-	can_use_fb = containing_function_has_frame_base (loc);
6693b3
 	mode = GET_MODE (rtl);
6693b3
 	rtl = XEXP (rtl, 0);
6693b3
 
6693b3
 	rtl = (*targetm.delegitimize_address) (rtl);
6693b3
 
6693b3
 	indirect_p = 1;
6693b3
-	ret = mem_loc_descriptor (rtl, mode, can_use_fb);
6693b3
+	ret = mem_loc_descriptor (rtl, mode);
6693b3
 	break;
6693b3
       }
6693b3
 
6693b3
@@ -9743,19 +9761,10 @@ rtl_for_decl_location (tree decl)
6693b3
 	}
6693b3
     }
6693b3
 
6693b3
-  if (rtl != NULL_RTX)
6693b3
-    {
6693b3
-      rtl = eliminate_regs (rtl, 0, NULL_RTX);
6693b3
-#ifdef LEAF_REG_REMAP
6693b3
-      if (current_function_uses_only_leaf_regs)
6693b3
-	leaf_renumber_regs_insn (rtl);
6693b3
-#endif
6693b3
-    }
6693b3
-
6693b3
   /* A variable with no DECL_RTL but a DECL_INITIAL is a compile-time constant,
6693b3
      and will have been substituted directly into all expressions that use it.
6693b3
      C does not have such a concept, but C++ and other languages do.  */
6693b3
-  else if (TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
6693b3
+  if (!rtl && TREE_CODE (decl) == VAR_DECL && DECL_INITIAL (decl))
6693b3
     {
6693b3
       /* If a variable is initialized with a string constant without embedded
6693b3
 	 zeros, build CONST_STRING.  */
6693b3
@@ -9803,6 +9812,34 @@ rtl_for_decl_location (tree decl)
6693b3
   return rtl;
6693b3
 }
6693b3
 
6693b3
+/* We need to figure out what section we should use as the base for the
6693b3
+   address ranges where a given location is valid.
6693b3
+   1. If this particular DECL has a section associated with it, use that.
6693b3
+   2. If this function has a section associated with it, use that.
6693b3
+   3. Otherwise, use the text section.
6693b3
+   XXX: If you split a variable across multiple sections, we won't notice.  */
6693b3
+
6693b3
+static const char *
6693b3
+secname_for_decl (tree decl)
6693b3
+{
6693b3
+  const char *secname;
6693b3
+
6693b3
+  if (DECL_SECTION_NAME (decl))
6693b3
+    {
6693b3
+      tree sectree = DECL_SECTION_NAME (decl);
6693b3
+      secname = TREE_STRING_POINTER (sectree);
6693b3
+    }
6693b3
+  else if (current_function_decl && DECL_SECTION_NAME (current_function_decl))
6693b3
+    {
6693b3
+      tree sectree = DECL_SECTION_NAME (current_function_decl);
6693b3
+      secname = TREE_STRING_POINTER (sectree);
6693b3
+    }
6693b3
+  else
6693b3
+    secname = text_section_label;
6693b3
+
6693b3
+  return secname;
6693b3
+}
6693b3
+
6693b3
 /* Generate *either* a DW_AT_location attribute or else a DW_AT_const_value
6693b3
    data attribute for a variable or a parameter.  We generate the
6693b3
    DW_AT_const_value attribute only in those cases where the given variable
6693b3
@@ -9834,36 +9871,11 @@ add_location_or_const_value_attribute (d
6693b3
      differ.  */
6693b3
   if (loc_list && loc_list->first != loc_list->last)
6693b3
     {
6693b3
-      const char *secname;
6693b3
-      const char *endname;
6693b3
+      const char *secname, *endname;
6693b3
       dw_loc_list_ref list;
6693b3
       rtx varloc;
6693b3
       struct var_loc_node *node;
6693b3
 
6693b3
-      /* We need to figure out what section we should use as the base
6693b3
-	 for the address ranges where a given location is valid.
6693b3
-	 1. If this particular DECL has a section associated with it,
6693b3
-	 use that.
6693b3
-	 2. If this function has a section associated with it, use
6693b3
-	 that.
6693b3
-	 3. Otherwise, use the text section.
6693b3
-	 XXX: If you split a variable across multiple sections, this
6693b3
-	 won't notice.  */
6693b3
-
6693b3
-      if (DECL_SECTION_NAME (decl))
6693b3
-	{
6693b3
-	  tree sectree = DECL_SECTION_NAME (decl);
6693b3
-	  secname = TREE_STRING_POINTER (sectree);
6693b3
-	}
6693b3
-      else if (current_function_decl
6693b3
-	       && DECL_SECTION_NAME (current_function_decl))
6693b3
-	{
6693b3
-	  tree sectree = DECL_SECTION_NAME (current_function_decl);
6693b3
-	  secname = TREE_STRING_POINTER (sectree);
6693b3
-	}
6693b3
-      else
6693b3
-	secname = text_section_label;
6693b3
-
6693b3
       /* Now that we know what section we are using for a base,
6693b3
          actually construct the list of locations.
6693b3
 	 The first location information is what is passed to the
6693b3
@@ -9877,7 +9889,9 @@ add_location_or_const_value_attribute (d
6693b3
 
6693b3
       node = loc_list->first;
6693b3
       varloc = NOTE_VAR_LOCATION (node->var_loc_note);
6693b3
-      list = new_loc_list (loc_descriptor (varloc, attr != DW_AT_frame_base),
6693b3
+      secname = secname_for_decl (decl);
6693b3
+
6693b3
+      list = new_loc_list (loc_descriptor (varloc),
6693b3
 			   node->label, node->next->label, secname, 1);
6693b3
       node = node->next;
6693b3
 
6693b3
@@ -9888,8 +9902,7 @@ add_location_or_const_value_attribute (d
6693b3
 	       NODE->NEXT->LABEL.  */
6693b3
 	    varloc = NOTE_VAR_LOCATION (node->var_loc_note);
6693b3
 	    add_loc_descr_to_loc_list (&list,
6693b3
-				       loc_descriptor (varloc,
6693b3
-						       attr != DW_AT_frame_base),
6693b3
+				       loc_descriptor (varloc),
6693b3
 				       node->label, node->next->label, secname);
6693b3
 	  }
6693b3
 
6693b3
@@ -9909,8 +9922,7 @@ add_location_or_const_value_attribute (d
6693b3
 	      endname = ggc_strdup (label_id);
6693b3
 	    }
6693b3
 	  add_loc_descr_to_loc_list (&list,
6693b3
-				     loc_descriptor (varloc,
6693b3
-						     attr != DW_AT_frame_base),
6693b3
+				     loc_descriptor (varloc),
6693b3
 				     node->label, endname, secname);
6693b3
 	}
6693b3
 
6693b3
@@ -9964,7 +9976,7 @@ add_location_or_const_value_attribute (d
6693b3
 	case REG:
6693b3
 	case SUBREG:
6693b3
 	case CONCAT:
6693b3
-	  descr = loc_descriptor (rtl, true);
6693b3
+	  descr = loc_descriptor (rtl);
6693b3
 	}
6693b3
       add_AT_location_description (die, attr, descr);
6693b3
       break;
6693b3
@@ -9977,14 +9989,14 @@ add_location_or_const_value_attribute (d
6693b3
 	int i;
6693b3
 
6693b3
 	/* Create the first one, so we have something to add to.  */
6693b3
-	descr = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0), true);
6693b3
+	descr = loc_descriptor (XEXP (RTVEC_ELT (par_elems, 0), 0));
6693b3
 	mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, 0), 0));
6693b3
 	add_loc_descr_op_piece (&descr, GET_MODE_SIZE (mode));
6693b3
 	for (i = 1; i < num_elem; i++)
6693b3
 	  {
6693b3
 	    dw_loc_descr_ref temp;
6693b3
 
6693b3
-	    temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0), true);
6693b3
+	    temp = loc_descriptor (XEXP (RTVEC_ELT (par_elems, i), 0));
6693b3
 	    add_loc_descr (&descr, temp);
6693b3
 	    mode = GET_MODE (XEXP (RTVEC_ELT (par_elems, i), 0));
6693b3
 	    add_loc_descr_op_piece (&descr, GET_MODE_SIZE (mode));
6693b3
@@ -10030,6 +10042,98 @@ tree_add_const_value_attribute (dw_die_r
6693b3
     }
6693b3
 }
6693b3
 
6693b3
+/* Convert the CFI instructions for the current function into a location
6693b3
+   list.  This is used for DW_AT_frame_base when we targeting a dwarf2
6693b3
+   consumer that does not support the dwarf3 DW_OP_call_frame_cfa.  */
6693b3
+
6693b3
+static dw_loc_list_ref
6693b3
+convert_cfa_to_loc_list (void)
6693b3
+{
6693b3
+  dw_fde_ref fde;
6693b3
+  dw_loc_list_ref list, *list_tail;
6693b3
+  dw_cfi_ref cfi;
6693b3
+  dw_cfa_location last_cfa, next_cfa;
6693b3
+  const char *start_label, *last_label, *section;
6693b3
+
6693b3
+  fde = &fde_table[fde_table_in_use - 1];
6693b3
+
6693b3
+  section = secname_for_decl (current_function_decl);
6693b3
+  list_tail = &list;
6693b3
+  list = NULL;
6693b3
+
6693b3
+  next_cfa.reg = INVALID_REGNUM;
6693b3
+  next_cfa.offset = 0;
6693b3
+  next_cfa.indirect = 0;
6693b3
+  next_cfa.base_offset = 0;
6693b3
+
6693b3
+  start_label = fde->dw_fde_begin;
6693b3
+
6693b3
+  /* ??? Bald assumption that the CIE opcode list does not contain
6693b3
+     advance opcodes.  */
6693b3
+  for (cfi = cie_cfi_head; cfi; cfi = cfi->dw_cfi_next)
6693b3
+    lookup_cfa_1 (cfi, &next_cfa);
6693b3
+
6693b3
+  last_cfa = next_cfa;
6693b3
+  last_label = start_label;
6693b3
+
6693b3
+  for (cfi = fde->dw_fde_cfi; cfi; cfi = cfi->dw_cfi_next)
6693b3
+    switch (cfi->dw_cfi_opc)
6693b3
+      {
6693b3
+      case DW_CFA_advance_loc1:
6693b3
+      case DW_CFA_advance_loc2:
6693b3
+      case DW_CFA_advance_loc4:
6693b3
+	if (!cfa_equal_p (&last_cfa, &next_cfa))
6693b3
+	  {
6693b3
+	    *list_tail = new_loc_list (build_cfa_loc (&last_cfa), start_label,
6693b3
+				       last_label, section, list == NULL);
6693b3
+
6693b3
+	    list_tail = &(*list_tail)->dw_loc_next;
6693b3
+	    last_cfa = next_cfa;
6693b3
+	    start_label = last_label;
6693b3
+	  }
6693b3
+	last_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
6693b3
+	break;
6693b3
+
6693b3
+      case DW_CFA_advance_loc:
6693b3
+	/* The encoding is complex enough that we should never emit this.  */
6693b3
+      case DW_CFA_remember_state:
6693b3
+      case DW_CFA_restore_state:
6693b3
+	/* We don't handle these two in this function.  It would be possible
6693b3
+	   if it were to be required.  */
6693b3
+	abort ();
6693b3
+
6693b3
+      default:
6693b3
+	lookup_cfa_1 (cfi, &next_cfa);
6693b3
+	break;
6693b3
+      }
6693b3
+
6693b3
+  if (!cfa_equal_p (&last_cfa, &next_cfa))
6693b3
+    {
6693b3
+      *list_tail = new_loc_list (build_cfa_loc (&last_cfa), start_label,
6693b3
+				 last_label, section, list == NULL);
6693b3
+      list_tail = &(*list_tail)->dw_loc_next;
6693b3
+      start_label = last_label;
6693b3
+    }
6693b3
+  *list_tail = new_loc_list (build_cfa_loc (&next_cfa), start_label,
6693b3
+			     fde->dw_fde_end, section, list == NULL);
6693b3
+
6693b3
+  return list;
6693b3
+}
6693b3
+
6693b3
+/* Compute a displacement from the "steady-state frame pointer" to
6693b3
+   the CFA, and store it in frame_pointer_cfa_offset.  */
6693b3
+
6693b3
+static void
6693b3
+compute_frame_pointer_to_cfa_displacement (void)
6693b3
+{
6693b3
+  HOST_WIDE_INT offset;
6693b3
+
6693b3
+  offset = eliminate_reg_to_offset (arg_pointer_rtx);
6693b3
+  offset += ARG_POINTER_CFA_OFFSET (current_function_decl);
6693b3
+
6693b3
+  frame_pointer_cfa_offset = -offset;
6693b3
+}
6693b3
+
6693b3
 /* Generate a DW_AT_name attribute given some string value to be included as
6693b3
    the value of the attribute.  */
6693b3
 
6693b3
@@ -10128,7 +10232,7 @@ add_bound_info (dw_die_ref subrange_die,
6693b3
 	  add_AT_flag (decl_die, DW_AT_artificial, 1);
6693b3
 	  add_type_attribute (decl_die, TREE_TYPE (bound), 1, 0, ctx);
6693b3
 	  add_AT_location_description (decl_die, DW_AT_location,
6693b3
-				       loc_descriptor (loc, true));
6693b3
+				       loc_descriptor (loc));
6693b3
 	  add_AT_die_ref (subrange_die, bound_attr, decl_die);
6693b3
 	}
6693b3
 
6693b3
@@ -11114,7 +11218,6 @@ gen_subprogram_die (tree decl, dw_die_re
6693b3
   char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
6693b3
   tree origin = decl_ultimate_origin (decl);
6693b3
   dw_die_ref subr_die;
6693b3
-  rtx fp_reg;
6693b3
   tree fn_arg_types;
6693b3
   tree outer_scope;
6693b3
   dw_die_ref old_die = lookup_decl_die (decl);
6693b3
@@ -11277,20 +11380,32 @@ gen_subprogram_die (tree decl, dw_die_re
6693b3
       add_AT_fde_ref (subr_die, DW_AT_MIPS_fde, current_funcdef_fde);
6693b3
 #endif
6693b3
 
6693b3
-      /* Define the "frame base" location for this routine.  We use the
6693b3
-	 frame pointer or stack pointer registers, since the RTL for local
6693b3
-	 variables is relative to one of them.  */
6693b3
-      if (frame_base_decl && lookup_decl_loc (frame_base_decl) != NULL)
6693b3
-	{
6693b3
-	  add_location_or_const_value_attribute (subr_die, frame_base_decl,
6693b3
-						 DW_AT_frame_base);
6693b3
-	}
6693b3
-      else
6693b3
-	{
6693b3
-	  fp_reg
6693b3
-	    = frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx;
6693b3
-	  add_AT_loc (subr_die, DW_AT_frame_base, reg_loc_descriptor (fp_reg));
6693b3
-	}
6693b3
+      /* We define the "frame base" as the function's CFA.  This is more
6693b3
+	 convenient for several reasons: (1) It's stable across the prologue
6693b3
+	 and epilogue, which makes it better than just a frame pointer,
6693b3
+	 (2) With dwarf3, there exists a one-byte encoding that allows us
6693b3
+	 to reference the .debug_frame data by proxy, but failing that,
6693b3
+	 (3) We can at least reuse the code inspection and interpretation
6693b3
+	 code that determines the CFA position at various points in the
6693b3
+	 function.  */
6693b3
+      /* ??? Use some command-line or configury switch to enable the use
6693b3
+	 of dwarf3 DW_OP_call_frame_cfa.  At present there are no dwarf
6693b3
+	 consumers that understand it; fall back to "pure" dwarf2 and
6693b3
+	 convert the CFA data into a location list.  */
6693b3
+      {
6693b3
+	dw_loc_list_ref list = convert_cfa_to_loc_list ();
6693b3
+	if (list->dw_loc_next)
6693b3
+	  add_AT_loc_list (subr_die, DW_AT_frame_base, list);
6693b3
+	else
6693b3
+	  add_AT_loc (subr_die, DW_AT_frame_base, list->expr);
6693b3
+      }
6693b3
+
6693b3
+      /* Compute a displacement from the "steady-state frame pointer" to
6693b3
+	 the CFA.  The former is what all stack slots and argument slots
6693b3
+	 will reference in the rtl; the later is what we've told the
6693b3
+	 debugger about.  We'll need to adjust all frame_base references
6693b3
+	 by this displacement.  */
6693b3
+      compute_frame_pointer_to_cfa_displacement ();
6693b3
 
6693b3
 #if 0
6693b3
       /* ??? This fails for nested inline functions, because context_display
6693b3
--- gcc/function.c.orig	2005-11-17 23:01:55.000000000 -0200
6693b3
+++ gcc/function.c	2005-11-17 23:07:55.000000000 -0200
6693b3
@@ -2824,12 +2824,6 @@
6693b3
 #endif
6693b3
 #endif
6693b3
 
6693b3
-/* On most machines, the CFA coincides with the first incoming parm.  */
6693b3
-
6693b3
-#ifndef ARG_POINTER_CFA_OFFSET
6693b3
-#define ARG_POINTER_CFA_OFFSET(FNDECL) FIRST_PARM_OFFSET (FNDECL)
6693b3
-#endif
6693b3
-
6693b3
 /* Build up a (MEM (ADDRESSOF (REG))) rtx for a register REG that just
6693b3
    had its address taken.  DECL is the decl or SAVE_EXPR for the
6693b3
    object stored in the register, for later use if we do need to force
6693b3
--- gcc/tree.h.orig	2005-11-17 23:06:26.000000000 -0200
6693b3
+++ gcc/tree.h	2005-11-17 23:07:55.000000000 -0200
6693b3
@@ -2065,7 +2065,6 @@
6693b3
 
6693b3
 #define NULL_TREE (tree) NULL
6693b3
 
6693b3
-extern GTY(()) tree frame_base_decl;
6693b3
 extern tree decl_assembler_name (tree);
6693b3
 
6693b3
 /* Compute the number of bytes occupied by 'node'.  This routine only
6693b3
--- gcc/var-tracking.c.orig	2005-11-17 23:01:55.000000000 -0200
6693b3
+++ gcc/var-tracking.c	2005-11-17 23:07:55.000000000 -0200
6693b3
@@ -266,19 +266,12 @@
6693b3
 /* Shall notes be emitted?  */
6693b3
 static bool emit_notes;
6693b3
 
6693b3
-/* Fake variable for stack pointer.  */
6693b3
-tree frame_base_decl;
6693b3
-
6693b3
-/* Stack adjust caused by function prologue.  */
6693b3
-static HOST_WIDE_INT frame_stack_adjust;
6693b3
-
6693b3
 /* Local function prototypes.  */
6693b3
 static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
6693b3
 					  HOST_WIDE_INT *);
6693b3
 static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
6693b3
 					       HOST_WIDE_INT *);
6693b3
 static void bb_stack_adjust_offset (basic_block);
6693b3
-static HOST_WIDE_INT prologue_stack_adjust (void);
6693b3
 static bool vt_stack_adjustments (void);
6693b3
 static rtx adjust_stack_reference (rtx, HOST_WIDE_INT);
6693b3
 static hashval_t variable_htab_hash (const void *);
6693b3
@@ -333,7 +326,6 @@
6693b3
 static void dump_dataflow_sets (void);
6693b3
 
6693b3
 static void variable_was_changed (variable, htab_t);
6693b3
-static void set_frame_base_location (dataflow_set *, rtx);
6693b3
 static void set_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
6693b3
 static void delete_variable_part (dataflow_set *, rtx, tree, HOST_WIDE_INT);
6693b3
 static int emit_note_insn_var_location (void **, void *);
6693b3
@@ -489,38 +481,6 @@
6693b3
   VTI (bb)->out.stack_adjust = offset;
6693b3
 }
6693b3
 
6693b3
-/* Compute stack adjustment caused by function prologue.  */
6693b3
-
6693b3
-static HOST_WIDE_INT
6693b3
-prologue_stack_adjust (void)
6693b3
-{
6693b3
-  HOST_WIDE_INT offset = 0;
6693b3
-  basic_block bb = ENTRY_BLOCK_PTR->next_bb;
6693b3
-  rtx insn;
6693b3
-  rtx end;
6693b3
-
6693b3
-  if (!BB_END (bb))
6693b3
-    return 0;
6693b3
-
6693b3
-  end = NEXT_INSN (BB_END (bb));
6693b3
-  for (insn = BB_HEAD (bb); insn != end; insn = NEXT_INSN (insn))
6693b3
-    {
6693b3
-      if (GET_CODE (insn) == NOTE
6693b3
-	  && NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
6693b3
-	break;
6693b3
-
6693b3
-      if (INSN_P (insn))
6693b3
-	{
6693b3
-	  HOST_WIDE_INT tmp;
6693b3
-
6693b3
-	  insn_stack_adjust_offset_pre_post (insn, &tmp, &tmp);
6693b3
-	  offset += tmp;
6693b3
-	}
6693b3
-    }
6693b3
-
6693b3
-  return offset;
6693b3
-}
6693b3
-
6693b3
 /* Compute stack adjustments for all blocks by traversing DFS tree.
6693b3
    Return true when the adjustments on all incoming edges are consistent.
6693b3
    Heavily borrowed from flow_depth_first_order_compute.  */
6693b3
@@ -533,7 +493,7 @@
6693b3
 
6693b3
   /* Initialize entry block.  */
6693b3
   VTI (ENTRY_BLOCK_PTR)->visited = true;
6693b3
-  VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = frame_stack_adjust;
6693b3
+  VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = INCOMING_FRAME_SP_OFFSET;
6693b3
 
6693b3
   /* Allocate stack for back-tracking up CFG.  */
6693b3
   stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
6693b3
@@ -587,27 +547,23 @@
6693b3
   return true;
6693b3
 }
6693b3
 
6693b3
-/* Adjust stack reference MEM by ADJUSTMENT bytes and return the new rtx.  */
6693b3
+/* Adjust stack reference MEM by ADJUSTMENT bytes and make it relative
6693b3
+   to the argument pointer.  Return the new rtx.  */
6693b3
 
6693b3
 static rtx
6693b3
 adjust_stack_reference (rtx mem, HOST_WIDE_INT adjustment)
6693b3
 {
6693b3
-  rtx adjusted_mem;
6693b3
-  rtx tmp;
6693b3
+  rtx addr, cfa, tmp;
6693b3
 
6693b3
-  if (adjustment == 0)
6693b3
-    return mem;
6693b3
+  adjustment -= ARG_POINTER_CFA_OFFSET (current_function_decl);
6693b3
+  cfa = plus_constant (arg_pointer_rtx, adjustment);
6693b3
 
6693b3
-  adjusted_mem = copy_rtx (mem);
6693b3
-  XEXP (adjusted_mem, 0) = replace_rtx (XEXP (adjusted_mem, 0),
6693b3
-					stack_pointer_rtx,
6693b3
-					gen_rtx_PLUS (Pmode, stack_pointer_rtx,
6693b3
-						      GEN_INT (adjustment)));
6693b3
-  tmp = simplify_rtx (XEXP (adjusted_mem, 0));
6693b3
+  addr = replace_rtx (copy_rtx (XEXP (mem, 0)), stack_pointer_rtx, cfa);
6693b3
+  tmp = simplify_rtx (addr);
6693b3
   if (tmp)
6693b3
-    XEXP (adjusted_mem, 0) = tmp;
6693b3
+    addr = tmp;
6693b3
 
6693b3
-  return adjusted_mem;
6693b3
+  return replace_equiv_address_nv (mem, addr);
6693b3
 }
6693b3
 
6693b3
 /* The hash function for variable_htab, computes the hash value
6693b3
@@ -1657,14 +1613,7 @@
6693b3
 	    break;
6693b3
 
6693b3
 	  case MO_ADJUST:
6693b3
-	    {
6693b3
-	      rtx base;
6693b3
-
6693b3
-	      out->stack_adjust += VTI (bb)->mos[i].u.adjust;
6693b3
-	      base = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
6693b3
-							out->stack_adjust));
6693b3
-	      set_frame_base_location (out, base);
6693b3
-	    }
6693b3
+	    out->stack_adjust += VTI (bb)->mos[i].u.adjust;
6693b3
 	    break;
6693b3
 	}
6693b3
     }
6693b3
@@ -1786,8 +1735,7 @@
6693b3
   for (; list; list = list->next)
6693b3
     {
6693b3
       print_mem_expr (rtl_dump_file, list->decl);
6693b3
-      fprintf (rtl_dump_file, "+");
6693b3
-      fprintf (rtl_dump_file, HOST_WIDE_INT_PRINT_DEC, list->offset);
6693b3
+      fprintf (rtl_dump_file, "+" HOST_WIDE_INT_PRINT_DEC, list->offset);
6693b3
     }
6693b3
   fprintf (rtl_dump_file, "\n");
6693b3
 }
6693b3
@@ -1837,9 +1785,8 @@
6693b3
 {
6693b3
   int i;
6693b3
 
6693b3
-  fprintf (rtl_dump_file, "Stack adjustment: ");
6693b3
-  fprintf (rtl_dump_file, HOST_WIDE_INT_PRINT_DEC, set->stack_adjust);
6693b3
-  fprintf (rtl_dump_file, "\n");
6693b3
+  fprintf (rtl_dump_file, "Stack adjustment: " HOST_WIDE_INT_PRINT_DEC "\n",
6693b3
+	   set->stack_adjust);
6693b3
   for (i = 1; i < FIRST_PSEUDO_REGISTER; i++)
6693b3
     {
6693b3
       if (set->regs[i])
6693b3
@@ -1921,37 +1868,6 @@
6693b3
     }
6693b3
 }
6693b3
 
6693b3
-/* Set the location of frame_base_decl to LOC in dataflow set SET.  This
6693b3
-   function expects that frame_base_decl has already one location for offset 0
6693b3
-   in the variable table.  */
6693b3
-
6693b3
-static void
6693b3
-set_frame_base_location (dataflow_set *set, rtx loc)
6693b3
-{
6693b3
-  variable var;
6693b3
-  
6693b3
-  var = htab_find_with_hash (set->vars, frame_base_decl,
6693b3
-			     VARIABLE_HASH_VAL (frame_base_decl));
6693b3
-#ifdef ENABLE_CHECKING
6693b3
-  if (!var)
6693b3
-    abort ();
6693b3
-  if (var->n_var_parts != 1)
6693b3
-    abort ();
6693b3
-  if (var->var_part[0].offset != 0)
6693b3
-    abort ();
6693b3
-  if (!var->var_part[0].loc_chain)
6693b3
-    abort ();
6693b3
-#endif
6693b3
-
6693b3
-  /* If frame_base_decl is shared unshare it first.  */
6693b3
-  if (var->refcount > 1)
6693b3
-    var = unshare_variable (set, var);
6693b3
-
6693b3
-  var->var_part[0].loc_chain->loc = loc;
6693b3
-  var->var_part[0].cur_loc = loc;
6693b3
-  variable_was_changed (var, set->vars);
6693b3
-}
6693b3
-
6693b3
 /* Set the part of variable's location in the dataflow set SET.  The variable
6693b3
    part is specified by variable's declaration DECL and offset OFFSET and the
6693b3
    part's location by LOC.  */
6693b3
@@ -2482,15 +2398,7 @@
6693b3
 	    break;
6693b3
 
6693b3
 	  case MO_ADJUST:
6693b3
-	    {
6693b3
-	      rtx base;
6693b3
-
6693b3
-	      set.stack_adjust += VTI (bb)->mos[i].u.adjust;
6693b3
-	      base = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
6693b3
-							set.stack_adjust));
6693b3
-	      set_frame_base_location (&set, base);
6693b3
-	      emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
6693b3
-	    }
6693b3
+	    set.stack_adjust += VTI (bb)->mos[i].u.adjust;
6693b3
 	    break;
6693b3
 	}
6693b3
     }
6693b3
@@ -2600,7 +2508,6 @@
6693b3
 	abort ();
6693b3
 #endif
6693b3
 
6693b3
-      incoming = eliminate_regs (incoming, 0, NULL_RTX);
6693b3
       out = &VTI (ENTRY_BLOCK_PTR)->out;
6693b3
 
6693b3
       if (GET_CODE (incoming) == REG)
6693b3
@@ -2614,9 +2521,7 @@
6693b3
 	  set_variable_part (out, incoming, parm, offset);
6693b3
 	}
6693b3
       else if (GET_CODE (incoming) == MEM)
6693b3
-	{
6693b3
-	  set_variable_part (out, incoming, parm, offset);
6693b3
-	}
6693b3
+	set_variable_part (out, incoming, parm, offset);
6693b3
     }
6693b3
 }
6693b3
 
6693b3
@@ -2761,28 +2666,6 @@
6693b3
   changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
6693b3
 				   NULL);
6693b3
   vt_add_function_parameters ();
6693b3
-
6693b3
-  if (!frame_pointer_needed)
6693b3
-    {
6693b3
-      rtx base;
6693b3
-
6693b3
-      /* Create fake variable for tracking stack pointer changes.  */
6693b3
-      frame_base_decl = make_node (VAR_DECL);
6693b3
-      DECL_NAME (frame_base_decl) = get_identifier ("___frame_base_decl");
6693b3
-      TREE_TYPE (frame_base_decl) = char_type_node;
6693b3
-      DECL_ARTIFICIAL (frame_base_decl) = 1;
6693b3
-      DECL_IGNORED_P (frame_base_decl) = 1;
6693b3
-
6693b3
-      /* Set its initial "location".  */
6693b3
-      frame_stack_adjust = -prologue_stack_adjust ();
6693b3
-      base = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
6693b3
-						frame_stack_adjust));
6693b3
-      set_variable_part (&VTI (ENTRY_BLOCK_PTR)->out, base, frame_base_decl, 0);
6693b3
-    }
6693b3
-  else
6693b3
-    {
6693b3
-      frame_base_decl = NULL;
6693b3
-    }
6693b3
 }
6693b3
 
6693b3
 /* Free the data structures needed for variable tracking.  */