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:
Zdenek Dvorak 2008-03-27 11:25:36 +01:00 committed by Richard Biener
parent a929bc2878
commit 724256083e
8 changed files with 1190 additions and 348 deletions

View File

@ -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,

View File

@ -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.

View 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" } } */

View 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" } } */

View File

@ -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, &current, cache);
tree_to_aff_combination_expand (rhs, comb->type, &current, 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 (&current, scale);
aff_combination_add (&to_add, &current);
@ -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);
}

View File

@ -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. */

View File

@ -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