Fix to expose more LIM when creating mem_ref
From-SVN: r162616
This commit is contained in:
parent
6fb58a378d
commit
880a145176
4 changed files with 58 additions and 13 deletions
|
@ -1,3 +1,10 @@
|
|||
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>
|
||||
|
||||
* rtl.def (DEBUG_INSN, INSN, JUMP_INSN, CALL_INSN, NOTE): Swap operands
|
||||
|
|
|
@ -832,8 +832,8 @@ struct mem_address
|
|||
};
|
||||
|
||||
struct affine_tree_combination;
|
||||
tree create_mem_ref (gimple_stmt_iterator *, tree, tree,
|
||||
struct affine_tree_combination *, tree, bool);
|
||||
tree create_mem_ref (gimple_stmt_iterator *, tree,
|
||||
struct affine_tree_combination *, tree, tree, tree, bool);
|
||||
rtx addr_for_mem_ref (struct mem_address *, addr_space_t, bool);
|
||||
void get_address_description (tree, struct mem_address *);
|
||||
tree maybe_fold_tmr (tree);
|
||||
|
|
|
@ -470,6 +470,31 @@ move_pointer_to_base (struct mem_address *parts, aff_tree *addr)
|
|||
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. */
|
||||
|
||||
static void
|
||||
|
@ -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.
|
||||
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
|
||||
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,
|
|||
addressing modes is useless. */
|
||||
|
||||
static void
|
||||
addr_to_parts (tree type, aff_tree *addr, tree base_hint,
|
||||
struct mem_address *parts, bool speed)
|
||||
addr_to_parts (tree type, aff_tree *addr, tree iv_cand,
|
||||
tree base_hint, struct mem_address *parts,
|
||||
bool speed)
|
||||
{
|
||||
tree part;
|
||||
unsigned i;
|
||||
|
@ -602,9 +629,17 @@ addr_to_parts (tree type, aff_tree *addr, tree base_hint,
|
|||
/* Try to find a symbol. */
|
||||
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
|
||||
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
|
||||
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)
|
|||
|
||||
/* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary
|
||||
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
|
||||
create_mem_ref (gimple_stmt_iterator *gsi, tree type, tree alias_ptr_type,
|
||||
aff_tree *addr, tree base_hint, bool speed)
|
||||
create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr,
|
||||
tree alias_ptr_type, tree iv_cand, tree base_hint, bool speed)
|
||||
{
|
||||
tree mem_ref, tmp;
|
||||
tree atype;
|
||||
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);
|
||||
mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts);
|
||||
if (mem_ref)
|
||||
|
|
|
@ -5745,7 +5745,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;
|
||||
tree ref, iv;
|
||||
bool ok;
|
||||
|
||||
adjust_iv_update_pos (cand, use);
|
||||
|
@ -5767,9 +5767,10 @@ rewrite_use_address (struct ivopts_data *data,
|
|||
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),
|
||||
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),
|
||||
&aff, base_hint, data->speed);
|
||||
iv, base_hint, data->speed);
|
||||
copy_ref_info (ref, *use->op_p);
|
||||
*use->op_p = ref;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue