Commit 880a1451 by Xinliang David Li Committed by Xinliang David Li

Fix to expose more LIM when creating mem_ref

From-SVN: r162616
parent 6fb58a37
2010-07-27 Xinliang David Li <davidxl@google.com>
* tree-flow.h (create_mem_ref): Add one new parameter.
* tree-ssa-address.c (create_mem_ref): New parameter.
(addr_to_parts): Ditto.
(move_variant_to_index): New function.
* tree-ssa-loop-ivopts.c (rewrite_use_address): Pass new argument.
2010-07-27 Bernd Schmidt <bernds@codesourcery.com> 2010-07-27 Bernd Schmidt <bernds@codesourcery.com>
* rtl.def (DEBUG_INSN, INSN, JUMP_INSN, CALL_INSN, NOTE): Swap operands * rtl.def (DEBUG_INSN, INSN, JUMP_INSN, CALL_INSN, NOTE): Swap operands
......
...@@ -832,8 +832,8 @@ struct mem_address ...@@ -832,8 +832,8 @@ struct mem_address
}; };
struct affine_tree_combination; struct affine_tree_combination;
tree create_mem_ref (gimple_stmt_iterator *, tree, tree, tree create_mem_ref (gimple_stmt_iterator *, tree,
struct affine_tree_combination *, tree, bool); struct affine_tree_combination *, tree, tree, tree, bool);
rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool); rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
void get_address_description (tree, struct mem_address *); void get_address_description (tree, struct mem_address *);
tree maybe_fold_tmr (tree); tree maybe_fold_tmr (tree);
......
...@@ -470,6 +470,31 @@ move_pointer_to_base (struct mem_address *parts, aff_tree *addr) ...@@ -470,6 +470,31 @@ move_pointer_to_base (struct mem_address *parts, aff_tree *addr)
aff_combination_remove_elt (addr, i); aff_combination_remove_elt (addr, i);
} }
/* Moves the loop variant part V in linear address ADDR to be the index
of PARTS. */
static void
move_variant_to_index (struct mem_address *parts, aff_tree *addr, tree v)
{
unsigned i;
tree val = NULL_TREE;
gcc_assert (!parts->index);
for (i = 0; i < addr->n; i++)
{
val = addr->elts[i].val;
if (operand_equal_p (val, v, 0))
break;
}
if (i == addr->n)
return;
parts->index = fold_convert (sizetype, val);
parts->step = double_int_to_tree (sizetype, addr->elts[i].coef);
aff_combination_remove_elt (addr, i);
}
/* Adds ELT to PARTS. */ /* Adds ELT to PARTS. */
static void static void
...@@ -573,7 +598,8 @@ most_expensive_mult_to_index (tree type, struct mem_address *parts, ...@@ -573,7 +598,8 @@ most_expensive_mult_to_index (tree type, struct mem_address *parts,
/* Splits address ADDR for a memory access of type TYPE into PARTS. /* Splits address ADDR for a memory access of type TYPE into PARTS.
If BASE_HINT is non-NULL, it specifies an SSA name to be used If BASE_HINT is non-NULL, it specifies an SSA name to be used
preferentially as base of the reference. preferentially as base of the reference, and IV_CAND is the selected
iv candidate used in ADDR.
TODO -- be more clever about the distribution of the elements of ADDR TODO -- be more clever about the distribution of the elements of ADDR
to PARTS. Some architectures do not support anything but single to PARTS. Some architectures do not support anything but single
...@@ -583,8 +609,9 @@ most_expensive_mult_to_index (tree type, struct mem_address *parts, ...@@ -583,8 +609,9 @@ most_expensive_mult_to_index (tree type, struct mem_address *parts,
addressing modes is useless. */ addressing modes is useless. */
static void static void
addr_to_parts (tree type, aff_tree *addr, tree base_hint, addr_to_parts (tree type, aff_tree *addr, tree iv_cand,
struct mem_address *parts, bool speed) tree base_hint, struct mem_address *parts,
bool speed)
{ {
tree part; tree part;
unsigned i; unsigned i;
...@@ -602,9 +629,17 @@ addr_to_parts (tree type, aff_tree *addr, tree base_hint, ...@@ -602,9 +629,17 @@ addr_to_parts (tree type, aff_tree *addr, tree base_hint,
/* Try to find a symbol. */ /* Try to find a symbol. */
move_fixed_address_to_symbol (parts, addr); move_fixed_address_to_symbol (parts, addr);
/* No need to do address parts reassociation if the number of parts
is <= 2 -- in that case, no loop invariant code motion can be
exposed. */
if (!base_hint && (addr->n > 2))
move_variant_to_index (parts, addr, iv_cand);
/* First move the most expensive feasible multiplication /* First move the most expensive feasible multiplication
to index. */ to index. */
most_expensive_mult_to_index (type, parts, addr, speed); if (!parts->index)
most_expensive_mult_to_index (type, parts, addr, speed);
/* Try to find a base of the reference. Since at the moment /* Try to find a base of the reference. Since at the moment
there is no reliable way how to distinguish between pointer and its there is no reliable way how to distinguish between pointer and its
...@@ -644,17 +679,19 @@ gimplify_mem_ref_parts (gimple_stmt_iterator *gsi, struct mem_address *parts) ...@@ -644,17 +679,19 @@ gimplify_mem_ref_parts (gimple_stmt_iterator *gsi, struct mem_address *parts)
/* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary /* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary
computations are emitted in front of GSI. TYPE is the mode computations are emitted in front of GSI. TYPE is the mode
of created memory reference. */ of created memory reference. IV_CAND is the selected iv candidate in ADDR,
and BASE_HINT is non NULL if IV_CAND comes from a base address
object. */
tree tree
create_mem_ref (gimple_stmt_iterator *gsi, tree type, tree alias_ptr_type, create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
aff_tree *addr, tree base_hint, bool speed) tree alias_ptr_type, tree iv_cand, tree base_hint, bool speed)
{ {
tree mem_ref, tmp; tree mem_ref, tmp;
tree atype; tree atype;
struct mem_address parts; struct mem_address parts;
addr_to_parts (type, addr, base_hint, &parts, speed); addr_to_parts (type, addr, iv_cand, base_hint, &parts, speed);
gimplify_mem_ref_parts (gsi, &parts); gimplify_mem_ref_parts (gsi, &parts);
mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts); mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts);
if (mem_ref) if (mem_ref)
......
...@@ -5745,7 +5745,7 @@ rewrite_use_address (struct ivopts_data *data, ...@@ -5745,7 +5745,7 @@ rewrite_use_address (struct ivopts_data *data,
aff_tree aff; aff_tree aff;
gimple_stmt_iterator bsi = gsi_for_stmt (use->stmt); gimple_stmt_iterator bsi = gsi_for_stmt (use->stmt);
tree base_hint = NULL_TREE; tree base_hint = NULL_TREE;
tree ref; tree ref, iv;
bool ok; bool ok;
adjust_iv_update_pos (cand, use); adjust_iv_update_pos (cand, use);
...@@ -5767,9 +5767,10 @@ rewrite_use_address (struct ivopts_data *data, ...@@ -5767,9 +5767,10 @@ rewrite_use_address (struct ivopts_data *data,
if (cand->iv->base_object) if (cand->iv->base_object)
base_hint = var_at_stmt (data->current_loop, cand, use->stmt); base_hint = var_at_stmt (data->current_loop, cand, use->stmt);
ref = create_mem_ref (&bsi, TREE_TYPE (*use->op_p), iv = var_at_stmt (data->current_loop, cand, use->stmt);
ref = create_mem_ref (&bsi, TREE_TYPE (*use->op_p), &aff,
reference_alias_ptr_type (*use->op_p), reference_alias_ptr_type (*use->op_p),
&aff, base_hint, data->speed); iv, base_hint, data->speed);
copy_ref_info (ref, *use->op_p); copy_ref_info (ref, *use->op_p);
*use->op_p = ref; *use->op_p = ref;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment