|
|
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. */
|