From: rguenth Date: Tue, 17 Apr 2012 13:33:41 +0000 (+0000) Subject: 2012-04-17 Richard Guenther X-Git-Tag: upstream/4.9.2~13227 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e01d3bb3abd2029e1e4fbfb4e2ce6cfc0a63ca97;p=platform%2Fupstream%2Flinaro-gcc.git 2012-04-17 Richard Guenther * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b1e1631..6ee7c12 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2012-04-17 Richard Guenther + + * 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 * stmt.c (cost_table_, use_cost_table, cost_table_initialize, diff --git a/gcc/expr.c b/gcc/expr.c index 46282d1..479dacf 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -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. */ diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index ba3adb0..241ee05 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -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); diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 2529b36..8225121 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -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 diff --git a/gcc/tree.h b/gcc/tree.h index e8bd858..6bfc29e 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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. */