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]

[PATCH, pretty-ipa]


Hi,

the patch below updates DECL_VALUE_EXPR and BLOCK_NONLOCALIZED_VARS so
that  dwarf2out can  then still  express the  value of  the aggregates
scalarized  by  intra-SRA.  Basically,  it  stores there  constructors
describing how to access  individual leaf (i.e.  non-aggregate) fields
(and array  elements) there.  create_debug_constructor  uses callbacks
so that  the function can be reused  for IPA-SRA as well  (I will post
this as a followup patch).  Honza works on the dwarf2out bits.

It  has  bootstrapped  and  is currently  being  regression-tested  on
x86_64-linux.  OK for pretty-ipa if it passes?

Thanks,

Martin


2009-04-02  Martin Jambor  <mjambor@suse.cz>

	* ipa-sra.c: Include flags.h
	(create_debug_constructor): New function.
	(access_tree_debug_search): New function.
	(intra_remap_nonlocalized_vars): New function.
	(intra_store_all_debug_information): New function.
	(perform_new_intra_sra): Call intra_store_all_debug_information.

Index: isra/gcc/ipa-sra.c
===================================================================
--- isra.orig/gcc/ipa-sra.c
+++ isra/gcc/ipa-sra.c
@@ -140,6 +140,8 @@ along with GCC; see the file COPYING3.
 #include "params.h"
 #include "target.h"
 #include "ipa-utils.h"
+#include "flags.h"
+
 
 /* Enumeration of all aggregate reductions we can do.  */
 enum sra_mode {SRA_MODE_EARLY_IPA,
@@ -2686,6 +2688,114 @@ convert_callers (struct cgraph_node *nod
   return;
 }
 
+/* Returns a constructor for aggregate of TYPE type which is a part of DECL at
+   offset OFFSET and accessible through EXPR.  SEARCH is a callback function
+   which locates values given their offset and size.  If EXPR is NULL, the
+   parts of the aggregate which have not been located by SEARCH have been
+   optimized out.  Returns error_mark_node if something goes wrong and this
+   cannot be achieved, for example when array index bounds cannot be
+   edetermined.  DATA is passed to SEARCH and not interpreted in any way.  */
+
+static tree
+create_debug_constructor (tree type, tree decl, tree expr,
+			  HOST_WIDE_INT offset,
+			  tree (*search) (tree, HOST_WIDE_INT, HOST_WIDE_INT,
+					  void *), void *data)
+{
+  tree fld, el, domain, index, max, tree_size;
+  HOST_WIDE_INT size;
+  VEC(constructor_elt,gc) *vals = VEC_alloc (constructor_elt, gc, 8);
+
+  gcc_assert (AGGREGATE_TYPE_P (type));
+
+  switch (TREE_CODE (type))
+    {
+    case UNION_TYPE:
+    case QUAL_UNION_TYPE:
+    case RECORD_TYPE:
+      for (fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
+	{
+	  HOST_WIDE_INT pos;
+	  tree fld_type, ref;
+	  constructor_elt *elt;
+	  tree value;
+
+	  if (TREE_CODE (fld) != FIELD_DECL)
+	    continue;
+	  pos = int_bit_position (fld);
+	  elt = VEC_safe_push (constructor_elt, gc, vals, NULL);
+	  elt->index = fld;
+	  if (expr)
+	    ref = build3 (COMPONENT_REF, TREE_TYPE (fld), expr, fld,
+			  NULL_TREE);
+	  else
+	    ref = NULL;
+	  fld_type = TREE_TYPE (fld);
+	  tree_size = TYPE_SIZE (TREE_TYPE (fld));
+	  gcc_assert (tree_size && host_integerp (tree_size, 1));
+	  size = tree_low_cst (tree_size, 1);
+
+	  value = search (decl, offset + pos, size, data);
+	  if (!value)
+	    {
+	      if (AGGREGATE_TYPE_P (fld_type))
+		value = create_debug_constructor (fld_type, decl, ref,
+						  offset + pos, search, data);
+	      else
+		value = ref;
+	    }
+	  elt->value = value;
+	}
+
+      break;
+    case ARRAY_TYPE:
+      domain = TYPE_DOMAIN (type);
+
+      if (!domain || !TYPE_MIN_VALUE (domain) || !TYPE_MAX_VALUE (domain))
+	return error_mark_node;
+
+      el = TREE_TYPE (type);
+      tree_size = TYPE_SIZE (el);
+      gcc_assert (tree_size && host_integerp (tree_size, 1));
+      size = tree_low_cst (tree_size, 1);
+      index =  TYPE_MIN_VALUE (domain);
+      max = TYPE_MAX_VALUE (domain);
+      while (!tree_int_cst_lt (max, index))
+	{
+	  constructor_elt *elt;
+	  tree ref, value;
+
+	  if (expr)
+	    ref = build4 (ARRAY_REF, TREE_TYPE (type), expr, index,
+			  NULL_TREE, NULL_TREE);
+	  else
+	    ref = NULL;
+
+	  elt = VEC_safe_push (constructor_elt, gc, vals, NULL);
+	  elt->index = index;
+
+	  value = search (decl, offset, size, data);
+	  if (!value)
+	    {
+	      if (AGGREGATE_TYPE_P (el))
+		value = create_debug_constructor (el, decl, ref, offset,
+						  search, data);
+	      else
+		value = ref;
+	    }
+	  elt->value = value;
+	  offset += size;
+	  index = int_const_binop (PLUS_EXPR, index, integer_one_node, 0);
+	}
+
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  return build_constructor (type, vals);
+}
+
 /* Perform all the modification required in IPA-SRA for NODE to have parameters
    as given in NOTES.  */
 
@@ -3890,6 +4000,79 @@ initialize_parameter_reductions (void)
 
 }
 
+/* Callback used by build_debug_constructor to locate a replacement in access
+   tree.  */
+
+static tree
+access_tree_debug_search (tree decl, HOST_WIDE_INT offset,
+			  HOST_WIDE_INT size, void *data ATTRIBUTE_UNUSED)
+{
+  struct access *access = get_var_base_offset_size_access (decl, offset, size);
+  if (access && access->to_be_replaced)
+    {
+      /* We read replacement_decl here directly because after the
+	 function has been modified it really ought to exist.  */
+      gcc_assert (access->replacement_decl);
+      return access->replacement_decl;
+    }
+  else
+    return NULL;
+}
+
+/* If any of values of NONLOCALIZED_VARS holds an aggregate that was split into
+   components by intra-SRA,  replace it with an appropriate constructor.  */
+
+static void
+intra_remap_nonlocalized_vars (tree block)
+{
+  int i, n;
+  tree t;
+
+  n = BLOCK_NUM_NONLOCALIZED_VARS (block);
+  for (i = 0; i < n; i++)
+    {
+      tree var = BLOCK_NONLOCALIZED_VAR_VALUE (block, i);
+
+      if (var && DECL_P (var)
+	  && bitmap_bit_p (candidate_bitmap, DECL_UID (var)))
+	{
+	  BLOCK_NONLOCALIZED_VAR_VALUE (block, i)
+	    = create_debug_constructor (TREE_TYPE (var), var, var, 0,
+					access_tree_debug_search, NULL);
+	}
+    }
+
+  for (t = BLOCK_SUBBLOCKS (block); t ; t = BLOCK_CHAIN (t))
+    intra_remap_nonlocalized_vars (t);
+}
+
+/* Store information describing how aggregates were reduced by intra-SRA to be
+   used later when generating debug info, if the debug info level requires it
+   it.  */
+
+static void
+intra_store_all_debug_information (void)
+{
+  tree var;
+  referenced_var_iterator rvi;
+
+  if (debug_info_level <= DINFO_LEVEL_TERSE)
+    return;
+
+  FOR_EACH_REFERENCED_VAR (var, rvi)
+    {
+      if (bitmap_bit_p (candidate_bitmap, DECL_UID (var)))
+	{
+	  tree cst;
+
+	  cst = create_debug_constructor (TREE_TYPE (var), var, var, 0,
+					  access_tree_debug_search, NULL);
+	  SET_DECL_VALUE_EXPR (var, cst);
+	}
+    }
+
+  intra_remap_nonlocalized_vars (DECL_INITIAL (current_function_decl));
+}
 
 /* The "main" function of intraprocedural SRA passes.  Runs the analysis and if
    it reveals there are components of some aggregates to be scalarized, it runs
@@ -3913,6 +4096,7 @@ perform_new_intra_sra (void)
   scan_function (sra_intra_modify_expr, sra_intra_modify_assign, NULL,
 		 false, NULL);
   initialize_parameter_reductions ();
+  intra_store_all_debug_information();
 
   if (sra_mode == SRA_MODE_EARLY_INTRA)
     ret = TODO_update_ssa;
Index: isra/gcc/Makefile.in
===================================================================
--- isra.orig/gcc/Makefile.in
+++ isra/gcc/Makefile.in
@@ -2614,7 +2614,7 @@ ipa-inline.o : ipa-inline.c gt-ipa-inlin
 ipa-sra.o : ipa-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    $(GIMPLE_H) $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) $(TREE_FLOW_H) \
    $(DIAGNOSTIC_H) $(TREE_DUMP_H) $(IPA_PROP_H) $(TIMEVAR_H) $(TARGET_H) \
-   tree-pass.h $(PARAMS_H)
+   tree-pass.h $(PARAMS_H) $(FLAGS_H)
 
 ipa-utils.o : ipa-utils.c $(IPA_UTILS_H) $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h $(TM_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) langhooks.h \


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