diff options
author | uweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-11-02 14:30:39 +0000 |
---|---|---|
committer | uweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4> | 2009-11-02 14:30:39 +0000 |
commit | 2451b8b88f07121042f58a4f646cbc045f8630e0 (patch) | |
tree | f4baec2a8f727693a22c86047fb07064f6e86319 /gcc/tree-ssa-loop-ivopts.c | |
parent | fe9e92d635d662fe1cd8d03dea9d33a7457fb3d7 (diff) | |
download | gcc-2451b8b88f07121042f58a4f646cbc045f8630e0.tar.gz |
gcc/
PR tree-optimization/41857
* tree-flow.h (rewrite_use_address): Add BASE_HINT argument.
* tree-ssa-loop-ivopts.c (rewrite_use_address): Pass base hint
to create_mem_ref.
* tree-ssa-address.c (move_hint_to_base): New function.
(most_expensive_mult_to_index): Add TYPE argument. Use mode and
address space associated with TYPE.
(addr_to_parts): Add TYPE and BASE_HINT arguments. Pass TYPE to
most_expensive_mult_to_index. Call move_hint_to_base.
(create_mem_ref): Add BASE_HINT argument. Pass BASE_HINT and
TYPE to addr_to_parts.
gcc/testsuite/
PR tree-optimization/41857
* gcc.target/spu/ea/pr41857.c: New file.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153810 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-ssa-loop-ivopts.c')
-rw-r--r-- | gcc/tree-ssa-loop-ivopts.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index 82e45d2db4d..e89ee0e4ce8 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -5510,6 +5510,7 @@ rewrite_use_address (struct ivopts_data *data, { aff_tree aff; gimple_stmt_iterator bsi = gsi_for_stmt (use->stmt); + tree base_hint = NULL_TREE; tree ref; bool ok; @@ -5517,7 +5518,22 @@ rewrite_use_address (struct ivopts_data *data, gcc_assert (ok); unshare_aff_combination (&aff); - ref = create_mem_ref (&bsi, TREE_TYPE (*use->op_p), &aff, data->speed); + /* To avoid undefined overflow problems, all IV candidates use unsigned + integer types. The drawback is that this makes it impossible for + create_mem_ref to distinguish an IV that is based on a memory object + from one that represents simply an offset. + + To work around this problem, we pass a hint to create_mem_ref that + indicates which variable (if any) in aff is an IV based on a memory + object. Note that we only consider the candidate. If this is not + based on an object, the base of the reference is in some subexpression + of the use -- but these will use pointer types, so they are recognized + by the create_mem_ref heuristics anyway. */ + if (cand->iv->base_object) + base_hint = var_at_stmt (data->current_loop, cand, use->stmt); + + ref = create_mem_ref (&bsi, TREE_TYPE (*use->op_p), &aff, base_hint, + data->speed); copy_ref_info (ref, *use->op_p); *use->op_p = ref; } |