aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSebastian Pop <sebastian.pop@amd.com>2009-11-25 05:28:05 +0000
committerSebastian Pop <spop@gcc.gnu.org>2009-11-25 05:28:05 +0000
commit7b7f2ca76cec6c22c1b0bd1a6bb31baebddaca99 (patch)
tree52a744653644e7ddc8b4754dda1d5ba9a19b3737 /gcc
parent6119e7d5ec67f6133abc2090697b7e3bf7e65ffc (diff)
downloadgcc-7b7f2ca76cec6c22c1b0bd1a6bb31baebddaca99.zip
gcc-7b7f2ca76cec6c22c1b0bd1a6bb31baebddaca99.tar.gz
gcc-7b7f2ca76cec6c22c1b0bd1a6bb31baebddaca99.tar.bz2
graphite-interchange.c (lst_perfect_nestify): Pass 3 parameters for the loops created by the loop distribution.
2009-11-03 Sebastian Pop <sebastian.pop@amd.com> * graphite-interchange.c (lst_perfect_nestify): Pass 3 parameters for the loops created by the loop distribution. Do not modify the input LSTs. (lst_try_interchange_loops): Same. Use a temporary LST for the transformed schedule. Call lst_update_scattering before data dependence analysis. (lst_try_interchange): Pass an extra parameter INDEX. (lst_do_interchange_1): New. (lst_do_interchange): Call lst_do_interchange_1. (scop_do_interchange): Call lst_update_scattering. * graphite-poly.c (apply_poly_transforms): Do not call lst_update_scattering. * graphite-poly.h (lst_pred): New. (lst_succ): New. (lst_find_first_pbb): Return NULL when not found. (lst_empty_p): New. (lst_insert_in_sequence): Allow LST1 to be NULL. (lst_replace): New. (lst_substitute_3): New. * gcc.dg/graphite/interchange-1.c: XFail. * gcc.dg/graphite/interchange-8.c: XFail. * gcc.dg/graphite/interchange-11.c: XFail. From-SVN: r154632
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog.graphite25
-rw-r--r--gcc/graphite-interchange.c164
-rw-r--r--gcc/graphite-poly.c1
-rw-r--r--gcc/graphite-poly.h118
-rw-r--r--gcc/testsuite/gcc.dg/graphite/interchange-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/graphite/interchange-8.c2
6 files changed, 255 insertions, 57 deletions
diff --git a/gcc/ChangeLog.graphite b/gcc/ChangeLog.graphite
index 2662b61..4565555 100644
--- a/gcc/ChangeLog.graphite
+++ b/gcc/ChangeLog.graphite
@@ -1,3 +1,28 @@
+2009-11-03 Sebastian Pop <sebastian.pop@amd.com>
+
+ * graphite-interchange.c (lst_perfect_nestify): Pass 3 parameters
+ for the loops created by the loop distribution. Do not modify the
+ input LSTs.
+ (lst_try_interchange_loops): Same. Use a temporary LST for the
+ transformed schedule. Call lst_update_scattering before data
+ dependence analysis.
+ (lst_try_interchange): Pass an extra parameter INDEX.
+ (lst_do_interchange_1): New.
+ (lst_do_interchange): Call lst_do_interchange_1.
+ (scop_do_interchange): Call lst_update_scattering.
+ * graphite-poly.c (apply_poly_transforms): Do not call
+ lst_update_scattering.
+ * graphite-poly.h (lst_pred): New.
+ (lst_succ): New.
+ (lst_find_first_pbb): Return NULL when not found.
+ (lst_empty_p): New.
+ (lst_insert_in_sequence): Allow LST1 to be NULL.
+ (lst_replace): New.
+ (lst_substitute_3): New.
+ * gcc.dg/graphite/interchange-1.c: XFail.
+ * gcc.dg/graphite/interchange-8.c: XFail.
+ * gcc.dg/graphite/interchange-11.c: XFail.
+
2009-10-30 Sebastian Pop <sebastian.pop@amd.com>
* graphite-interchange.c (lst_perfectly_nested_p): New.
diff --git a/gcc/graphite-interchange.c b/gcc/graphite-interchange.c
index 6bfa9ab..6ac7fca 100644
--- a/gcc/graphite-interchange.c
+++ b/gcc/graphite-interchange.c
@@ -493,12 +493,14 @@ lst_perfectly_nested_p (lst_p loop1, lst_p loop2)
/* Transform the loop nest between LOOP1 and LOOP2 into a perfect
nest. To continue the naming tradition, this function is called
- after perfect_nestify. */
+ after perfect_nestify. NEST is set to the perfectly nested loop
+ that is created. BEFORE/AFTER are set to the loops distributed
+ before/after the loop NEST. */
static void
-lst_perfect_nestify (lst_p loop1, lst_p loop2)
+lst_perfect_nestify (lst_p loop1, lst_p loop2, lst_p *before,
+ lst_p *nest, lst_p *after)
{
- lst_p before, after;
poly_bb_p first, last;
gcc_assert (loop1 && loop2
@@ -508,40 +510,52 @@ lst_perfect_nestify (lst_p loop1, lst_p loop2)
first = LST_PBB (lst_find_first_pbb (loop2));
last = LST_PBB (lst_find_last_pbb (loop2));
- before = copy_lst (loop1);
- after = copy_lst (loop1);
+ *before = copy_lst (loop1);
+ *nest = copy_lst (loop1);
+ *after = copy_lst (loop1);
- lst_remove_all_before_including_pbb (before, first, false);
- lst_remove_all_before_including_pbb (after, last, true);
+ lst_remove_all_before_including_pbb (*before, first, false);
+ lst_remove_all_before_including_pbb (*after, last, true);
- lst_remove_all_before_excluding_pbb (loop1, first, true);
- lst_remove_all_before_excluding_pbb (loop1, last, false);
-
- lst_insert_in_sequence (before, loop1, true);
- lst_insert_in_sequence (after, loop1, false);
+ lst_remove_all_before_excluding_pbb (*nest, first, true);
+ lst_remove_all_before_excluding_pbb (*nest, last, false);
}
/* Try to interchange LOOP1 with LOOP2 for all the statements of the
body of LOOP2. LOOP1 contains LOOP2. Return true if it did the
- interchange. */
+ interchange. CREATED_LOOP_BEFORE/CREATED_LOOP_AFTER are set to
+ true if the loop distribution created a loop before/after LOOP1. */
static bool
-lst_try_interchange_loops (scop_p scop, lst_p loop1, lst_p loop2)
+lst_try_interchange_loops (scop_p scop, lst_p loop1, lst_p loop2,
+ lst_p *before, lst_p *nest, lst_p *after)
{
int depth1 = lst_depth (loop1);
int depth2 = lst_depth (loop2);
+ lst_p transformed;
+
+ *before = NULL;
+ *after = NULL;
+ *nest = NULL;
if (!lst_interchange_profitable_p (loop2, depth1, depth2))
return false;
- store_lst_schedule (scop);
-
if (!lst_perfectly_nested_p (loop1, loop2))
- lst_perfect_nestify (loop1, loop2);
+ lst_perfect_nestify (loop1, loop2, before, nest, after);
- gcc_assert (lst_perfectly_nested_p (loop1, loop2));
lst_apply_interchange (loop2, depth1, depth2);
+ /* Sync the transformed LST information and the PBB scatterings
+ before using the scatterings in the data dependence analysis. */
+ if (*before || *nest || *after)
+ {
+ transformed = lst_substitute_3 (SCOP_TRANSFORMED_SCHEDULE (scop), loop1,
+ *before, *nest, *after);
+ lst_update_scattering (transformed);
+ free_lst (transformed);
+ }
+
if (graphite_legal_transform (scop))
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -549,65 +563,114 @@ lst_try_interchange_loops (scop_p scop, lst_p loop1, lst_p loop2)
"Loops at depths %d and %d will be interchanged.\n",
depth1, depth2);
+ /* Transform the SCOP_TRANSFORMED_SCHEDULE of the SCOP. */
+ lst_insert_in_sequence (*before, loop1, true);
+ lst_insert_in_sequence (*after, loop1, false);
+
+ if (*nest)
+ {
+ lst_replace (loop1, *nest);
+ free_lst (loop1);
+ }
+
return true;
}
/* Undo the transform. */
lst_apply_interchange (loop2, depth2, depth1);
- restore_lst_schedule (scop);
+ *before = NULL;
+ *after = NULL;
+ *nest = NULL;
return false;
}
+static bool lst_do_interchange_1 (scop_p, lst_p, int *);
+
/* Try to interchange LOOP with all the loops contained in the body of
- LST. Return true if it did interchanged some loops. */
+ LST. Return true if it did interchanged some loops. INDEX points
+ to the next element to be processed by lst_do_interchange. */
static bool
-lst_try_interchange (scop_p scop, lst_p loop, lst_p lst)
+lst_try_interchange (scop_p scop, lst_p loop, lst_p lst, int *index)
{
- if (!lst)
+ int i;
+ lst_p l;
+ lst_p before, nest, after;
+ bool res;
+
+ if (!lst || !LST_LOOP_P (lst))
return false;
- if (LST_LOOP_P (lst))
+ res = lst_try_interchange_loops (scop, loop, lst, &before, &nest, &after);
+
+ if (before)
{
- int i;
- lst_p l;
- bool res = lst_try_interchange_loops (scop, loop, lst);
+ res |= lst_do_interchange_1 (scop, before, index);
+ (*index)++;
+ }
- for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
- res |= lst_try_interchange (scop, loop, l);
+ if (nest)
+ res |= lst_do_interchange_1 (scop, nest, index);
+ else
+ for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
+ res |= lst_try_interchange (scop, loop, l, index);
- return res;
+ if (after)
+ {
+ res |= lst_do_interchange_1 (scop, after, index);
+ (*index)++;
}
- return false;
+ (*index)++;
+ return res;
}
-/* Interchanges all the loops of LST that are considered profitable to
- interchange. Return true if it did interchanged some loops. */
+/* Interchanges all the loops of LOOP that are considered profitable
+ to interchange. Return true if it did interchanged some loops.
+ INDEX points to the next element to be processed by
+ lst_do_interchange. */
static bool
-lst_do_interchange (scop_p scop, lst_p lst)
+lst_do_interchange_1 (scop_p scop, lst_p loop, int *index)
{
- if (!lst)
+ int i;
+ lst_p l;
+ bool res = false;
+
+ if (!loop || !LST_LOOP_P (loop))
return false;
- if (LST_LOOP_P (lst))
- {
- int i;
- lst_p l;
- bool res = false;
+ for (i = 0; VEC_iterate (lst_p, LST_SEQ (loop), i, l); i++)
+ res |= lst_try_interchange (scop, loop, l, index);
+
+ return res;
+}
- if (lst_depth (lst) >= 0)
- for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
- res |= lst_try_interchange (scop, lst, l);
+/* Interchanges all the loops of LOOP and the loops of its body that
+ are considered profitable to interchange. Return true if it did
+ interchanged some loops. INDEX points to the next element to be
+ processed in the LST_SEQ (LOOP) vector. */
- for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
- res |= lst_do_interchange (scop, l);
+static bool
+lst_do_interchange (scop_p scop, lst_p loop, int *index)
+{
+ lst_p l;
+ bool res = false;
- return res;
- }
+ if (!loop || !LST_LOOP_P (loop))
+ return false;
- return false;
+ if (lst_depth (loop) >= 0)
+ res = lst_do_interchange_1 (scop, loop, index);
+
+ while (VEC_iterate (lst_p, LST_SEQ (loop), *index, l))
+ if (LST_LOOP_P (l))
+ res |= lst_do_interchange (scop, l, index);
+ else
+ (*index)++;
+
+ (*index)++;
+ return res;
}
/* Interchanges all the loop depths that are considered profitable for SCOP. */
@@ -615,10 +678,11 @@ lst_do_interchange (scop_p scop, lst_p lst)
bool
scop_do_interchange (scop_p scop)
{
- lst_p lst = copy_lst (SCOP_TRANSFORMED_SCHEDULE (scop));
- bool res = lst_do_interchange (scop, lst);
+ int i = 0;
+ bool res = lst_do_interchange (scop, SCOP_TRANSFORMED_SCHEDULE (scop), &i);
+
+ lst_update_scattering (SCOP_TRANSFORMED_SCHEDULE (scop));
- free_lst (lst);
return res;
}
diff --git a/gcc/graphite-poly.c b/gcc/graphite-poly.c
index f628052..fa949cc 100644
--- a/gcc/graphite-poly.c
+++ b/gcc/graphite-poly.c
@@ -263,7 +263,6 @@ apply_poly_transforms (scop_p scop)
transform_done |= scop_do_interchange (scop);
}
- lst_update_scattering (SCOP_TRANSFORMED_SCHEDULE (scop));
return transform_done;
}
diff --git a/gcc/graphite-poly.h b/gcc/graphite-poly.h
index 6cd46ae..8f25a37 100644
--- a/gcc/graphite-poly.h
+++ b/gcc/graphite-poly.h
@@ -792,6 +792,48 @@ lst_dewey_number_at_depth (lst_p lst, int depth)
return lst_dewey_number_at_depth (LST_LOOP_FATHER (lst), depth);
}
+/* Returns the predecessor of LST in the sequence of its loop father.
+ Returns NULL if LST is the first statement in the sequence. */
+
+static inline lst_p
+lst_pred (lst_p lst)
+{
+ int dewey;
+ lst_p father;
+
+ if (!lst || !LST_LOOP_FATHER (lst))
+ return NULL;
+
+ dewey = lst_dewey_number (lst);
+ if (dewey == 0)
+ return NULL;
+
+ father = LST_LOOP_FATHER (lst);
+ return VEC_index (lst_p, LST_SEQ (father), dewey - 1);
+}
+
+/* Returns the successor of LST in the sequence of its loop father.
+ Returns NULL if there is none. */
+
+static inline lst_p
+lst_succ (lst_p lst)
+{
+ int dewey;
+ lst_p father;
+
+ if (!lst || !LST_LOOP_FATHER (lst))
+ return NULL;
+
+ dewey = lst_dewey_number (lst);
+ father = LST_LOOP_FATHER (lst);
+
+ if (VEC_length (lst_p, LST_SEQ (father)) == (unsigned) dewey + 1)
+ return NULL;
+
+ return VEC_index (lst_p, LST_SEQ (father), dewey + 1);
+}
+
+
/* Return the LST node corresponding to PBB. */
static inline lst_p
@@ -853,10 +895,18 @@ lst_find_first_pbb (lst_p lst)
return res;
}
- gcc_unreachable ();
return NULL;
}
+/* Returns true when LST is a loop that does not contains
+ statements. */
+
+static inline bool
+lst_empty_p (lst_p lst)
+{
+ return !lst_find_first_pbb (lst);
+}
+
/* Return the last lst representing a PBB statement in LST. */
static inline lst_p
@@ -1029,16 +1079,76 @@ lst_update_scattering (lst_p lst)
static inline void
lst_insert_in_sequence (lst_p lst1, lst_p lst2, bool before)
{
- lst_p father = LST_LOOP_FATHER (lst2);
- int dewey = lst_dewey_number (lst2);
+ lst_p father;
+ int dewey;
+
+ /* Do not insert empty loops. */
+ if (!lst1 || lst_empty_p (lst1))
+ return;
+
+ father = LST_LOOP_FATHER (lst2);
+ dewey = lst_dewey_number (lst2);
- gcc_assert (lst1 && lst2 && father && dewey >= 0);
+ gcc_assert (lst2 && father && dewey >= 0);
VEC_safe_insert (lst_p, heap, LST_SEQ (father), before ? dewey : dewey + 1,
lst1);
LST_LOOP_FATHER (lst1) = father;
}
+/* Replaces LST1 with LST2. */
+
+static inline void
+lst_replace (lst_p lst1, lst_p lst2)
+{
+ lst_p father;
+ int dewey;
+
+ if (!lst2 || lst_empty_p (lst2))
+ return;
+
+ father = LST_LOOP_FATHER (lst1);
+ dewey = lst_dewey_number (lst1);
+ LST_LOOP_FATHER (lst2) = father;
+ VEC_replace (lst_p, LST_SEQ (father), dewey, lst2);
+}
+
+/* Returns a copy of ROOT where LST has been replaced by a copy of the
+ LSTs A B C in this sequence. */
+
+static inline lst_p
+lst_substitute_3 (lst_p root, lst_p lst, lst_p a, lst_p b, lst_p c)
+{
+ int i;
+ lst_p l;
+ VEC (lst_p, heap) *seq;
+
+ if (!root)
+ return NULL;
+
+ gcc_assert (lst && root != lst);
+
+ if (!LST_LOOP_P (root))
+ return new_lst_stmt (LST_PBB (root));
+
+ seq = VEC_alloc (lst_p, heap, 5);
+
+ for (i = 0; VEC_iterate (lst_p, LST_SEQ (root), i, l); i++)
+ if (l != lst)
+ VEC_safe_push (lst_p, heap, seq, lst_substitute_3 (l, lst, a, b, c));
+ else
+ {
+ if (!lst_empty_p (a))
+ VEC_safe_push (lst_p, heap, seq, copy_lst (a));
+ if (!lst_empty_p (b))
+ VEC_safe_push (lst_p, heap, seq, copy_lst (b));
+ if (!lst_empty_p (c))
+ VEC_safe_push (lst_p, heap, seq, copy_lst (c));
+ }
+
+ return new_lst_loop (seq);
+}
+
/* Moves LST before LOOP if BEFORE is true, and after the LOOP if
BEFORE is false. */
diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-1.c b/gcc/testsuite/gcc.dg/graphite/interchange-1.c
index 09ce4ea..cd9197d 100644
--- a/gcc/testsuite/gcc.dg/graphite/interchange-1.c
+++ b/gcc/testsuite/gcc.dg/graphite/interchange-1.c
@@ -18,5 +18,5 @@ int foo(int N, int *res)
*res = sum + N;
}
-/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "graphite" } } */
diff --git a/gcc/testsuite/gcc.dg/graphite/interchange-8.c b/gcc/testsuite/gcc.dg/graphite/interchange-8.c
index f002cc1..24b9a15 100644
--- a/gcc/testsuite/gcc.dg/graphite/interchange-8.c
+++ b/gcc/testsuite/gcc.dg/graphite/interchange-8.c
@@ -41,5 +41,5 @@ foo (void)
}
/* Loops K and L should be interchanged. */
-/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" } } */
+/* { dg-final { scan-tree-dump-times "will be interchanged" 1 "graphite" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "graphite" } } */