tree-ssa-loop-im.c (struct mem_ref): Use bitmap_head instead of bitmap.
2013-03-25 Richard Biener <rguenther@suse.de> * tree-ssa-loop-im.c (struct mem_ref): Use bitmap_head instead of bitmap. (memory_references): Likewise. (outermost_indep_loop, mem_ref_alloc, mark_ref_stored, gather_mem_refs_stmt, record_dep_loop, ref_indep_loop_p_1, ref_indep_loop_p_2, find_refs_for_sm): Adjust. (gather_mem_refs_in_loops): Fold into ... (analyze_memory_references): ... this. Move initialization to tree_ssa_lim_initialize. (fill_always_executed_in): Rename to ... (fill_always_executed_in_1): ... this. (fill_always_executed_in): Move contains_call computation to this new function from ... (tree_ssa_lim_initialize): ... here. (tree_ssa_lim): Call fill_always_executed_in. From-SVN: r197038
This commit is contained in:
parent
5789594736
commit
374001cbee
@ -1,3 +1,21 @@
|
||||
2013-03-25 Richard Biener <rguenther@suse.de>
|
||||
|
||||
* tree-ssa-loop-im.c (struct mem_ref): Use bitmap_head instead
|
||||
of bitmap.
|
||||
(memory_references): Likewise.
|
||||
(outermost_indep_loop, mem_ref_alloc, mark_ref_stored,
|
||||
gather_mem_refs_stmt, record_dep_loop, ref_indep_loop_p_1,
|
||||
ref_indep_loop_p_2, find_refs_for_sm): Adjust.
|
||||
(gather_mem_refs_in_loops): Fold into ...
|
||||
(analyze_memory_references): ... this. Move initialization
|
||||
to tree_ssa_lim_initialize.
|
||||
(fill_always_executed_in): Rename to ...
|
||||
(fill_always_executed_in_1): ... this.
|
||||
(fill_always_executed_in): Move contains_call computation to
|
||||
this new function from ...
|
||||
(tree_ssa_lim_initialize): ... here.
|
||||
(tree_ssa_lim): Call fill_always_executed_in.
|
||||
|
||||
2013-03-25 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* postreload.c (reload_combine): Fix code detecting returns.
|
||||
|
@ -108,7 +108,7 @@ typedef struct mem_ref
|
||||
query meta-data. */
|
||||
ao_ref mem;
|
||||
|
||||
bitmap stored; /* The set of loops in that this memory location
|
||||
bitmap_head stored; /* The set of loops in that this memory location
|
||||
is stored to. */
|
||||
vec<vec<mem_ref_loc> > accesses_in_loop;
|
||||
/* The locations of the accesses. Vector
|
||||
@ -117,14 +117,14 @@ typedef struct mem_ref
|
||||
/* The following sets are computed on demand. We keep both set and
|
||||
its complement, so that we know whether the information was
|
||||
already computed or not. */
|
||||
bitmap indep_loop; /* The set of loops in that the memory
|
||||
bitmap_head indep_loop; /* The set of loops in that the memory
|
||||
reference is independent, meaning:
|
||||
If it is stored in the loop, this store
|
||||
is independent on all other loads and
|
||||
stores.
|
||||
If it is only loaded, then it is independent
|
||||
on all stores in the loop. */
|
||||
bitmap dep_loop; /* The complement of INDEP_LOOP. */
|
||||
bitmap_head dep_loop; /* The complement of INDEP_LOOP. */
|
||||
} *mem_ref_p;
|
||||
|
||||
/* We use two bits per loop in the ref->{in,}dep_loop bitmaps, the first
|
||||
@ -146,13 +146,13 @@ static struct
|
||||
vec<mem_ref_p> refs_list;
|
||||
|
||||
/* The set of memory references accessed in each loop. */
|
||||
vec<bitmap> refs_in_loop;
|
||||
vec<bitmap_head> refs_in_loop;
|
||||
|
||||
/* The set of memory references stored in each loop. */
|
||||
vec<bitmap> refs_stored_in_loop;
|
||||
vec<bitmap_head> refs_stored_in_loop;
|
||||
|
||||
/* The set of memory references stored in each loop, including subloops . */
|
||||
vec<bitmap> all_refs_stored_in_loop;
|
||||
vec<bitmap_head> all_refs_stored_in_loop;
|
||||
|
||||
/* Cache for expanding memory addresses. */
|
||||
struct pointer_map_t *ttae_cache;
|
||||
@ -584,13 +584,13 @@ outermost_indep_loop (struct loop *outer, struct loop *loop, mem_ref_p ref)
|
||||
{
|
||||
struct loop *aloop;
|
||||
|
||||
if (bitmap_bit_p (ref->stored, loop->num))
|
||||
if (bitmap_bit_p (&ref->stored, loop->num))
|
||||
return NULL;
|
||||
|
||||
for (aloop = outer;
|
||||
aloop != loop;
|
||||
aloop = superloop_at_depth (loop, loop_depth (aloop) + 1))
|
||||
if (!bitmap_bit_p (ref->stored, aloop->num)
|
||||
if (!bitmap_bit_p (&ref->stored, aloop->num)
|
||||
&& ref_indep_loop_p (aloop, ref))
|
||||
return aloop;
|
||||
|
||||
@ -1457,9 +1457,9 @@ mem_ref_alloc (tree mem, unsigned hash, unsigned id)
|
||||
ao_ref_init (&ref->mem, mem);
|
||||
ref->id = id;
|
||||
ref->hash = hash;
|
||||
ref->stored = BITMAP_ALLOC (&lim_bitmap_obstack);
|
||||
ref->indep_loop = BITMAP_ALLOC (&lim_bitmap_obstack);
|
||||
ref->dep_loop = BITMAP_ALLOC (&lim_bitmap_obstack);
|
||||
bitmap_initialize (&ref->stored, &lim_bitmap_obstack);
|
||||
bitmap_initialize (&ref->indep_loop, &lim_bitmap_obstack);
|
||||
bitmap_initialize (&ref->dep_loop, &lim_bitmap_obstack);
|
||||
ref->accesses_in_loop.create (0);
|
||||
|
||||
return ref;
|
||||
@ -1487,11 +1487,9 @@ record_mem_ref_loc (mem_ref_p ref, struct loop *loop, gimple stmt, tree *loc)
|
||||
static void
|
||||
mark_ref_stored (mem_ref_p ref, struct loop *loop)
|
||||
{
|
||||
for (;
|
||||
loop != current_loops->tree_root
|
||||
&& !bitmap_bit_p (ref->stored, loop->num);
|
||||
loop = loop_outer (loop))
|
||||
bitmap_set_bit (ref->stored, loop->num);
|
||||
while (loop != current_loops->tree_root
|
||||
&& bitmap_set_bit (&ref->stored, loop->num))
|
||||
loop = loop_outer (loop);
|
||||
}
|
||||
|
||||
/* Gathers memory references in statement STMT in LOOP, storing the
|
||||
@ -1552,10 +1550,10 @@ gather_mem_refs_stmt (struct loop *loop, gimple stmt)
|
||||
|
||||
record_mem_ref_loc (ref, loop, stmt, mem);
|
||||
}
|
||||
bitmap_set_bit (memory_accesses.refs_in_loop[loop->num], ref->id);
|
||||
bitmap_set_bit (&memory_accesses.refs_in_loop[loop->num], ref->id);
|
||||
if (is_stored)
|
||||
{
|
||||
bitmap_set_bit (memory_accesses.refs_stored_in_loop[loop->num], ref->id);
|
||||
bitmap_set_bit (&memory_accesses.refs_stored_in_loop[loop->num], ref->id);
|
||||
mark_ref_stored (ref, loop);
|
||||
}
|
||||
return;
|
||||
@ -1580,7 +1578,7 @@ sort_bbs_in_loop_postorder_cmp (const void *bb1_, const void *bb2_)
|
||||
/* Gathers memory references in loops. */
|
||||
|
||||
static void
|
||||
gather_mem_refs_in_loops (void)
|
||||
analyze_memory_references (void)
|
||||
{
|
||||
gimple_stmt_iterator bsi;
|
||||
basic_block bb, *bbs;
|
||||
@ -1621,8 +1619,8 @@ gather_mem_refs_in_loops (void)
|
||||
FOR_EACH_LOOP (li, loop, LI_FROM_INNERMOST)
|
||||
{
|
||||
/* Finalize the overall touched references (including subloops). */
|
||||
bitmap_ior_into (memory_accesses.all_refs_stored_in_loop[loop->num],
|
||||
memory_accesses.refs_stored_in_loop[loop->num]);
|
||||
bitmap_ior_into (&memory_accesses.all_refs_stored_in_loop[loop->num],
|
||||
&memory_accesses.refs_stored_in_loop[loop->num]);
|
||||
|
||||
/* Propagate the information about accessed memory references up
|
||||
the loop hierarchy. */
|
||||
@ -1630,44 +1628,11 @@ gather_mem_refs_in_loops (void)
|
||||
if (outer == current_loops->tree_root)
|
||||
continue;
|
||||
|
||||
bitmap_ior_into (memory_accesses.all_refs_stored_in_loop[outer->num],
|
||||
memory_accesses.all_refs_stored_in_loop[loop->num]);
|
||||
bitmap_ior_into (&memory_accesses.all_refs_stored_in_loop[outer->num],
|
||||
&memory_accesses.all_refs_stored_in_loop[loop->num]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Gathers information about memory accesses in the loops. */
|
||||
|
||||
static void
|
||||
analyze_memory_references (void)
|
||||
{
|
||||
unsigned i;
|
||||
bitmap empty;
|
||||
|
||||
memory_accesses.refs = htab_create (100, memref_hash, memref_eq, NULL);
|
||||
memory_accesses.refs_list.create (100);
|
||||
/* Allocate a special, unanalyzable mem-ref with ID zero. */
|
||||
memory_accesses.refs_list.quick_push
|
||||
(mem_ref_alloc (error_mark_node, 0, UNANALYZABLE_MEM_ID));
|
||||
|
||||
memory_accesses.refs_in_loop.create (number_of_loops ());
|
||||
memory_accesses.refs_stored_in_loop.create (number_of_loops ());
|
||||
memory_accesses.all_refs_stored_in_loop.create (number_of_loops ());
|
||||
|
||||
for (i = 0; i < number_of_loops (); i++)
|
||||
{
|
||||
empty = BITMAP_ALLOC (&lim_bitmap_obstack);
|
||||
memory_accesses.refs_in_loop.quick_push (empty);
|
||||
empty = BITMAP_ALLOC (&lim_bitmap_obstack);
|
||||
memory_accesses.refs_stored_in_loop.quick_push (empty);
|
||||
empty = BITMAP_ALLOC (&lim_bitmap_obstack);
|
||||
memory_accesses.all_refs_stored_in_loop.quick_push (empty);
|
||||
}
|
||||
|
||||
memory_accesses.ttae_cache = NULL;
|
||||
|
||||
gather_mem_refs_in_loops ();
|
||||
}
|
||||
|
||||
/* Returns true if MEM1 and MEM2 may alias. TTAE_CACHE is used as a cache in
|
||||
tree_to_aff_combination_expand. */
|
||||
|
||||
@ -2231,7 +2196,7 @@ record_dep_loop (struct loop *loop, mem_ref_p ref, bool stored_p)
|
||||
/* We can propagate dependent-in-loop bits up the loop
|
||||
hierarchy to all outer loops. */
|
||||
while (loop != current_loops->tree_root
|
||||
&& bitmap_set_bit (ref->dep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
|
||||
&& bitmap_set_bit (&ref->dep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
|
||||
loop = loop_outer (loop);
|
||||
}
|
||||
|
||||
@ -2247,9 +2212,9 @@ ref_indep_loop_p_1 (struct loop *loop, mem_ref_p ref, bool stored_p)
|
||||
mem_ref_p aref;
|
||||
|
||||
if (stored_p)
|
||||
refs_to_check = memory_accesses.refs_in_loop[loop->num];
|
||||
refs_to_check = &memory_accesses.refs_in_loop[loop->num];
|
||||
else
|
||||
refs_to_check = memory_accesses.refs_stored_in_loop[loop->num];
|
||||
refs_to_check = &memory_accesses.refs_stored_in_loop[loop->num];
|
||||
|
||||
if (bitmap_bit_p (refs_to_check, UNANALYZABLE_MEM_ID))
|
||||
return false;
|
||||
@ -2270,11 +2235,11 @@ ref_indep_loop_p_1 (struct loop *loop, mem_ref_p ref, bool stored_p)
|
||||
static bool
|
||||
ref_indep_loop_p_2 (struct loop *loop, mem_ref_p ref, bool stored_p)
|
||||
{
|
||||
stored_p |= bitmap_bit_p (ref->stored, loop->num);
|
||||
stored_p |= bitmap_bit_p (&ref->stored, loop->num);
|
||||
|
||||
if (bitmap_bit_p (ref->indep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
|
||||
if (bitmap_bit_p (&ref->indep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
|
||||
return true;
|
||||
if (bitmap_bit_p (ref->dep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
|
||||
if (bitmap_bit_p (&ref->dep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
|
||||
return false;
|
||||
|
||||
struct loop *inner = loop->inner;
|
||||
@ -2294,12 +2259,12 @@ ref_indep_loop_p_2 (struct loop *loop, mem_ref_p ref, bool stored_p)
|
||||
/* Record the computed result in the cache. */
|
||||
if (indep_p)
|
||||
{
|
||||
if (bitmap_set_bit (ref->indep_loop, LOOP_DEP_BIT (loop->num, stored_p))
|
||||
if (bitmap_set_bit (&ref->indep_loop, LOOP_DEP_BIT (loop->num, stored_p))
|
||||
&& stored_p)
|
||||
{
|
||||
/* If it's independend against all refs then it's independent
|
||||
against stores, too. */
|
||||
bitmap_set_bit (ref->indep_loop, LOOP_DEP_BIT (loop->num, false));
|
||||
bitmap_set_bit (&ref->indep_loop, LOOP_DEP_BIT (loop->num, false));
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -2373,7 +2338,7 @@ can_sm_ref_p (struct loop *loop, mem_ref_p ref)
|
||||
static void
|
||||
find_refs_for_sm (struct loop *loop, bitmap sm_executed, bitmap refs_to_sm)
|
||||
{
|
||||
bitmap refs = memory_accesses.all_refs_stored_in_loop[loop->num];
|
||||
bitmap refs = &memory_accesses.all_refs_stored_in_loop[loop->num];
|
||||
unsigned i;
|
||||
bitmap_iterator bi;
|
||||
mem_ref_p ref;
|
||||
@ -2451,7 +2416,7 @@ store_motion (void)
|
||||
blocks that contain a nonpure call. */
|
||||
|
||||
static void
|
||||
fill_always_executed_in (struct loop *loop, sbitmap contains_call)
|
||||
fill_always_executed_in_1 (struct loop *loop, sbitmap contains_call)
|
||||
{
|
||||
basic_block bb = NULL, *bbs, last = NULL;
|
||||
unsigned i;
|
||||
@ -2510,45 +2475,80 @@ fill_always_executed_in (struct loop *loop, sbitmap contains_call)
|
||||
}
|
||||
|
||||
for (loop = loop->inner; loop; loop = loop->next)
|
||||
fill_always_executed_in (loop, contains_call);
|
||||
fill_always_executed_in_1 (loop, contains_call);
|
||||
}
|
||||
|
||||
/* Fills ALWAYS_EXECUTED_IN information for basic blocks, i.e.
|
||||
for each such basic block bb records the outermost loop for that execution
|
||||
of its header implies execution of bb. */
|
||||
|
||||
static void
|
||||
fill_always_executed_in (void)
|
||||
{
|
||||
sbitmap contains_call = sbitmap_alloc (last_basic_block);
|
||||
basic_block bb;
|
||||
struct loop *loop;
|
||||
|
||||
bitmap_clear (contains_call);
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
gimple_stmt_iterator gsi;
|
||||
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
|
||||
{
|
||||
if (nonpure_call_p (gsi_stmt (gsi)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gsi_end_p (gsi))
|
||||
bitmap_set_bit (contains_call, bb->index);
|
||||
}
|
||||
|
||||
for (loop = current_loops->tree_root->inner; loop; loop = loop->next)
|
||||
fill_always_executed_in_1 (loop, contains_call);
|
||||
|
||||
sbitmap_free (contains_call);
|
||||
}
|
||||
|
||||
|
||||
/* Compute the global information needed by the loop invariant motion pass. */
|
||||
|
||||
static void
|
||||
tree_ssa_lim_initialize (void)
|
||||
{
|
||||
sbitmap contains_call = sbitmap_alloc (last_basic_block);
|
||||
gimple_stmt_iterator bsi;
|
||||
struct loop *loop;
|
||||
basic_block bb;
|
||||
unsigned i;
|
||||
|
||||
bitmap_obstack_initialize (&lim_bitmap_obstack);
|
||||
|
||||
bitmap_clear (contains_call);
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi))
|
||||
{
|
||||
if (nonpure_call_p (gsi_stmt (bsi)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!gsi_end_p (bsi))
|
||||
bitmap_set_bit (contains_call, bb->index);
|
||||
}
|
||||
|
||||
for (loop = current_loops->tree_root->inner; loop; loop = loop->next)
|
||||
fill_always_executed_in (loop, contains_call);
|
||||
|
||||
sbitmap_free (contains_call);
|
||||
|
||||
lim_aux_data_map = pointer_map_create ();
|
||||
|
||||
if (flag_tm)
|
||||
compute_transaction_bits ();
|
||||
|
||||
alloc_aux_for_edges (0);
|
||||
|
||||
memory_accesses.refs = htab_create (100, memref_hash, memref_eq, NULL);
|
||||
memory_accesses.refs_list.create (100);
|
||||
/* Allocate a special, unanalyzable mem-ref with ID zero. */
|
||||
memory_accesses.refs_list.quick_push
|
||||
(mem_ref_alloc (error_mark_node, 0, UNANALYZABLE_MEM_ID));
|
||||
|
||||
memory_accesses.refs_in_loop.create (number_of_loops ());
|
||||
memory_accesses.refs_in_loop.quick_grow (number_of_loops ());
|
||||
memory_accesses.refs_stored_in_loop.create (number_of_loops ());
|
||||
memory_accesses.refs_stored_in_loop.quick_grow (number_of_loops ());
|
||||
memory_accesses.all_refs_stored_in_loop.create (number_of_loops ());
|
||||
memory_accesses.all_refs_stored_in_loop.quick_grow (number_of_loops ());
|
||||
|
||||
for (i = 0; i < number_of_loops (); i++)
|
||||
{
|
||||
bitmap_initialize (&memory_accesses.refs_in_loop[i],
|
||||
&lim_bitmap_obstack);
|
||||
bitmap_initialize (&memory_accesses.refs_stored_in_loop[i],
|
||||
&lim_bitmap_obstack);
|
||||
bitmap_initialize (&memory_accesses.all_refs_stored_in_loop[i],
|
||||
&lim_bitmap_obstack);
|
||||
}
|
||||
|
||||
memory_accesses.ttae_cache = NULL;
|
||||
}
|
||||
|
||||
/* Cleans up after the invariant motion pass. */
|
||||
@ -2595,6 +2595,9 @@ tree_ssa_lim (void)
|
||||
/* Gathers information about memory accesses in the loops. */
|
||||
analyze_memory_references ();
|
||||
|
||||
/* Fills ALWAYS_EXECUTED_IN information for basic blocks. */
|
||||
fill_always_executed_in ();
|
||||
|
||||
/* For each statement determine the outermost loop in that it is
|
||||
invariant and cost for computing the invariant. */
|
||||
determine_invariantness ();
|
||||
|
Loading…
Reference in New Issue
Block a user