2012-04-17 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Apr 2012 13:33:41 +0000 (13:33 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 17 Apr 2012 13:33:41 +0000 (13:33 +0000)
* tree-flow.h (array_at_struct_end_p): Move declaration ...
* tree.h (array_at_struct_end_p): ... here.
* tree-ssa-loop-niter.c (array_at_struct_end_p): Move ...
* expr.c (array_at_struct_end_p): ... here.  Rewrite.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186527 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/expr.c
gcc/tree-flow.h
gcc/tree-ssa-loop-niter.c
gcc/tree.h

index b1e1631..6ee7c12 100644 (file)
@@ -1,3 +1,10 @@
+2012-04-17  Richard Guenther  <rguenther@suse.de>
+
+       * tree-flow.h (array_at_struct_end_p): Move declaration ...
+       * tree.h (array_at_struct_end_p): ... here.
+       * tree-ssa-loop-niter.c (array_at_struct_end_p): Move ...
+       * expr.c (array_at_struct_end_p): ... here.  Rewrite.
+
 2012-04-17  Steven Bosscher  <steven@gcc.gnu.org>
 
        * stmt.c (cost_table_, use_cost_table, cost_table_initialize,
index 46282d1..479dacf 100644 (file)
@@ -6778,6 +6778,43 @@ array_ref_low_bound (tree exp)
   return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0);
 }
 
+/* Returns true if REF is an array reference to an array at the end of
+   a structure.  If this is the case, the array may be allocated larger
+   than its upper bound implies.  */
+
+bool
+array_at_struct_end_p (tree ref)
+{
+  if (TREE_CODE (ref) != ARRAY_REF
+      && TREE_CODE (ref) != ARRAY_RANGE_REF)
+    return false;
+
+  while (handled_component_p (ref))
+    {
+      /* If the reference chain contains a component reference to a
+         non-union type and there follows another field the reference
+        is not at the end of a structure.  */
+      if (TREE_CODE (ref) == COMPONENT_REF
+         && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
+       {
+         tree nextf = DECL_CHAIN (TREE_OPERAND (ref, 1));
+         while (nextf && TREE_CODE (nextf) != FIELD_DECL)
+           nextf = DECL_CHAIN (nextf);
+         if (nextf)
+           return false;
+       }
+
+      ref = TREE_OPERAND (ref, 0);
+    }
+
+  /* If the reference is based on a declared entity, the size of the array
+     is constrained by its given domain.  */
+  if (DECL_P (ref))
+    return false;
+
+  return true;
+}
+
 /* Return a tree representing the upper bound of the array mentioned in
    EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */
 
index ba3adb0..241ee05 100644 (file)
@@ -686,7 +686,6 @@ tree find_loop_niter (struct loop *, edge *);
 tree loop_niter_by_eval (struct loop *, edge);
 tree find_loop_niter_by_eval (struct loop *, edge *);
 void estimate_numbers_of_iterations (bool);
-bool array_at_struct_end_p (tree);
 bool scev_probably_wraps_p (tree, tree, gimple, struct loop *, bool);
 bool convert_affine_scev (struct loop *, tree, tree *, tree *, gimple, bool);
 
index 2529b36..8225121 100644 (file)
@@ -2640,47 +2640,6 @@ record_nonwrapping_iv (struct loop *loop, tree base, tree step, gimple stmt,
   record_estimate (loop, niter_bound, max, stmt, false, realistic, upper);
 }
 
-/* Returns true if REF is a reference to an array at the end of a dynamically
-   allocated structure.  If this is the case, the array may be allocated larger
-   than its upper bound implies.  */
-
-bool
-array_at_struct_end_p (tree ref)
-{
-  tree base = get_base_address (ref);
-  tree parent, field;
-
-  /* Unless the reference is through a pointer, the size of the array matches
-     its declaration.  */
-  if (!base || (!INDIRECT_REF_P (base) && TREE_CODE (base) != MEM_REF))
-    return false;
-
-  for (;handled_component_p (ref); ref = parent)
-    {
-      parent = TREE_OPERAND (ref, 0);
-
-      if (TREE_CODE (ref) == COMPONENT_REF)
-       {
-         /* All fields of a union are at its end.  */
-         if (TREE_CODE (TREE_TYPE (parent)) == UNION_TYPE)
-           continue;
-
-         /* Unless the field is at the end of the struct, we are done.  */
-         field = TREE_OPERAND (ref, 1);
-         if (DECL_CHAIN (field))
-           return false;
-       }
-
-      /* The other options are ARRAY_REF, ARRAY_RANGE_REF, VIEW_CONVERT_EXPR.
-        In all these cases, we might be accessing the last element, and
-        although in practice this will probably never happen, it is legal for
-        the indices of this last element to exceed the bounds of the array.
-        Therefore, continue checking.  */
-    }
-
-  return true;
-}
-
 /* Determine information about number of iterations a LOOP from the index
    IDX of a data reference accessed in STMT.  RELIABLE is true if STMT is
    guaranteed to be executed in every iteration of LOOP.  Callback for
index e8bd858..6bfc29e 100644 (file)
@@ -5068,6 +5068,8 @@ extern bool contains_packed_reference (const_tree exp);
 
 extern tree array_ref_element_size (tree);
 
+bool array_at_struct_end_p (tree);
+
 /* Return a tree representing the lower bound of the array mentioned in
    EXP, an ARRAY_REF or an ARRAY_RANGE_REF.  */