This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


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

Re: [VTA] first step in turning debug insns into debug notes


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


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