summaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-ivopts.c
diff options
context:
space:
mode:
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>2009-11-02 14:30:39 +0000
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>2009-11-02 14:30:39 +0000
commit2451b8b88f07121042f58a4f646cbc045f8630e0 (patch)
treef4baec2a8f727693a22c86047fb07064f6e86319 /gcc/tree-ssa-loop-ivopts.c
parentfe9e92d635d662fe1cd8d03dea9d33a7457fb3d7 (diff)
downloadgcc-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.c18
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;
}