tree-affine.h (aff_combination_expand): Declare.
2008-03-27 Zdenek Dvorak <ook@ucw.cz> * tree-affine.h (aff_combination_expand): Declare. (get_inner_reference_aff): Likewise. * tree-affine.c (aff_combination_expand): Split out from tree_to_aff_combination_expand. (get_inner_reference_aff): New function. * tree-parloops.c (loop_parallel_p): Free vectorizer info. * tree-ssa-loop-im.c: Include tree-affine.h and pointer-set.h. (struct lim_aux_data): sm_done field removed. (mem_ref_loc_p, mem_ref_locs_p): New types. (struct mem_ref): Added id, stored, accesses_in_loop, indep_loop, dep_loop, indep_ref, dep_ref fields. Removed is_stored, locs and next fields. (memory_accesses): New variable. (movement_possibility): Do not allow moving statements that store to memory. (outermost_indep_loop, simple_mem_ref_in_stmt, mem_ref_in_stmt): New functions. (determine_max_movement): For statements with memory references, find the outermost loop in that the reference is independent. (move_computations_stmt): Mark the virtual operands for renaming. (memref_free, mem_ref_alloc, mem_ref_locs_alloc, mark_ref_stored, gather_mem_refs_stmt, gather_mem_refs_in_loops, vtoe_hash, vtoe_eq, vtoe_free, record_vop_access, get_vop_accesses, get_vop_stores, add_vop_ref_mapping, create_vop_ref_mapping_loop, create_vop_ref_mapping, analyze_memory_references, cannot_overlap_p, mem_refs_may_alias_p, rewrite_mem_ref_loc, get_all_locs_in_loop, ref_always_accessed_p, refs_independent_p, record_indep_loop, ref_indep_loop_p_1, ref_indep_loop_p, can_sm_ref_p, find_refs_for_sm, store_motion_loop, store_motion): New functions. (struct vop_to_refs_elt): New type. (record_mem_ref_loc, free_mem_ref_locs, rewrite_mem_refs, memref_hash, memref_eq, hoist_memory_references): Rewritten. (schedule_sm): Replaced by... (execute_sm): ... this. (determine_lsm_ref, hoist_memory_references, loop_suitable_for_sm, gather_mem_refs_stmt, gather_mem_refs, find_more_ref_vops, free_mem_ref, free_mem_refs, determine_lsm_loop, determine_lsm): Removed. (tree_ssa_lim_finalize): Free data structures used by store motion. (tree_ssa_lim): Call analyze_memory_references. Use store_motion instead of determine_lsm. * gcc.dg/tree-ssa/loop-32.c: New testcase. * gcc.dg/tree-ssa/loop-33.c: Likewise. From-SVN: r133637
This commit is contained in:
parent
a929bc2878
commit
724256083e
@ -1,3 +1,50 @@
|
||||
2008-03-27 Zdenek Dvorak <ook@ucw.cz>
|
||||
|
||||
* tree-affine.h (aff_combination_expand): Declare.
|
||||
(get_inner_reference_aff): Likewise.
|
||||
* tree-affine.c (aff_combination_expand): Split out from
|
||||
tree_to_aff_combination_expand.
|
||||
(get_inner_reference_aff): New function.
|
||||
* tree-parloops.c (loop_parallel_p): Free vectorizer info.
|
||||
* tree-ssa-loop-im.c: Include tree-affine.h and pointer-set.h.
|
||||
(struct lim_aux_data): sm_done field removed.
|
||||
(mem_ref_loc_p, mem_ref_locs_p): New types.
|
||||
(struct mem_ref): Added id, stored, accesses_in_loop,
|
||||
indep_loop, dep_loop, indep_ref, dep_ref fields.
|
||||
Removed is_stored, locs and next fields.
|
||||
(memory_accesses): New variable.
|
||||
(movement_possibility): Do not allow moving statements
|
||||
that store to memory.
|
||||
(outermost_indep_loop, simple_mem_ref_in_stmt, mem_ref_in_stmt):
|
||||
New functions.
|
||||
(determine_max_movement): For statements with memory references,
|
||||
find the outermost loop in that the reference is independent.
|
||||
(move_computations_stmt): Mark the virtual operands for
|
||||
renaming.
|
||||
(memref_free, mem_ref_alloc, mem_ref_locs_alloc, mark_ref_stored,
|
||||
gather_mem_refs_stmt, gather_mem_refs_in_loops, vtoe_hash, vtoe_eq,
|
||||
vtoe_free, record_vop_access, get_vop_accesses, get_vop_stores,
|
||||
add_vop_ref_mapping, create_vop_ref_mapping_loop,
|
||||
create_vop_ref_mapping, analyze_memory_references,
|
||||
cannot_overlap_p, mem_refs_may_alias_p, rewrite_mem_ref_loc,
|
||||
get_all_locs_in_loop, ref_always_accessed_p,
|
||||
refs_independent_p, record_indep_loop, ref_indep_loop_p_1,
|
||||
ref_indep_loop_p, can_sm_ref_p, find_refs_for_sm,
|
||||
store_motion_loop, store_motion): New functions.
|
||||
(struct vop_to_refs_elt): New type.
|
||||
(record_mem_ref_loc, free_mem_ref_locs, rewrite_mem_refs,
|
||||
memref_hash, memref_eq, hoist_memory_references): Rewritten.
|
||||
(schedule_sm): Replaced by...
|
||||
(execute_sm): ... this.
|
||||
(determine_lsm_ref, hoist_memory_references,
|
||||
loop_suitable_for_sm, gather_mem_refs_stmt, gather_mem_refs,
|
||||
find_more_ref_vops, free_mem_ref, free_mem_refs,
|
||||
determine_lsm_loop, determine_lsm): Removed.
|
||||
(tree_ssa_lim_finalize): Free data structures used by store
|
||||
motion.
|
||||
(tree_ssa_lim): Call analyze_memory_references. Use
|
||||
store_motion instead of determine_lsm.
|
||||
|
||||
2008-03-27 Paolo Bonzini <bonzini@gnu.org>
|
||||
|
||||
* config.cc (m68hc11, m6811, m68hc12, m6812): Add usegas.h,
|
||||
|
@ -1,3 +1,8 @@
|
||||
2008-03-27 Zdenek Dvorak <ook@ucw.cz>
|
||||
|
||||
* gcc.dg/tree-ssa/loop-32.c: New testcase.
|
||||
* gcc.dg/tree-ssa/loop-33.c: Likewise.
|
||||
|
||||
2008-03-27 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
* gcc.dg/fold-addr-1.c: New testcase.
|
||||
|
46
gcc/testsuite/gcc.dg/tree-ssa/loop-32.c
Normal file
46
gcc/testsuite/gcc.dg/tree-ssa/loop-32.c
Normal file
@ -0,0 +1,46 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-lim-details" } */
|
||||
|
||||
int x;
|
||||
int a[100];
|
||||
|
||||
struct a
|
||||
{
|
||||
int X;
|
||||
int Y;
|
||||
};
|
||||
|
||||
void bla(void);
|
||||
|
||||
void test1(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* We should perform store motion here. */
|
||||
for (x = 0; x < 100; x++)
|
||||
a[x] = x;
|
||||
}
|
||||
|
||||
void test2(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* But not here. */
|
||||
for (x = 0; x < 100; x++)
|
||||
bla ();
|
||||
}
|
||||
|
||||
void test3(struct a *A)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* But we should here (using base + offset analysis). */
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
A[5].X += i;
|
||||
A[5].Y += i;
|
||||
}
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "Executing store motion of" 3 "lim" } } */
|
||||
/* { dg-final { cleanup-tree-dump "lim" } } */
|
40
gcc/testsuite/gcc.dg/tree-ssa/loop-33.c
Normal file
40
gcc/testsuite/gcc.dg/tree-ssa/loop-33.c
Normal file
@ -0,0 +1,40 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -fdump-tree-lim-details" } */
|
||||
|
||||
int x;
|
||||
int a[100];
|
||||
|
||||
struct a
|
||||
{
|
||||
int X;
|
||||
int Y;
|
||||
};
|
||||
|
||||
struct a arr[100];
|
||||
|
||||
void test4(unsigned b)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* And here. */
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
arr[b+8].X += i;
|
||||
arr[b+9].X += i;
|
||||
}
|
||||
}
|
||||
|
||||
void test5(struct a *A, unsigned b)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* And here as well. */
|
||||
for (i = 0; i < 100; i++)
|
||||
{
|
||||
A[b].X += i;
|
||||
A[b+1].Y += i;
|
||||
}
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "Executing store motion of" 4 "lim" { xfail lp64 } } } */
|
||||
/* { dg-final { cleanup-tree-dump "lim" } } */
|
@ -562,19 +562,11 @@ struct name_expansion
|
||||
unsigned in_progress : 1;
|
||||
};
|
||||
|
||||
/* Similar to tree_to_aff_combination, but follows SSA name definitions
|
||||
and expands them recursively. CACHE is used to cache the expansions
|
||||
of the ssa names, to avoid exponential time complexity for cases
|
||||
like
|
||||
|
||||
a1 = a0 + a0;
|
||||
a2 = a1 + a1;
|
||||
a3 = a2 + a2;
|
||||
... */
|
||||
/* Expands SSA names in COMB recursively. CACHE is used to cache the
|
||||
results. */
|
||||
|
||||
void
|
||||
tree_to_aff_combination_expand (tree expr, tree type, aff_tree *comb,
|
||||
struct pointer_map_t **cache)
|
||||
aff_combination_expand (aff_tree *comb, struct pointer_map_t **cache)
|
||||
{
|
||||
unsigned i;
|
||||
aff_tree to_add, current, curre;
|
||||
@ -583,8 +575,7 @@ tree_to_aff_combination_expand (tree expr, tree type, aff_tree *comb,
|
||||
void **slot;
|
||||
struct name_expansion *exp;
|
||||
|
||||
tree_to_aff_combination (expr, type, comb);
|
||||
aff_combination_zero (&to_add, type);
|
||||
aff_combination_zero (&to_add, comb->type);
|
||||
for (i = 0; i < comb->n; i++)
|
||||
{
|
||||
e = comb->elts[i].val;
|
||||
@ -616,7 +607,7 @@ tree_to_aff_combination_expand (tree expr, tree type, aff_tree *comb,
|
||||
exp = XNEW (struct name_expansion);
|
||||
exp->in_progress = 1;
|
||||
*slot = exp;
|
||||
tree_to_aff_combination_expand (rhs, type, ¤t, cache);
|
||||
tree_to_aff_combination_expand (rhs, comb->type, ¤t, cache);
|
||||
exp->expansion = current;
|
||||
exp->in_progress = 0;
|
||||
}
|
||||
@ -632,7 +623,7 @@ tree_to_aff_combination_expand (tree expr, tree type, aff_tree *comb,
|
||||
COMB while traversing it; include the term -coef * E, to remove
|
||||
it from COMB. */
|
||||
scale = comb->elts[i].coef;
|
||||
aff_combination_zero (&curre, type);
|
||||
aff_combination_zero (&curre, comb->type);
|
||||
aff_combination_add_elt (&curre, e, double_int_neg (scale));
|
||||
aff_combination_scale (¤t, scale);
|
||||
aff_combination_add (&to_add, ¤t);
|
||||
@ -641,6 +632,24 @@ tree_to_aff_combination_expand (tree expr, tree type, aff_tree *comb,
|
||||
aff_combination_add (comb, &to_add);
|
||||
}
|
||||
|
||||
/* Similar to tree_to_aff_combination, but follows SSA name definitions
|
||||
and expands them recursively. CACHE is used to cache the expansions
|
||||
of the ssa names, to avoid exponential time complexity for cases
|
||||
like
|
||||
|
||||
a1 = a0 + a0;
|
||||
a2 = a1 + a1;
|
||||
a3 = a2 + a2;
|
||||
... */
|
||||
|
||||
void
|
||||
tree_to_aff_combination_expand (tree expr, tree type, aff_tree *comb,
|
||||
struct pointer_map_t **cache)
|
||||
{
|
||||
tree_to_aff_combination (expr, type, comb);
|
||||
aff_combination_expand (comb, cache);
|
||||
}
|
||||
|
||||
/* Frees memory occupied by struct name_expansion in *VALUE. Callback for
|
||||
pointer_map_traverse. */
|
||||
|
||||
@ -783,3 +792,36 @@ debug_aff (aff_tree *val)
|
||||
print_aff (stderr, val);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
|
||||
/* Returns address of the reference REF in ADDR. The size of the accessed
|
||||
location is stored to SIZE. */
|
||||
|
||||
void
|
||||
get_inner_reference_aff (tree ref, aff_tree *addr, double_int *size)
|
||||
{
|
||||
HOST_WIDE_INT bitsize, bitpos;
|
||||
tree toff;
|
||||
enum machine_mode mode;
|
||||
int uns, vol;
|
||||
aff_tree tmp;
|
||||
tree base = get_inner_reference (ref, &bitsize, &bitpos, &toff, &mode,
|
||||
&uns, &vol, false);
|
||||
tree base_addr = build_fold_addr_expr (base);
|
||||
|
||||
/* ADDR = &BASE + TOFF + BITPOS / BITS_PER_UNIT. */
|
||||
|
||||
tree_to_aff_combination (base_addr, sizetype, addr);
|
||||
|
||||
if (toff)
|
||||
{
|
||||
tree_to_aff_combination (toff, sizetype, &tmp);
|
||||
aff_combination_add (addr, &tmp);
|
||||
}
|
||||
|
||||
aff_combination_const (&tmp, sizetype,
|
||||
shwi_to_double_int (bitpos / BITS_PER_UNIT));
|
||||
aff_combination_add (addr, &tmp);
|
||||
|
||||
*size = shwi_to_double_int ((bitsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
|
||||
}
|
||||
|
||||
|
@ -71,8 +71,10 @@ void tree_to_aff_combination (tree, tree, aff_tree *);
|
||||
tree aff_combination_to_tree (aff_tree *);
|
||||
void unshare_aff_combination (aff_tree *);
|
||||
bool aff_combination_constant_multiple_p (aff_tree *, aff_tree *, double_int *);
|
||||
void aff_combination_expand (aff_tree *, struct pointer_map_t **);
|
||||
void tree_to_aff_combination_expand (tree, tree, aff_tree *,
|
||||
struct pointer_map_t **);
|
||||
void get_inner_reference_aff (tree, aff_tree *, double_int *);
|
||||
void free_affine_expand_cache (struct pointer_map_t **);
|
||||
|
||||
/* Debugging functions. */
|
||||
|
@ -317,6 +317,9 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list, struct tree_niter_des
|
||||
}
|
||||
}
|
||||
|
||||
/* Get rid of the information created by the vectorizer functions. */
|
||||
destroy_loop_vec_info (simple_loop_info, true);
|
||||
|
||||
for (phi = phi_nodes (exit->dest); phi; phi = PHI_CHAIN (phi))
|
||||
{
|
||||
struct reduction_info *red;
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user