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 4/7] Break up determine_known_aggregate_parts


Hi,

the main purpose of this patch is to break up function
determine_known_aggregate_parts so that the next patch can use the
standalone bits and to make the changes slightly easier for review.

However, this patch also removes some of the offset checks which Honza
correctly thought superfluous and even possibly filtering out useful
information.
 
Bootstrapped and tested and LTO-bootstrapped on x86_64-linux.
OK for trunk after the preceeding patches get in?

Thanks,

Martin


2014-02-19  Martin Jambor  <mjambor@suse.cz>

	* ipa-prop.c (get_place_in_agg_contents_list): New function.
	(build_agg_jump_func_from_list): Likewise.
	(determine_known_aggregate_parts): Renamed to
	determine_locally_known_aggregate_parts.  Moved some functionality
	to the two functions above, removed bound checks.

Index: src/gcc/ipa-prop.c
===================================================================
--- src.orig/gcc/ipa-prop.c
+++ src/gcc/ipa-prop.c
@@ -1679,14 +1679,72 @@ struct ipa_known_agg_contents_list
   struct ipa_known_agg_contents_list *next;
 };
 
+/* Find the proper place in linked list of ipa_known_agg_contents_list
+   structures where to put a new one with the given LHS_OFFSET and LHS_SIZE,
+   unless there is a partial overlap, in which case return NULL, or such
+   element is already there, in which case set *ALREADY_THERE to true.  */
+
+static struct ipa_known_agg_contents_list **
+get_place_in_agg_contents_list (struct ipa_known_agg_contents_list **list,
+				HOST_WIDE_INT lhs_offset,
+				HOST_WIDE_INT lhs_size,
+				bool *already_there)
+{
+  struct ipa_known_agg_contents_list **p = list;
+  while (*p && (*p)->offset < lhs_offset)
+    {
+      if ((*p)->offset + (*p)->size > lhs_offset)
+	return NULL;
+      p = &(*p)->next;
+    }
+
+  if (*p && (*p)->offset < lhs_offset + lhs_size)
+    {
+      if ((*p)->offset == lhs_offset && (*p)->size == lhs_size)
+	/* We already know this value is subsequently overwritten with
+	   something else.  */
+	*already_there = true;
+      else
+	/* Otherwise this is a partial overlap which we cannot
+	   represent.  */
+	return NULL;
+    }
+  return p;
+}
+
+/* Build aggregate jump function from LIST, assuming there are exactly
+   CONST_COUNT constant entries there and that th offset of the passed argument
+   is ARG_OFFSET and store it into JFUNC.  */
+
+static void
+build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
+			       int const_count, HOST_WIDE_INT arg_offset,
+			       struct ipa_jump_func *jfunc)
+{
+  vec_alloc (jfunc->agg.items, const_count);
+  while (list)
+    {
+      if (list->constant)
+	{
+	  struct ipa_agg_jf_item item;
+	  item.offset = list->offset - arg_offset;
+	  gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
+	  item.value = unshare_expr_without_location (list->constant);
+	  jfunc->agg.items->quick_push (item);
+	}
+      list = list->next;
+    }
+}
+
 /* Traverse statements from CALL backwards, scanning whether an aggregate given
    in ARG is filled in with constant values.  ARG can either be an aggregate
-   expression or a pointer to an aggregate.  ARG_TYPE is the type of the aggregate.
-   JFUNC is the jump function into which the constants are subsequently stored.  */
+   expression or a pointer to an aggregate.  ARG_TYPE is the type of the
+   aggregate.  JFUNC is the jump function into which the constants are
+   subsequently stored.  */
 
 static void
-determine_known_aggregate_parts (gimple call, tree arg, tree arg_type,
-				 struct ipa_jump_func *jfunc)
+determine_locally_known_aggregate_parts (gimple call, tree arg, tree arg_type,
+					 struct ipa_jump_func *jfunc)
 {
   struct ipa_known_agg_contents_list *list = NULL;
   int item_count = 0, const_count = 0;
@@ -1728,10 +1786,8 @@ determine_known_aggregate_parts (gimple
 	    return;
 	  if (DECL_P (arg_base))
 	    {
-	      tree size;
 	      check_ref = false;
-	      size = build_int_cst (integer_type_node, arg_size);
-	      ao_ref_init_from_ptr_and_size (&r, arg_base, size);
+	      ao_ref_init (&r, arg_base);
 	    }
 	  else
 	    return;
@@ -1769,7 +1825,6 @@ determine_known_aggregate_parts (gimple
       gimple stmt = gsi_stmt (gsi);
       HOST_WIDE_INT lhs_offset, lhs_size, lhs_max_size;
       tree lhs, rhs, lhs_base;
-      bool partial_overlap;
 
       if (!stmt_may_clobber_ref_p_1 (stmt, &r))
 	continue;
@@ -1786,11 +1841,7 @@ determine_known_aggregate_parts (gimple
       lhs_base = get_ref_base_and_extent (lhs, &lhs_offset, &lhs_size,
 					  &lhs_max_size);
       if (lhs_max_size == -1
-	  || lhs_max_size != lhs_size
-	  || (lhs_offset < arg_offset
-	      && lhs_offset + lhs_size > arg_offset)
-	  || (lhs_offset < arg_offset + arg_size
-	      && lhs_offset + lhs_size > arg_offset + arg_size))
+	  || lhs_max_size != lhs_size)
 	break;
 
       if (check_ref)
@@ -1808,34 +1859,13 @@ determine_known_aggregate_parts (gimple
 	    break;
 	}
 
-      if (lhs_offset + lhs_size < arg_offset
-	  || lhs_offset >= (arg_offset + arg_size))
-	continue;
-
-      partial_overlap = false;
-      p = &list;
-      while (*p && (*p)->offset < lhs_offset)
-	{
-	  if ((*p)->offset + (*p)->size > lhs_offset)
-	    {
-	      partial_overlap = true;
-	      break;
-	    }
-	  p = &(*p)->next;
-	}
-      if (partial_overlap)
+      bool already_there = false;
+      p = get_place_in_agg_contents_list (&list, lhs_offset, lhs_size,
+					  &already_there);
+      if (!p)
 	break;
-      if (*p && (*p)->offset < lhs_offset + lhs_size)
-	{
-	  if ((*p)->offset == lhs_offset && (*p)->size == lhs_size)
-	    /* We already know this value is subsequently overwritten with
-	       something else.  */
-	    continue;
-	  else
-	    /* Otherwise this is a partial overlap which we cannot
-	       represent.  */
-	    break;
-	}
+      if (already_there)
+	continue;
 
       rhs = get_ssa_def_if_simple_copy (rhs);
       n = XALLOCA (struct ipa_known_agg_contents_list);
@@ -1864,19 +1894,7 @@ determine_known_aggregate_parts (gimple
   if (const_count)
     {
       jfunc->agg.by_ref = by_ref;
-      vec_alloc (jfunc->agg.items, const_count);
-      while (list)
-	{
-	  if (list->constant)
-	    {
-	      struct ipa_agg_jf_item item;
-	      item.offset = list->offset - arg_offset;
-	      gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
-	      item.value = unshare_expr_without_location (list->constant);
-	      jfunc->agg.items->quick_push (item);
-	    }
-	  list = list->next;
-	}
+      build_agg_jump_func_from_list (list, const_count, arg_offset, jfunc);
     }
 }
 
@@ -2113,7 +2131,7 @@ ipa_compute_jump_functions_for_edge (str
 	  && jfunc->type != IPA_JF_ANCESTOR
 	  && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
 	      || POINTER_TYPE_P (param_type)))
-	determine_known_aggregate_parts (call, arg, param_type, jfunc);
+	determine_locally_known_aggregate_parts (call, arg, param_type, jfunc);
     }
 }
 


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