This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [VTA] first step in turning debug insns into debug notes
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 07 Apr 2008 04:15:24 -0300
- Subject: Re: [VTA] first step in turning debug insns into debug notes
- References: <ork5jgsqvr.fsf@oliva.athome.lsd.ic.unicamp.br>
for gcc/ChangeLog.vta
from Alexandre Oliva <aoliva@redhat.com>
* var-tracking.c: Include target.h.
(VT_MAY_HAVE_VALUE_LOC): Remove.
(vt_expand_loc): Don't discard values. Delegitimize top-level
MEMs.
* Makefile.in (var-tracking.o): Depend on TARGET_H.
* simplify-rtx.c (delegitimize_mem_from_attrs): New.
* rtl.h (delegitimize_mem_from_attrs): Declare it.
* target-def.h (TARGET_DELEGITIMIZE_ADDRESS): Use it.
* config/i386/i386.c (ix86_delegitimize_address): Use it.
* config/rs6000/rs6000.c (TARGET_DELEGITIMIZE_ADDRESS): Define to...
(rs600_delegitimize_address): ... this. New.
* expr.c (get_inner_reference): Don't crash if the ultimate
containing object is NULL.
* cfgexpand.c (expand_debug_expr_1): Conditionally renamed from...
(expand_debug_expr): ... this, to avoid unwrapped constants.
* dwarf2out.c (mem_loc_descriptor): Check for TLS symbols,
emit TLS annotations for them.
(loc_descriptor): Recurse for CONSTs. Discard value exprs.
* local-alloc.c (adjust_debug_insns_equivs): Wrap constants.
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c.orig 2008-04-07 03:34:45.000000000 -0300
+++ gcc/var-tracking.c 2008-04-07 03:34:52.000000000 -0300
@@ -107,6 +107,7 @@
#include "timevar.h"
#include "tree-pass.h"
#include "cselib.h"
+#include "target.h"
/* Type of micro operation. */
enum micro_operation_type
@@ -3378,12 +3379,6 @@ delete_variable_part (dataflow_set *set,
}
}
-/* ??? Unconditionally reject LOCs that are not actual locations, but
- rather expressions that denote values, for now. This requires
- extensions to DWARF-3, so even when we enable it, we may want to
- make it conditional. */
-#define VT_MAY_HAVE_VALUE_LOC false
-
/* Callback for cselib_expand_value, that looks for expressions
holding the value in the var-tracking hash tables. */
@@ -3431,24 +3426,8 @@ vt_expand_loc (rtx loc, htab_t vars)
loc = cselib_expand_value_rtx_cb (loc, scratch_regs, 5,
vt_expand_loc_callback, vars);
- if (loc && !VT_MAY_HAVE_VALUE_LOC)
- {
- switch (GET_CODE (loc))
- {
- case SUBREG:
- case SIGN_EXTEND:
- case ZERO_EXTEND:
- case REG:
- case MEM:
- case CONCAT:
- case CONCATN:
- case PARALLEL:
- break;
-
- default:
- return NULL;
- }
- }
+ if (loc && MEM_P (loc))
+ loc = targetm.delegitimize_address (loc);
return loc;
}
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in.orig 2008-04-07 03:34:45.000000000 -0300
+++ gcc/Makefile.in 2008-04-07 03:34:52.000000000 -0300
@@ -2609,7 +2609,7 @@ regstat.o : regstat.c $(CONFIG_H) $(SYST
var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h $(FLAGS_H) \
$(BASIC_BLOCK_H) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \
- $(REGS_H) $(EXPR_H) $(TIMEVAR_H) tree-pass.h cselib.h
+ $(REGS_H) $(EXPR_H) $(TIMEVAR_H) tree-pass.h cselib.h $(TARGET_H)
profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) $(FUNCTION_H) \
toplev.h $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \
Index: gcc/simplify-rtx.c
===================================================================
--- gcc/simplify-rtx.c.orig 2008-04-07 03:34:45.000000000 -0300
+++ gcc/simplify-rtx.c 2008-04-07 03:34:52.000000000 -0300
@@ -1,6 +1,6 @@
/* RTL simplification functions for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -202,6 +202,106 @@ avoid_constant_pool_reference (rtx x)
return x;
}
+/* Simplify a MEM based on its attributes. This is the default
+ delegitimize_address target hook, and it's recommended that every
+ overrider call it. */
+
+rtx
+delegitimize_mem_from_attrs (rtx x)
+{
+ if (MEM_P (x)
+ && MEM_EXPR (x)
+ && (!MEM_OFFSET (x)
+ || GET_CODE (MEM_OFFSET (x)) == CONST_INT))
+ {
+ tree decl = MEM_EXPR (x);
+ enum machine_mode mode = GET_MODE (x);
+ HOST_WIDE_INT offset = 0;
+
+ switch (TREE_CODE (decl))
+ {
+ default:
+ decl = NULL;
+ break;
+
+ case VAR_DECL:
+ break;
+
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ case COMPONENT_REF:
+ case BIT_FIELD_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case VIEW_CONVERT_EXPR:
+ {
+ HOST_WIDE_INT bitsize, bitpos;
+ tree toffset;
+ int unsignedp = 0, volatilep = 0;
+
+ decl = get_inner_reference (decl, &bitsize, &bitpos, &toffset,
+ &mode, &unsignedp, &volatilep, false);
+ if (bitsize != GET_MODE_BITSIZE (mode)
+ || (bitpos % BITS_PER_UNIT)
+ || (toffset && !host_integerp (toffset, 0)))
+ decl = NULL;
+ else
+ {
+ offset += bitpos / BITS_PER_UNIT;
+ if (toffset)
+ offset += TREE_INT_CST_LOW (toffset);
+ }
+ break;
+ }
+ }
+
+ if (decl
+ && mode == GET_MODE (x)
+ && TREE_CODE (decl) == VAR_DECL
+ && (TREE_STATIC (decl)
+ || DECL_THREAD_LOCAL_P (decl))
+ && DECL_RTL_SET_P (decl)
+ && MEM_P (DECL_RTL (decl)))
+ {
+ rtx newx;
+
+ if (MEM_OFFSET (x))
+ offset += INTVAL (MEM_OFFSET (x));
+
+ newx = DECL_RTL (decl);
+
+ if (MEM_P (newx))
+ {
+ rtx n = XEXP (newx, 0), o = XEXP (x, 0);
+
+ /* Avoid creating a new MEM needlessly if we already had
+ the same address. We do if there's no OFFSET and the
+ old address X is identical to NEWX, or if X is of the
+ form (plus NEWX OFFSET), or the NEWX is of the form
+ (plus Y (const_int Z)) and X is that with the offset
+ added: (plus Y (const_int Z+OFFSET)). */
+ if (!((offset == 0
+ || (GET_CODE (o) == PLUS
+ && GET_CODE (XEXP (o, 1)) == CONST_INT
+ && (offset == INTVAL (XEXP (o, 1))
+ || (GET_CODE (n) == PLUS
+ && GET_CODE (XEXP (n, 1)) == CONST_INT
+ && (INTVAL (XEXP (n, 1)) + offset
+ == INTVAL (XEXP (o, 1)))
+ && (n = XEXP (n, 0))))
+ && (o = XEXP (o, 0))))
+ && rtx_equal_p (o, n)))
+ x = adjust_address_nv (newx, mode, offset);
+ }
+ else if (GET_MODE (x) == GET_MODE (newx)
+ && offset == 0)
+ x = newx;
+ }
+ }
+
+ return x;
+}
+
/* Make a unary operation by first seeing if it folds and otherwise making
the specified operation. */
Index: gcc/rtl.h
===================================================================
--- gcc/rtl.h.orig 2008-04-07 03:34:45.000000000 -0300
+++ gcc/rtl.h 2008-04-07 03:34:52.000000000 -0300
@@ -1716,6 +1716,7 @@ extern rtx simplify_gen_subreg (enum mac
extern rtx simplify_replace_rtx (rtx, const_rtx, rtx);
extern rtx simplify_rtx (const_rtx);
extern rtx avoid_constant_pool_reference (rtx);
+extern rtx delegitimize_mem_from_attrs (rtx);
extern bool mode_signbit_p (enum machine_mode, const_rtx);
/* In regclass.c */
Index: gcc/target-def.h
===================================================================
--- gcc/target-def.h.orig 2008-04-07 03:34:45.000000000 -0300
+++ gcc/target-def.h 2008-04-07 03:34:52.000000000 -0300
@@ -1,5 +1,5 @@
/* Default initializers for a generic GCC target.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify it
@@ -461,7 +461,7 @@
#define TARGET_CANNOT_FORCE_CONST_MEM hook_bool_rtx_false
#define TARGET_CANNOT_COPY_INSN_P NULL
#define TARGET_COMMUTATIVE_P hook_bool_const_rtx_commutative_p
-#define TARGET_DELEGITIMIZE_ADDRESS hook_rtx_rtx_identity
+#define TARGET_DELEGITIMIZE_ADDRESS delegitimize_mem_from_attrs
#define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_false
#define TARGET_MIN_ANCHOR_OFFSET 0
#define TARGET_MAX_ANCHOR_OFFSET 0
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c.orig 2008-04-07 03:34:45.000000000 -0300
+++ gcc/config/i386/i386.c 2008-04-07 03:35:02.000000000 -0300
@@ -8312,9 +8312,9 @@ i386_output_dwarf_dtprel (FILE *file, in
the DWARF output code. */
static rtx
-ix86_delegitimize_address (rtx orig_x)
+ix86_delegitimize_address (rtx x)
{
- rtx x = orig_x;
+ rtx orig_x = delegitimize_mem_from_attrs (x);
/* reg_addend is NULL or a multiple of some register. */
rtx reg_addend = NULL_RTX;
/* const_addend is NULL or a const_int. */
@@ -8322,6 +8322,8 @@ ix86_delegitimize_address (rtx orig_x)
/* This is the result, or NULL. */
rtx result = NULL_RTX;
+ x = orig_x;
+
if (MEM_P (x))
x = XEXP (x, 0);
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c.orig 2008-04-07 03:34:45.000000000 -0300
+++ gcc/config/rs6000/rs6000.c 2008-04-07 03:34:52.000000000 -0300
@@ -1,6 +1,6 @@
/* Subroutines used for code generation on IBM RS/6000.
Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
@@ -868,6 +868,7 @@ static bool rs6000_is_opaque_type (const
static rtx rs6000_dwarf_register_span (rtx);
static void rs6000_init_dwarf_reg_sizes_extra (tree);
static rtx rs6000_legitimize_tls_address (rtx, enum tls_model);
+static rtx rs6000_delegitimize_address (rtx);
static void rs6000_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
static rtx rs6000_tls_get_addr (void);
static rtx rs6000_got_sym (void);
@@ -1225,6 +1226,9 @@ static const char alt_reg_names[][8] =
#undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
#define TARGET_USE_BLOCKS_FOR_CONSTANT_P rs6000_use_blocks_for_constant_p
+#undef TARGET_DELEGITIMIZE_ADDRESS
+#define TARGET_DELEGITIMIZE_ADDRESS rs6000_delegitimize_address
+
#undef TARGET_BUILTIN_RECIPROCAL
#define TARGET_BUILTIN_RECIPROCAL rs6000_builtin_reciprocal
@@ -3678,6 +3682,33 @@ rs6000_legitimize_address (rtx x, rtx ol
return NULL_RTX;
}
+/* If ORIG_X is a constant pool reference, return its known value,
+ otherwise ORIG_X. */
+
+static rtx
+rs6000_delegitimize_address (rtx x)
+{
+ rtx orig_x = delegitimize_mem_from_attrs (x);
+
+ x = orig_x;
+
+ if (!MEM_P (x))
+ return orig_x;
+
+ x = XEXP (x, 0);
+
+ if (legitimate_constant_pool_address_p (x)
+ && GET_CODE (XEXP (x, 1)) == CONST
+ && GET_CODE (XEXP (XEXP (x, 1), 0)) == MINUS
+ && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 0)) == SYMBOL_REF
+ && constant_pool_expr_p (XEXP (XEXP (XEXP (x, 1), 0), 0))
+ && GET_CODE (XEXP (XEXP (XEXP (x, 1), 0), 1)) == SYMBOL_REF
+ && toc_relative_expr_p (XEXP (XEXP (XEXP (x, 1), 0), 1)))
+ return get_pool_constant (XEXP (XEXP (XEXP (x, 1), 0), 0));
+
+ return orig_x;
+}
+
/* This is called from dwarf2out.c via TARGET_ASM_OUTPUT_DWARF_DTPREL.
We need to emit DTP-relative relocations. */
Index: gcc/expr.c
===================================================================
--- gcc/expr.c.orig 2008-04-07 03:34:45.000000000 -0300
+++ gcc/expr.c 2008-04-07 03:34:52.000000000 -0300
@@ -1,6 +1,6 @@
/* Convert tree expression to rtl instructions, for GNU compiler.
Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -5925,7 +5925,7 @@ get_inner_reference (tree exp, HOST_WIDE
/* Compute cumulative bit-offset for nested component-refs and array-refs,
and find the ultimate containing object. */
- while (1)
+ do
{
switch (TREE_CODE (exp))
{
@@ -6004,6 +6004,7 @@ get_inner_reference (tree exp, HOST_WIDE
exp = TREE_OPERAND (exp, 0);
}
+ while (exp);
done:
/* If OFFSET is constant, see if we can return the whole thing as a
Index: gcc/cfgexpand.c
===================================================================
--- gcc/cfgexpand.c.orig 2008-04-07 03:39:23.000000000 -0300
+++ gcc/cfgexpand.c 2008-04-07 03:39:32.000000000 -0300
@@ -1628,12 +1628,31 @@ unwrap_constant (rtx x)
return x;
}
+#ifdef ENABLE_CHECKING
+static rtx expand_debug_expr_1 (tree exp);
+#endif
+
/* Return an RTX equivalent to the value of the tree expression
EXP. */
static rtx
expand_debug_expr (tree exp)
{
+#ifdef ENABLE_CHECKING
+ rtx ret = expand_debug_expr_1 (exp);
+
+ gcc_assert (!ret || GET_MODE (ret) != VOIDmode
+ || (GET_CODE (ret) != CONST_INT
+ && GET_CODE (ret) != CONST_FIXED
+ && GET_CODE (ret) != CONST_DOUBLE));
+
+ return ret;
+}
+
+static rtx
+expand_debug_expr_1 (tree exp)
+{
+#endif
rtx op0 = NULL_RTX, op1 = NULL_RTX, op2 = NULL_RTX;
enum machine_mode mode = TYPE_MODE (TREE_TYPE (exp));
int unsignedp = TYPE_UNSIGNED (TREE_TYPE (exp));
@@ -2142,7 +2161,7 @@ expand_debug_expr (tree exp)
if (!op0 || !MEM_P (op0))
return NULL;
- return XEXP (op0, 0);
+ return wrap_constant (mode, XEXP (op0, 0));
case VECTOR_CST:
exp = build_constructor_from_list (TREE_TYPE (exp),
Index: gcc/dwarf2out.c
===================================================================
--- gcc/dwarf2out.c.orig 2008-04-07 03:39:21.000000000 -0300
+++ gcc/dwarf2out.c 2008-04-07 03:40:12.000000000 -0300
@@ -9168,6 +9168,25 @@ mem_loc_descriptor (rtx rtl, enum machin
return 0;
}
+ if (GET_CODE (rtl) == SYMBOL_REF
+ && SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE)
+ {
+ dw_loc_descr_ref temp;
+
+ /* If this is not defined, we have no way to emit the data. */
+ if (!targetm.have_tls || !targetm.asm_out.output_dwarf_dtprel)
+ break;
+
+ temp = new_loc_descr (INTERNAL_DW_OP_tls_addr, 0, 0);
+ temp->dw_loc_oprnd1.val_class = dw_val_class_addr;
+ temp->dw_loc_oprnd1.v.val_addr = rtl;
+
+ mem_loc_result = new_loc_descr (DW_OP_GNU_push_tls_address, 0, 0);
+ add_loc_descr (&mem_loc_result, temp);
+
+ break;
+ }
+
mem_loc_result = new_loc_descr (DW_OP_addr, 0, 0);
mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_addr;
mem_loc_result->dw_loc_oprnd1.v.val_addr = rtl;
@@ -9412,8 +9431,13 @@ loc_descriptor (rtx rtl, enum var_init_s
}
break;
+ case CONST:
+ loc_result = loc_descriptor (XEXP (rtl, 0), initialized);
+ break;
+
default:
- gcc_unreachable ();
+ /* Value expression. */
+ break;
}
return loc_result;
Index: gcc/local-alloc.c
===================================================================
--- gcc/local-alloc.c.orig 2008-04-07 03:39:20.000000000 -0300
+++ gcc/local-alloc.c 2008-04-07 03:40:30.000000000 -0300
@@ -1,6 +1,6 @@
/* Allocate registers within a basic block, for GNU compiler.
Copyright (C) 1987, 1988, 1991, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
@@ -807,24 +807,42 @@ adjust_debug_insns_equivs (unsigned regn
for (use = DF_REG_USE_CHAIN (regno); use; use = DF_REF_NEXT_REG (use))
{
rtx insn = DF_REF_INSN (use), *loc, x;
+ bool wrap = false;
if (!DEBUG_INSN_P (insn))
continue;
+ loc = DF_REF_LOC (use);
+ x = *loc;
+
if (!eqv)
{
+ rtx reg;
+
eqv = *reg_equiv[regno].src_p;
if (MEM_P (eqv))
eqv = targetm.delegitimize_address (eqv);
- }
- loc = DF_REF_LOC (use);
- x = *loc;
+ if (GET_CODE (x) == SUBREG)
+ reg = SUBREG_REG (x);
+ else
+ reg = x;
+
+ if (GET_MODE (eqv) != GET_MODE (reg))
+ {
+ rtx save = eqv;
+
+ eqv = wrap_constant (GET_MODE (reg), eqv);
+
+ if (save != eqv && GET_CODE (eqv) == CONST)
+ wrap = true;
+
+ gcc_assert (GET_MODE (eqv) == GET_MODE (reg));
+ }
+ }
if (REG_P (x) && REGNO (x) == regno)
{
- gcc_assert (GET_MODE (eqv) == VOIDmode
- || GET_MODE (eqv) == GET_MODE (x));
validate_unshare_change (insn, loc, eqv, true);
}
else if (GET_CODE (x) == SUBREG && REGNO (SUBREG_REG (x)) == regno)
@@ -839,6 +857,9 @@ adjust_debug_insns_equivs (unsigned regn
GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x));
+ if (wrap)
+ sreqv = wrap_constant (GET_MODE (x), sreqv);
+
validate_change (insn, loc, sreqv, true);
}
else