diff options
author | Aditya Kumar <aditya.k7@samsung.com> | 2015-12-04 21:36:55 +0000 |
---|---|---|
committer | Sebastian Pop <spop@gcc.gnu.org> | 2015-12-04 21:36:55 +0000 |
commit | 15256e28a5351f788b66e574bf1ad53a23fbdda1 (patch) | |
tree | d513c64fdac4af127f0b0f73928de02267d28fe3 /gcc/graphite-scop-detection.c | |
parent | bdf5848047f719389f64bcd2a6dda081adafa9aa (diff) | |
download | gcc-15256e28a5351f788b66e574bf1ad53a23fbdda1.zip gcc-15256e28a5351f788b66e574bf1ad53a23fbdda1.tar.gz gcc-15256e28a5351f788b66e574bf1ad53a23fbdda1.tar.bz2 |
fix PR68693: Check for loop structure when extending the SCoP
The check for dominance while extending the scop assumed that
multiple successors meant a loop which is not true in case of
conditionals around the loop.
Improved pretty printers for better debugging.
PR tree-optimization/68693
* graphite-scop-detection.c (dot_all_sese): New
(dot_all_scops_1): Renamed to dot_all_sese.
(dot_all_scops): Removed.
(dot_sese): New.
(dot_cfg): New.
(scop_detection::get_nearest_dom_with_single_entry): Check that preds are from different loop levels.
(scop_detection::get_nearest_pdom_with_single_exit): Check that succs are from different loop levels.
(scop_detection::print_sese): Inlined.
(scop_detection::print_edge): New.
(scop_detection::merge_sese): Added dumps.
* graphite.h: Add declarations.
gcc/testsuite/ChangeLog:
* gfortran.dg/graphite/pr68693.f90: New test.
Co-Authored-By: Sebastian Pop <s.pop@samsung.com>
From-SVN: r231309
Diffstat (limited to 'gcc/graphite-scop-detection.c')
-rw-r--r-- | gcc/graphite-scop-detection.c | 153 |
1 files changed, 72 insertions, 81 deletions
diff --git a/gcc/graphite-scop-detection.c b/gcc/graphite-scop-detection.c index 2f4231a..729a5fd 100644 --- a/gcc/graphite-scop-detection.c +++ b/gcc/graphite-scop-detection.c @@ -98,22 +98,16 @@ public: - "()" around the node number denotes the entry or the exit nodes of the SCOP. These are not part of SCoP. */ -static void -dot_all_scops_1 (FILE *file, vec<scop_p> scops) +DEBUG_FUNCTION void +dot_all_sese (FILE *file, vec<sese_l>& scops) { - basic_block bb; - edge e; - edge_iterator ei; - scop_p scop; - const char *color; - int i; - /* Disable debugging while printing graph. */ int tmp_dump_flags = dump_flags; dump_flags = 0; fprintf (file, "digraph all {\n"); + basic_block bb; FOR_ALL_BB_FN (bb, cfun) { int part_of_scop = false; @@ -126,12 +120,15 @@ dot_all_scops_1 (FILE *file, vec<scop_p> scops) fprintf (file, "CELLSPACING=\"0\">\n"); /* Select color for SCoP. */ - FOR_EACH_VEC_ELT (scops, i, scop) + sese_l *region; + int i; + FOR_EACH_VEC_ELT (scops, i, region) { - sese_l region = scop->scop_info->region; - if (bb_in_sese_p (bb, region) || (region.exit->dest == bb) - || (region.entry->dest == bb)) + bool sese_in_region = bb_in_sese_p (bb, *region); + if (sese_in_region || (region->exit->dest == bb) + || (region->entry->dest == bb)) { + const char *color; switch (i % 17) { case 0: /* red */ @@ -192,21 +189,21 @@ dot_all_scops_1 (FILE *file, vec<scop_p> scops) fprintf (file, " <TR><TD WIDTH=\"50\" BGCOLOR=\"%s\">", color); - if (!bb_in_sese_p (bb, region)) + if (!sese_in_region) fprintf (file, " ("); - if (bb == region.entry->dest && bb == region.exit->dest) + if (bb == region->entry->dest && bb == region->exit->dest) fprintf (file, " %d*# ", bb->index); - else if (bb == region.entry->dest) + else if (bb == region->entry->dest) fprintf (file, " %d* ", bb->index); - else if (bb == region.exit->dest) + else if (bb == region->exit->dest) fprintf (file, " %d# ", bb->index); else fprintf (file, " %d ", bb->index); fprintf (file, "{lp_%d}", bb->loop_father->num); - if (!bb_in_sese_p (bb, region)) + if (!sese_in_region) fprintf (file, ")"); fprintf (file, "</TD></TR>\n"); @@ -225,6 +222,8 @@ dot_all_scops_1 (FILE *file, vec<scop_p> scops) FOR_ALL_BB_FN (bb, cfun) { + edge e; + edge_iterator ei; FOR_EACH_EDGE (e, ei, bb->succs) fprintf (file, "%d -> %d;\n", bb->index, e->dest->index); } @@ -235,52 +234,29 @@ dot_all_scops_1 (FILE *file, vec<scop_p> scops) dump_flags = tmp_dump_flags; } -/* Display all SCoPs using dotty. */ - -DEBUG_FUNCTION void -dot_all_scops (vec<scop_p> scops) -{ - /* When debugging, enable the following code. This cannot be used - in production compilers because it calls "system". */ -#if 0 - int x; - FILE *stream = fopen ("/tmp/allscops.dot", "w"); - gcc_assert (stream); - - dot_all_scops_1 (stream, scops); - fclose (stream); - - x = system ("dotty /tmp/allscops.dot &"); -#else - dot_all_scops_1 (stderr, scops); -#endif -} - -/* Display all SCoPs using dotty. */ +/* Display SCoP on stderr. */ DEBUG_FUNCTION void -dot_scop (scop_p scop) +dot_sese (sese_l& scop) { - auto_vec<scop_p, 1> scops; + vec<sese_l> scops; + scops.create (1); if (scop) scops.safe_push (scop); - /* When debugging, enable the following code. This cannot be used - in production compilers because it calls "system". */ -#if 0 - { - int x; - FILE *stream = fopen ("/tmp/allscops.dot", "w"); - gcc_assert (stream); + dot_all_sese (stderr, scops); - dot_all_scops_1 (stream, scops); - fclose (stream); - x = system ("dotty /tmp/allscops.dot &"); - } -#else - dot_all_scops_1 (stderr, scops); -#endif + scops.release (); +} + +DEBUG_FUNCTION void +dot_cfg () +{ + vec<sese_l> scops; + scops.create (1); + dot_all_sese (stderr, scops); + scops.release (); } /* Return true if BB is empty, contains only DEBUG_INSNs. */ @@ -552,9 +528,20 @@ public: static edge get_nearest_pdom_with_single_exit (basic_block dom); - /* Print S to FILE. */ - static void print_sese (FILE *file, sese_l s); + /* Pretty printers. */ + + static void print_edge (FILE *file, const_edge e) + { + fprintf (file, "edge (bb_%d, bb_%d)", e->src->index, e->dest->index); + } + + static void print_sese (FILE *file, sese_l s) + { + fprintf (file, "(entry_"); print_edge (file, s.entry); + fprintf (file, ", exit_"); print_edge (file, s.exit); + fprintf (file, ")\n"); + } /* Merge scops at same loop depth and returns the new sese. Returns a new SESE when merge was successful, INVALID_SESE otherwise. */ @@ -717,9 +704,14 @@ scop_detection::get_nearest_dom_with_single_entry (basic_block dom) { edge e1 = (*dom->preds)[0]; edge e2 = (*dom->preds)[1]; - if (dominated_by_p (CDI_DOMINATORS, e2->src, e1->src)) + loop_p l = dom->loop_father; + loop_p l1 = e1->src->loop_father; + loop_p l2 = e2->src->loop_father; + if (l != l1 + && dominated_by_p (CDI_DOMINATORS, e2->src, e1->src)) return e1; - if (dominated_by_p (CDI_DOMINATORS, e1->src, e2->src)) + if (l != l2 + && dominated_by_p (CDI_DOMINATORS, e1->src, e2->src)) return e2; } @@ -738,39 +730,35 @@ scop_detection::get_nearest_dom_with_single_entry (basic_block dom) back-loop the back-edge is not counted. */ edge -scop_detection::get_nearest_pdom_with_single_exit (basic_block dom) +scop_detection::get_nearest_pdom_with_single_exit (basic_block pdom) { - if (!dom->succs) + if (!pdom->succs) return NULL; - if (dom->succs->length () == 2) + if (pdom->succs->length () == 2) { - edge e1 = (*dom->succs)[0]; - edge e2 = (*dom->succs)[1]; - if (dominated_by_p (CDI_POST_DOMINATORS, e2->dest, e1->dest)) + edge e1 = (*pdom->succs)[0]; + edge e2 = (*pdom->succs)[1]; + loop_p l = pdom->loop_father; + loop_p l1 = e1->dest->loop_father; + loop_p l2 = e2->dest->loop_father; + if (l != l1 + && dominated_by_p (CDI_POST_DOMINATORS, e2->dest, e1->dest)) return e1; - if (dominated_by_p (CDI_POST_DOMINATORS, e1->dest, e2->dest)) + if (l != l2 + && dominated_by_p (CDI_POST_DOMINATORS, e1->dest, e2->dest)) return e2; } - while (dom->succs->length () != 1) + while (pdom->succs->length () != 1) { - if (dom->succs->length () < 1) + if (pdom->succs->length () < 1) return NULL; - dom = get_immediate_dominator (CDI_POST_DOMINATORS, dom); - if (!dom->succs) + pdom = get_immediate_dominator (CDI_POST_DOMINATORS, pdom); + if (!pdom->succs) return NULL; } - return (*dom->succs)[0]; -} - -/* Print S to FILE. */ -void -scop_detection::print_sese (FILE *file, sese_l s) -{ - fprintf (file, "(entry_edge (bb_%d, bb_%d), exit_edge (bb_%d, bb_%d))\n", - s.entry->src->index, s.entry->dest->index, - s.exit->src->index, s.exit->dest->index); + return (*pdom->succs)[0]; } /* Merge scops at same loop depth and returns the new sese. @@ -815,6 +803,9 @@ scop_detection::merge_sese (sese_l first, sese_l second) const sese_l combined (entry, exit); + DEBUG_PRINT (dp << "checking combined sese: "; + print_sese (dump_file, combined)); + /* FIXME: We could iterate to find the dom which dominates pdom, and pdom which post-dominates dom, until it stabilizes. Also, ENTRY->SRC and EXIT->DEST should be in the same loop nest. */ |