From: Yuri Rumyantsev Date: Wed, 10 Aug 2016 15:03:02 +0000 (+0000) Subject: re PR middle-end/71734 (FAIL: libgomp.fortran/simd4.f90 -O3 -g execution test) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ff4fa9934e4ebecfdca45f00efa9f523b11f717a;p=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 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index afa402028d7..a0a3698601f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2016-08-10 Yuri Rumyantsev + + 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 PR target/72853 diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index 947724bceff..463db048cb6 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -196,7 +196,7 @@ static struct static bitmap_obstack lim_bitmap_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. */ #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 = superloop_at_depth (loop, loop_depth (aloop) + 1)) 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; - if (ref_indep_loop_p (loop, ref)) + if (ref_indep_loop_p (loop, ref, loop)) return loop; else return NULL; @@ -2109,17 +2109,23 @@ record_dep_loop (struct loop *loop, im_mem_ref *ref, bool stored_p) loop = loop_outer (loop); } -/* Returns true if REF in REF_LOOP is independent on all other memory - references in LOOP. */ +/* Returns true if REF is independent on all other memory + references in LOOP. REF_LOOP is where REF is accessed, SAFELEN is the + safelen to apply. */ static bool -ref_indep_loop_p_1 (int safelen, struct loop *loop, - im_mem_ref *ref, bool stored_p) +ref_indep_loop_p_1 (int safelen, struct loop *loop, im_mem_ref *ref, + 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; - unsigned i; - bitmap_iterator bi; - im_mem_ref *aref; if (stored_p) 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]; if (bitmap_bit_p (refs_to_check, UNANALYZABLE_MEM_ID)) - return false; - - if (safelen > 1) + indep_p = false; + else if (safelen > 1) { 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); fprintf (dump_file, "\n"); } + + /* Avoid caching here as safelen depends on context and refs + are shared between different contexts. */ return true; } - - EXECUTE_IF_SET_IN_BITMAP (refs_to_check, 0, i, bi) + else { - aref = memory_accesses.refs_list[i]; - if (!refs_independent_p (ref, aref)) + 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; - } - - 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_1 (safelen, inner, ref, stored_p, ref_loop)) + { + indep_p = false; + break; + } + inner = inner->next; + } - struct loop *inner = loop->inner; - while (inner) - { - if (!ref_indep_loop_p_2 (safelen, inner, ref, stored_p)) - return false; - 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; + } + } + } } - bool indep_p = ref_indep_loop_p_1 (safelen, loop, ref, stored_p); - if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Querying dependencies of ref %u in loop %d: %s\n", 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 - LOOP. */ + LOOP. REF_LOOP is the loop where REF is accessed. */ 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)); - 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. */ @@ -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 in LOOP. */ - if (!ref_indep_loop_p (loop, ref)) + if (!ref_indep_loop_p (loop, ref, loop)) return false; return true;