mirror of git://gcc.gnu.org/git/gcc.git
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>
|
2008-03-27 Paolo Bonzini <bonzini@gnu.org>
|
||||||
|
|
||||||
* config.cc (m68hc11, m6811, m68hc12, m6812): Add usegas.h,
|
* 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>
|
2008-03-27 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
* gcc.dg/fold-addr-1.c: New testcase.
|
* gcc.dg/fold-addr-1.c: New testcase.
|
||||||
|
|
|
@ -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" } } */
|
|
@ -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;
|
unsigned in_progress : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Similar to tree_to_aff_combination, but follows SSA name definitions
|
/* Expands SSA names in COMB recursively. CACHE is used to cache the
|
||||||
and expands them recursively. CACHE is used to cache the expansions
|
results. */
|
||||||
of the ssa names, to avoid exponential time complexity for cases
|
|
||||||
like
|
|
||||||
|
|
||||||
a1 = a0 + a0;
|
|
||||||
a2 = a1 + a1;
|
|
||||||
a3 = a2 + a2;
|
|
||||||
... */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
tree_to_aff_combination_expand (tree expr, tree type, aff_tree *comb,
|
aff_combination_expand (aff_tree *comb, struct pointer_map_t **cache)
|
||||||
struct pointer_map_t **cache)
|
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
aff_tree to_add, current, curre;
|
aff_tree to_add, current, curre;
|
||||||
|
@ -583,8 +575,7 @@ tree_to_aff_combination_expand (tree expr, tree type, aff_tree *comb,
|
||||||
void **slot;
|
void **slot;
|
||||||
struct name_expansion *exp;
|
struct name_expansion *exp;
|
||||||
|
|
||||||
tree_to_aff_combination (expr, type, comb);
|
aff_combination_zero (&to_add, comb->type);
|
||||||
aff_combination_zero (&to_add, type);
|
|
||||||
for (i = 0; i < comb->n; i++)
|
for (i = 0; i < comb->n; i++)
|
||||||
{
|
{
|
||||||
e = comb->elts[i].val;
|
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 = XNEW (struct name_expansion);
|
||||||
exp->in_progress = 1;
|
exp->in_progress = 1;
|
||||||
*slot = exp;
|
*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->expansion = current;
|
||||||
exp->in_progress = 0;
|
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
|
COMB while traversing it; include the term -coef * E, to remove
|
||||||
it from COMB. */
|
it from COMB. */
|
||||||
scale = comb->elts[i].coef;
|
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_add_elt (&curre, e, double_int_neg (scale));
|
||||||
aff_combination_scale (¤t, scale);
|
aff_combination_scale (¤t, scale);
|
||||||
aff_combination_add (&to_add, ¤t);
|
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);
|
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
|
/* Frees memory occupied by struct name_expansion in *VALUE. Callback for
|
||||||
pointer_map_traverse. */
|
pointer_map_traverse. */
|
||||||
|
|
||||||
|
@ -783,3 +792,36 @@ debug_aff (aff_tree *val)
|
||||||
print_aff (stderr, val);
|
print_aff (stderr, val);
|
||||||
fprintf (stderr, "\n");
|
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 *);
|
tree aff_combination_to_tree (aff_tree *);
|
||||||
void unshare_aff_combination (aff_tree *);
|
void unshare_aff_combination (aff_tree *);
|
||||||
bool aff_combination_constant_multiple_p (aff_tree *, aff_tree *, double_int *);
|
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 *,
|
void tree_to_aff_combination_expand (tree, tree, aff_tree *,
|
||||||
struct pointer_map_t **);
|
struct pointer_map_t **);
|
||||||
|
void get_inner_reference_aff (tree, aff_tree *, double_int *);
|
||||||
void free_affine_expand_cache (struct pointer_map_t **);
|
void free_affine_expand_cache (struct pointer_map_t **);
|
||||||
|
|
||||||
/* Debugging functions. */
|
/* 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))
|
for (phi = phi_nodes (exit->dest); phi; phi = PHI_CHAIN (phi))
|
||||||
{
|
{
|
||||||
struct reduction_info *red;
|
struct reduction_info *red;
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue