diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2005-10-19 16:27:10 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2005-10-19 16:27:10 +0000 |
commit | a1b23b2f7cef7cd0b8df65ed1936b8ea7ea65696 (patch) | |
tree | c114fff08f7b39691bd889779fe938aaad5a6e05 /gcc/cfgexpand.c | |
parent | f95f80d1a762998d6b8731d506f6667ccbdaf996 (diff) | |
download | gcc-a1b23b2f7cef7cd0b8df65ed1936b8ea7ea65696.tar.gz |
cfgexpand.c (discover_nonconstant_array_refs_r, [...]): Move here from tree-outof-ssa.c
* cfgexpand.c (discover_nonconstant_array_refs_r,
discover_nonconstant_array_refs): Move here from tree-outof-ssa.c
(tree_expand_cfg): Call discover_nonconstant_array_refs.
* tree-outof-ssa.c (rewrite_out_of_ssa): Remove call to
discover_nonconstant_array_refs.
From-SVN: r105623
Diffstat (limited to 'gcc/cfgexpand.c')
-rw-r--r-- | gcc/cfgexpand.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 69546bf1350..f3a340ac251 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -1463,6 +1463,67 @@ construct_exit_block (void) update_bb_for_insn (exit_block); } +/* Helper function for discover_nonconstant_array_refs. + Look for ARRAY_REF nodes with non-constant indexes and mark them + addressable. */ + +static tree +discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees, + void *data ATTRIBUTE_UNUSED) +{ + tree t = *tp; + + if (IS_TYPE_OR_DECL_P (t)) + *walk_subtrees = 0; + else if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) + { + while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) + && is_gimple_min_invariant (TREE_OPERAND (t, 1)) + && (!TREE_OPERAND (t, 2) + || is_gimple_min_invariant (TREE_OPERAND (t, 2)))) + || (TREE_CODE (t) == COMPONENT_REF + && (!TREE_OPERAND (t,2) + || is_gimple_min_invariant (TREE_OPERAND (t, 2)))) + || TREE_CODE (t) == BIT_FIELD_REF + || TREE_CODE (t) == REALPART_EXPR + || TREE_CODE (t) == IMAGPART_EXPR + || TREE_CODE (t) == VIEW_CONVERT_EXPR + || TREE_CODE (t) == NOP_EXPR + || TREE_CODE (t) == CONVERT_EXPR) + t = TREE_OPERAND (t, 0); + + if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF) + { + t = get_base_address (t); + if (t && DECL_P (t)) + TREE_ADDRESSABLE (t) = 1; + } + + *walk_subtrees = 0; + } + + return NULL_TREE; +} + +/* RTL expansion is not able to compile array references with variable + offsets for arrays stored in single register. Discover such + expressions and mark variables as addressable to avoid this + scenario. */ + +static void +discover_nonconstant_array_refs (void) +{ + basic_block bb; + block_stmt_iterator bsi; + + FOR_EACH_BB (bb) + { + for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) + walk_tree (bsi_stmt_ptr (bsi), discover_nonconstant_array_refs_r, + NULL , NULL); + } +} + /* Translate the intermediate representation contained in the CFG from GIMPLE trees to RTL. @@ -1484,6 +1545,9 @@ tree_expand_cfg (void) /* Prepare the rtl middle end to start recording block changes. */ reset_block_changes (); + /* Mark arrays indexed with non-constant indices with TREE_ADDRESSABLE. */ + discover_nonconstant_array_refs (); + /* Expand the variables recorded during gimple lowering. */ expand_used_vars (); |