mirror of git://gcc.gnu.org/git/gcc.git
re PR middle-end/71734 (FAIL: libgomp.fortran/simd4.f90 -O3 -g execution test)
Fix PR tree-optimization/71734 2016-08-10 Yuri Rumyantsev <ysrumyan@gmail.com> PR tree-optimization/71734 * tree-ssa-loop-im.c (ref_indep_loop_p): Add new argument REF_LOOP, invoke ref_indep_loop_p_1. (outermost_indep_loop): Pass LOOP argumnet where REF was defined to ref_indep_loop_p. (ref_indep_loop_p_1): Fix commentary, add argument REF_LOOP, combine it with ref_indep_lopp_p_2, update SAFELEN if only REF is inside LOOP, do not cache dpendence value for loops with non-zero SAFELEN. (ref_indep_loop_p_2): Delete function. (can_sm_ref_p): Pass LOOP as additional argument to ref_indep_loop_p. From-SVN: r239326
This commit is contained in:
parent
a0883b0800
commit
ff4fa9934e
|
|
@ -1,3 +1,18 @@
|
||||||
|
2016-08-10 Yuri Rumyantsev <ysrumyan@gmail.com>
|
||||||
|
|
||||||
|
PR tree-optimization/71734
|
||||||
|
* tree-ssa-loop-im.c (ref_indep_loop_p): Add new argument
|
||||||
|
REF_LOOP, invoke ref_indep_loop_p_1.
|
||||||
|
(outermost_indep_loop): Pass LOOP argumnet where REF was defined
|
||||||
|
to ref_indep_loop_p.
|
||||||
|
(ref_indep_loop_p_1): Fix commentary, add argument REF_LOOP,
|
||||||
|
combine it with ref_indep_lopp_p_2, update SAFELEN if only REF
|
||||||
|
is inside LOOP, do not cache dpendence value for loops with
|
||||||
|
non-zero SAFELEN.
|
||||||
|
(ref_indep_loop_p_2): Delete function.
|
||||||
|
(can_sm_ref_p): Pass LOOP as additional argument to
|
||||||
|
ref_indep_loop_p.
|
||||||
|
|
||||||
2016-08-10 Michael Meissner <meissner@linux.vnet.ibm.com>
|
2016-08-10 Michael Meissner <meissner@linux.vnet.ibm.com>
|
||||||
|
|
||||||
PR target/72853
|
PR target/72853
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,7 @@ static struct
|
||||||
static bitmap_obstack lim_bitmap_obstack;
|
static bitmap_obstack lim_bitmap_obstack;
|
||||||
static obstack mem_ref_obstack;
|
static obstack mem_ref_obstack;
|
||||||
|
|
||||||
static bool ref_indep_loop_p (struct loop *, im_mem_ref *);
|
static bool ref_indep_loop_p (struct loop *, im_mem_ref *, struct loop *);
|
||||||
|
|
||||||
/* Minimum cost of an expensive expression. */
|
/* Minimum cost of an expensive expression. */
|
||||||
#define LIM_EXPENSIVE ((unsigned) PARAM_VALUE (PARAM_LIM_EXPENSIVE))
|
#define LIM_EXPENSIVE ((unsigned) PARAM_VALUE (PARAM_LIM_EXPENSIVE))
|
||||||
|
|
@ -544,10 +544,10 @@ outermost_indep_loop (struct loop *outer, struct loop *loop, im_mem_ref *ref)
|
||||||
aloop != loop;
|
aloop != loop;
|
||||||
aloop = superloop_at_depth (loop, loop_depth (aloop) + 1))
|
aloop = superloop_at_depth (loop, loop_depth (aloop) + 1))
|
||||||
if ((!ref->stored || !bitmap_bit_p (ref->stored, aloop->num))
|
if ((!ref->stored || !bitmap_bit_p (ref->stored, aloop->num))
|
||||||
&& ref_indep_loop_p (aloop, ref))
|
&& ref_indep_loop_p (aloop, ref, loop))
|
||||||
return aloop;
|
return aloop;
|
||||||
|
|
||||||
if (ref_indep_loop_p (loop, ref))
|
if (ref_indep_loop_p (loop, ref, loop))
|
||||||
return loop;
|
return loop;
|
||||||
else
|
else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -2109,17 +2109,23 @@ record_dep_loop (struct loop *loop, im_mem_ref *ref, bool stored_p)
|
||||||
loop = loop_outer (loop);
|
loop = loop_outer (loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if REF in REF_LOOP is independent on all other memory
|
/* Returns true if REF is independent on all other memory
|
||||||
references in LOOP. */
|
references in LOOP. REF_LOOP is where REF is accessed, SAFELEN is the
|
||||||
|
safelen to apply. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ref_indep_loop_p_1 (int safelen, struct loop *loop,
|
ref_indep_loop_p_1 (int safelen, struct loop *loop, im_mem_ref *ref,
|
||||||
im_mem_ref *ref, bool stored_p)
|
bool stored_p, struct loop *ref_loop)
|
||||||
{
|
{
|
||||||
|
stored_p |= (ref->stored && bitmap_bit_p (ref->stored, loop->num));
|
||||||
|
|
||||||
|
if (loop->safelen > safelen
|
||||||
|
/* Check that REF is accessed inside LOOP. */
|
||||||
|
&& (loop == ref_loop || flow_loop_nested_p (loop, ref_loop)))
|
||||||
|
safelen = loop->safelen;
|
||||||
|
|
||||||
|
bool indep_p = true;
|
||||||
bitmap refs_to_check;
|
bitmap refs_to_check;
|
||||||
unsigned i;
|
|
||||||
bitmap_iterator bi;
|
|
||||||
im_mem_ref *aref;
|
|
||||||
|
|
||||||
if (stored_p)
|
if (stored_p)
|
||||||
refs_to_check = &memory_accesses.refs_in_loop[loop->num];
|
refs_to_check = &memory_accesses.refs_in_loop[loop->num];
|
||||||
|
|
@ -2127,9 +2133,8 @@ ref_indep_loop_p_1 (int safelen, struct loop *loop,
|
||||||
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))
|
if (bitmap_bit_p (refs_to_check, UNANALYZABLE_MEM_ID))
|
||||||
return false;
|
indep_p = false;
|
||||||
|
else if (safelen > 1)
|
||||||
if (safelen > 1)
|
|
||||||
{
|
{
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
{
|
{
|
||||||
|
|
@ -2138,47 +2143,45 @@ ref_indep_loop_p_1 (int safelen, struct loop *loop,
|
||||||
print_generic_expr (dump_file, ref->mem.ref, TDF_SLIM);
|
print_generic_expr (dump_file, ref->mem.ref, TDF_SLIM);
|
||||||
fprintf (dump_file, "\n");
|
fprintf (dump_file, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Avoid caching here as safelen depends on context and refs
|
||||||
|
are shared between different contexts. */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
EXECUTE_IF_SET_IN_BITMAP (refs_to_check, 0, i, bi)
|
|
||||||
{
|
{
|
||||||
aref = memory_accesses.refs_list[i];
|
if (bitmap_bit_p (&ref->indep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
|
||||||
if (!refs_independent_p (ref, aref))
|
return true;
|
||||||
|
if (bitmap_bit_p (&ref->dep_loop, LOOP_DEP_BIT (loop->num, stored_p)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
struct loop *inner = loop->inner;
|
||||||
|
while (inner)
|
||||||
|
{
|
||||||
|
if (!ref_indep_loop_p_1 (safelen, inner, ref, stored_p, ref_loop))
|
||||||
|
{
|
||||||
|
indep_p = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
inner = inner->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (indep_p)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
bitmap_iterator bi;
|
||||||
|
EXECUTE_IF_SET_IN_BITMAP (refs_to_check, 0, i, bi)
|
||||||
|
{
|
||||||
|
im_mem_ref *aref = memory_accesses.refs_list[i];
|
||||||
|
if (!refs_independent_p (ref, aref))
|
||||||
|
{
|
||||||
|
indep_p = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Returns true if REF in REF_LOOP is independent on all other memory
|
|
||||||
references in LOOP. Wrapper over ref_indep_loop_p_1, caching its
|
|
||||||
results. */
|
|
||||||
|
|
||||||
static bool
|
|
||||||
ref_indep_loop_p_2 (int safelen, struct loop *loop,
|
|
||||||
im_mem_ref *ref, bool stored_p)
|
|
||||||
{
|
|
||||||
stored_p |= (ref->stored && bitmap_bit_p (ref->stored, loop->num));
|
|
||||||
|
|
||||||
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)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (loop->safelen > safelen)
|
|
||||||
safelen = loop->safelen;
|
|
||||||
|
|
||||||
struct loop *inner = loop->inner;
|
|
||||||
while (inner)
|
|
||||||
{
|
|
||||||
if (!ref_indep_loop_p_2 (safelen, inner, ref, stored_p))
|
|
||||||
return false;
|
|
||||||
inner = inner->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool indep_p = ref_indep_loop_p_1 (safelen, loop, ref, stored_p);
|
|
||||||
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
fprintf (dump_file, "Querying dependencies of ref %u in loop %d: %s\n",
|
fprintf (dump_file, "Querying dependencies of ref %u in loop %d: %s\n",
|
||||||
ref->id, loop->num, indep_p ? "independent" : "dependent");
|
ref->id, loop->num, indep_p ? "independent" : "dependent");
|
||||||
|
|
@ -2209,14 +2212,14 @@ ref_indep_loop_p_2 (int safelen, struct loop *loop,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if REF is independent on all other memory references in
|
/* Returns true if REF is independent on all other memory references in
|
||||||
LOOP. */
|
LOOP. REF_LOOP is the loop where REF is accessed. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
ref_indep_loop_p (struct loop *loop, im_mem_ref *ref)
|
ref_indep_loop_p (struct loop *loop, im_mem_ref *ref, struct loop *ref_loop)
|
||||||
{
|
{
|
||||||
gcc_checking_assert (MEM_ANALYZABLE (ref));
|
gcc_checking_assert (MEM_ANALYZABLE (ref));
|
||||||
|
|
||||||
return ref_indep_loop_p_2 (0, loop, ref, false);
|
return ref_indep_loop_p_1 (0, loop, ref, false, ref_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns true if we can perform store motion of REF from LOOP. */
|
/* Returns true if we can perform store motion of REF from LOOP. */
|
||||||
|
|
@ -2252,7 +2255,7 @@ can_sm_ref_p (struct loop *loop, im_mem_ref *ref)
|
||||||
|
|
||||||
/* And it must be independent on all other memory references
|
/* And it must be independent on all other memory references
|
||||||
in LOOP. */
|
in LOOP. */
|
||||||
if (!ref_indep_loop_p (loop, ref))
|
if (!ref_indep_loop_p (loop, ref, loop))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue