Commit 6119e7d5 by Sebastian Pop Committed by Sebastian Pop

graphite-interchange.c (lst_perfectly_nested_p): New.

2009-10-30  Sebastian Pop  <sebastian.pop@amd.com>

	* graphite-interchange.c (lst_perfectly_nested_p): New.
	(lst_perfect_nestify): New.
	(lst_try_interchange_loops): Call store_lst_schedule,
	lst_perfectly_nested_p, lst_perfect_nestify and restore_lst_schedule.
	(scop_do_interchange): Avoid redundant legality test.
	Call lst_do_interchange on a copy of SCOP_TRANSFORMED_SCHEDULE.
	* graphite-poly.c (apply_poly_transforms): Call lst_update_scattering.
	* graphite-poly.h (psct_static_dim): New.
	(lst_dewey_number_at_depth): New.
	(lst_find_pbb): Restructured.
	(lst_find_first_pbb): Restructured.
	(lst_find_last_pbb): New.
	(lst_contains_p): New.
	(lst_contains_pbb): New.
	(lst_create_nest): New.
	(lst_remove_from_sequence): New.
	(pbb_update_scattering): New.
	(lst_update_scattering_under): New.
	(lst_update_scattering_seq): New.
	(lst_update_scattering): New.
	(lst_insert_in_sequence): New.
	(lst_distribute_lst): New.
	(lst_remove_all_before_including_pbb): New.
	(lst_remove_all_before_excluding_pbb): New.

From-SVN: r154631
parent 431f3f22
2009-10-30 Sebastian Pop <sebastian.pop@amd.com> 2009-10-30 Sebastian Pop <sebastian.pop@amd.com>
* graphite-interchange.c (lst_perfectly_nested_p): New.
(lst_perfect_nestify): New.
(lst_try_interchange_loops): Call store_lst_schedule,
lst_perfectly_nested_p, lst_perfect_nestify and restore_lst_schedule.
(scop_do_interchange): Avoid redundant legality test.
Call lst_do_interchange on a copy of SCOP_TRANSFORMED_SCHEDULE.
* graphite-poly.c (apply_poly_transforms): Call lst_update_scattering.
* graphite-poly.h (psct_static_dim): New.
(lst_dewey_number_at_depth): New.
(lst_find_pbb): Restructured.
(lst_find_first_pbb): Restructured.
(lst_find_last_pbb): New.
(lst_contains_p): New.
(lst_contains_pbb): New.
(lst_create_nest): New.
(lst_remove_from_sequence): New.
(pbb_update_scattering): New.
(lst_update_scattering_under): New.
(lst_update_scattering_seq): New.
(lst_update_scattering): New.
(lst_insert_in_sequence): New.
(lst_distribute_lst): New.
(lst_remove_all_before_including_pbb): New.
(lst_remove_all_before_excluding_pbb): New.
2009-10-30 Sebastian Pop <sebastian.pop@amd.com>
* tree-ssa-loop-niter.c (finite_loop_p): Do not call twice * tree-ssa-loop-niter.c (finite_loop_p): Do not call twice
get_loop_exit_edges. get_loop_exit_edges.
......
...@@ -475,6 +475,51 @@ lst_interchange_profitable_p (lst_p lst, int depth1, int depth2) ...@@ -475,6 +475,51 @@ lst_interchange_profitable_p (lst_p lst, int depth1, int depth2)
return pbb_interchange_profitable_p (depth1, depth2, LST_PBB (lst)); return pbb_interchange_profitable_p (depth1, depth2, LST_PBB (lst));
} }
/* Return true when the nest starting at LOOP1 and ending on LOOP2 is
perfect: i.e. there are no sequence of statements. */
static bool
lst_perfectly_nested_p (lst_p loop1, lst_p loop2)
{
if (loop1 == loop2)
return true;
if (!LST_LOOP_P (loop1))
return false;
return VEC_length (lst_p, LST_SEQ (loop1)) == 1
&& lst_perfectly_nested_p (VEC_index (lst_p, LST_SEQ (loop1), 0), 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. */
static void
lst_perfect_nestify (lst_p loop1, lst_p loop2)
{
lst_p before, after;
poly_bb_p first, last;
gcc_assert (loop1 && loop2
&& loop1 != loop2
&& LST_LOOP_P (loop1) && LST_LOOP_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);
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);
}
/* Try to interchange LOOP1 with LOOP2 for all the statements of the /* Try to interchange LOOP1 with LOOP2 for all the statements of the
body of LOOP2. LOOP1 contains LOOP2. Return true if it did the body of LOOP2. LOOP1 contains LOOP2. Return true if it did the
...@@ -489,6 +534,12 @@ lst_try_interchange_loops (scop_p scop, lst_p loop1, lst_p loop2) ...@@ -489,6 +534,12 @@ lst_try_interchange_loops (scop_p scop, lst_p loop1, lst_p loop2)
if (!lst_interchange_profitable_p (loop2, depth1, depth2)) if (!lst_interchange_profitable_p (loop2, depth1, depth2))
return false; return false;
store_lst_schedule (scop);
if (!lst_perfectly_nested_p (loop1, loop2))
lst_perfect_nestify (loop1, loop2);
gcc_assert (lst_perfectly_nested_p (loop1, loop2));
lst_apply_interchange (loop2, depth1, depth2); lst_apply_interchange (loop2, depth1, depth2);
if (graphite_legal_transform (scop)) if (graphite_legal_transform (scop))
...@@ -503,6 +554,7 @@ lst_try_interchange_loops (scop_p scop, lst_p loop1, lst_p loop2) ...@@ -503,6 +554,7 @@ lst_try_interchange_loops (scop_p scop, lst_p loop1, lst_p loop2)
/* Undo the transform. */ /* Undo the transform. */
lst_apply_interchange (loop2, depth2, depth1); lst_apply_interchange (loop2, depth2, depth1);
restore_lst_schedule (scop);
return false; return false;
} }
...@@ -563,22 +615,11 @@ lst_do_interchange (scop_p scop, lst_p lst) ...@@ -563,22 +615,11 @@ lst_do_interchange (scop_p scop, lst_p lst)
bool bool
scop_do_interchange (scop_p scop) scop_do_interchange (scop_p scop)
{ {
bool transform_done = false; lst_p lst = copy_lst (SCOP_TRANSFORMED_SCHEDULE (scop));
bool res = lst_do_interchange (scop, lst);
store_scattering (scop);
transform_done = lst_do_interchange (scop, SCOP_TRANSFORMED_SCHEDULE (scop)); free_lst (lst);
return res;
if (!transform_done)
return false;
if (!graphite_legal_transform (scop))
{
restore_scattering (scop);
return false;
}
return transform_done;
} }
......
...@@ -263,6 +263,7 @@ apply_poly_transforms (scop_p scop) ...@@ -263,6 +263,7 @@ apply_poly_transforms (scop_p scop)
transform_done |= scop_do_interchange (scop); transform_done |= scop_do_interchange (scop);
} }
lst_update_scattering (SCOP_TRANSFORMED_SCHEDULE (scop));
return transform_done; return transform_done;
} }
......
...@@ -575,8 +575,19 @@ psct_parameter_dim (poly_bb_p pbb, graphite_dim_t param) ...@@ -575,8 +575,19 @@ psct_parameter_dim (poly_bb_p pbb, graphite_dim_t param)
static inline ppl_dimension_type static inline ppl_dimension_type
psct_dynamic_dim (poly_bb_p pbb, graphite_dim_t level) psct_dynamic_dim (poly_bb_p pbb, graphite_dim_t level)
{ {
graphite_dim_t result; graphite_dim_t result = 1 + 2 * level;
result = 1 + 2 * level;
gcc_assert (result < pbb_nb_scattering_transform (pbb));
return result;
}
/* The scattering dimension of PBB corresponding to the static
sequence of the loop level LEVEL. */
static inline ppl_dimension_type
psct_static_dim (poly_bb_p pbb, graphite_dim_t level)
{
graphite_dim_t result = 2 * level;
gcc_assert (result < pbb_nb_scattering_transform (pbb)); gcc_assert (result < pbb_nb_scattering_transform (pbb));
return result; return result;
...@@ -768,6 +779,19 @@ lst_dewey_number (lst_p lst) ...@@ -768,6 +779,19 @@ lst_dewey_number (lst_p lst)
return -1; return -1;
} }
/* Returns the Dewey number of LST at depth DEPTH. */
static inline int
lst_dewey_number_at_depth (lst_p lst, int depth)
{
gcc_assert (lst && depth >= 0 && lst_depth (lst) <= depth);
if (lst_depth (lst) == depth)
return lst_dewey_number (lst);
return lst_dewey_number_at_depth (LST_LOOP_FATHER (lst), depth);
}
/* Return the LST node corresponding to PBB. */ /* Return the LST node corresponding to PBB. */
static inline lst_p static inline lst_p
...@@ -779,15 +803,15 @@ lst_find_pbb (lst_p lst, poly_bb_p pbb) ...@@ -779,15 +803,15 @@ lst_find_pbb (lst_p lst, poly_bb_p pbb)
if (!lst) if (!lst)
return NULL; return NULL;
if (LST_LOOP_P (lst)) if (!LST_LOOP_P (lst))
for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++) return (pbb == LST_PBB (lst)) ? lst : NULL;
{
lst_p res = lst_find_pbb (l, pbb); for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
if (res) {
return res; lst_p res = lst_find_pbb (l, pbb);
} if (res)
else if (pbb == LST_PBB (lst)) return res;
return lst; }
return NULL; return NULL;
} }
...@@ -808,7 +832,7 @@ find_lst_loop (lst_p stmt, int loop_depth) ...@@ -808,7 +832,7 @@ find_lst_loop (lst_p stmt, int loop_depth)
return loop; return loop;
} }
/* Return the LST node corresponding to PBB. */ /* Return the first lst representing a PBB statement in LST. */
static inline lst_p static inline lst_p
lst_find_first_pbb (lst_p lst) lst_find_first_pbb (lst_p lst)
...@@ -819,15 +843,310 @@ lst_find_first_pbb (lst_p lst) ...@@ -819,15 +843,310 @@ lst_find_first_pbb (lst_p lst)
if (!lst) if (!lst)
return NULL; return NULL;
if (!LST_LOOP_P (lst))
return lst;
for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
{
lst_p res = lst_find_first_pbb (l);
if (res)
return res;
}
gcc_unreachable ();
return NULL;
}
/* Return the last lst representing a PBB statement in LST. */
static inline lst_p
lst_find_last_pbb (lst_p lst)
{
int i;
lst_p l, res = NULL;
if (!lst)
return NULL;
if (!LST_LOOP_P (lst))
return lst;
for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
{
lst_p last = lst_find_last_pbb (l);
if (last)
res = last;
}
gcc_assert (res);
return res;
}
/* Returns true if LOOP contains LST, in other words, if LST is nested
in LOOP. */
static inline bool
lst_contains_p (lst_p loop, lst_p lst)
{
if (!loop || !lst || !LST_LOOP_P (loop))
return false;
if (loop == lst)
return true;
return lst_contains_p (loop, LST_LOOP_FATHER (lst));
}
/* Returns true if LOOP contains PBB, in other words, if PBB is nested
in LOOP. */
static inline bool
lst_contains_pbb (lst_p loop, poly_bb_p pbb)
{
return lst_find_pbb (loop, pbb) ? true : false;
}
/* Creates a loop nest of depth NB_LOOPS containing LST. */
static inline lst_p
lst_create_nest (int nb_loops, lst_p lst)
{
lst_p res, loop;
VEC (lst_p, heap) *seq;
if (nb_loops == 0)
return lst;
seq = VEC_alloc (lst_p, heap, 1);
loop = lst_create_nest (nb_loops - 1, lst);
VEC_quick_push (lst_p, seq, loop);
res = new_lst_loop (seq);
LST_LOOP_FATHER (loop) = res;
return res;
}
/* Removes LST from the sequence of statements of its loop father. */
static inline void
lst_remove_from_sequence (lst_p lst)
{
lst_p father = LST_LOOP_FATHER (lst);
int dewey = lst_dewey_number (lst);
gcc_assert (lst && father && dewey >= 0);
VEC_ordered_remove (lst_p, LST_SEQ (father), dewey);
LST_LOOP_FATHER (lst) = NULL;
}
/* Updates the scattering of PBB to be at the DEWEY number in the loop
at depth LEVEL. */
static inline void
pbb_update_scattering (poly_bb_p pbb, graphite_dim_t level, int dewey)
{
ppl_Polyhedron_t ph = PBB_TRANSFORMED_SCATTERING (pbb);
ppl_dimension_type sched = psct_static_dim (pbb, level);
ppl_dimension_type ds[1];
ppl_Constraint_t new_cstr;
ppl_Linear_Expression_t expr;
ppl_dimension_type dim;
ppl_Polyhedron_space_dimension (ph, &dim);
ds[0] = sched;
ppl_Polyhedron_remove_space_dimensions (ph, ds, 1);
ppl_insert_dimensions (ph, sched, 1);
ppl_new_Linear_Expression_with_dimension (&expr, dim);
ppl_set_coef (expr, sched, -1);
ppl_set_inhomogeneous (expr, dewey);
ppl_new_Constraint (&new_cstr, expr, PPL_CONSTRAINT_TYPE_EQUAL);
ppl_delete_Linear_Expression (expr);
ppl_Polyhedron_add_constraint (ph, new_cstr);
ppl_delete_Constraint (new_cstr);
}
/* Updates the scattering of all the PBBs under LST to be at the DEWEY
number in the loop at depth LEVEL. */
static inline void
lst_update_scattering_under (lst_p lst, int level, int dewey)
{
int i;
lst_p l;
gcc_assert (lst && level >= 0 && dewey >= 0);
if (LST_LOOP_P (lst)) if (LST_LOOP_P (lst))
for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++) for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
lst_update_scattering_under (l, level, dewey);
else
pbb_update_scattering (LST_PBB (lst), level, dewey);
}
/* Updates the scattering of all the PBBs under LST and in sequence
with LST. */
static inline void
lst_update_scattering_seq (lst_p lst)
{
int i;
lst_p l;
lst_p father = LST_LOOP_FATHER (lst);
int dewey = lst_dewey_number (lst);
int level = lst_depth (lst);
gcc_assert (lst && father && dewey >= 0 && level >= 0);
for (i = dewey; VEC_iterate (lst_p, LST_SEQ (father), i, l); i++)
lst_update_scattering_under (l, level, i);
}
/* Updates the all the scattering levels of all the PBBs under
LST. */
static inline void
lst_update_scattering (lst_p lst)
{
int i;
lst_p l;
if (!lst || !LST_LOOP_P (lst))
return;
if (LST_LOOP_FATHER (lst))
lst_update_scattering_seq (lst);
for (i = 0; VEC_iterate (lst_p, LST_SEQ (lst), i, l); i++)
lst_update_scattering (l);
}
/* Inserts LST1 before LST2 if BEFORE is true; inserts LST1 after LST2
if BEFORE is false. */
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);
gcc_assert (lst1 && lst2 && father && dewey >= 0);
VEC_safe_insert (lst_p, heap, LST_SEQ (father), before ? dewey : dewey + 1,
lst1);
LST_LOOP_FATHER (lst1) = father;
}
/* Moves LST before LOOP if BEFORE is true, and after the LOOP if
BEFORE is false. */
static inline void
lst_distribute_lst (lst_p loop, lst_p lst, bool before)
{
int loop_depth = lst_depth (loop);
int depth = lst_depth (lst);
int nb_loops = depth - loop_depth;
gcc_assert (lst && loop && LST_LOOP_P (loop) && nb_loops > 0);
lst_remove_from_sequence (lst);
lst_insert_in_sequence (lst_create_nest (nb_loops, lst), loop, before);
}
/* Removes from LOOP all the statements before/after and including PBB
if BEFORE is true/false. Returns the negation of BEFORE when the
statement PBB has been found. */
static inline bool
lst_remove_all_before_including_pbb (lst_p loop, poly_bb_p pbb, bool before)
{
int i;
lst_p l;
if (!loop || !LST_LOOP_P (loop))
return before;
for (i = 0; VEC_iterate (lst_p, LST_SEQ (loop), i, l);)
if (LST_LOOP_P (l))
{
before = lst_remove_all_before_including_pbb (l, pbb, before);
if (VEC_length (lst_p, LST_SEQ (l)) == 0)
{
VEC_ordered_remove (lst_p, LST_SEQ (loop), i);
free_lst (l);
}
else
i++;
}
else
{ {
lst_p res = lst_find_first_pbb (l); if (before)
if (res) {
return res; if (LST_PBB (l) == pbb)
before = false;
VEC_ordered_remove (lst_p, LST_SEQ (loop), i);
free_lst (l);
}
else if (LST_PBB (l) == pbb)
{
before = true;
VEC_ordered_remove (lst_p, LST_SEQ (loop), i);
free_lst (l);
}
else
i++;
} }
return lst; return before;
}
/* Removes from LOOP all the statements before/after and excluding PBB
if BEFORE is true/false; Returns the negation of BEFORE when the
statement PBB has been found. */
static inline bool
lst_remove_all_before_excluding_pbb (lst_p loop, poly_bb_p pbb, bool before)
{
int i;
lst_p l;
if (!loop || !LST_LOOP_P (loop))
return before;
for (i = 0; VEC_iterate (lst_p, LST_SEQ (loop), i, l);)
if (LST_LOOP_P (l))
{
before = lst_remove_all_before_excluding_pbb (l, pbb, before);
if (VEC_length (lst_p, LST_SEQ (l)) == 0)
{
VEC_ordered_remove (lst_p, LST_SEQ (loop), i);
free_lst (l);
continue;
}
i++;
}
else
{
if (before && LST_PBB (l) != pbb)
{
VEC_ordered_remove (lst_p, LST_SEQ (loop), i);
free_lst (l);
continue;
}
i++;
if (LST_PBB (l) == pbb)
before = before ? false : true;
}
return before;
} }
/* A SCOP is a Static Control Part of the program, simple enough to be /* A SCOP is a Static Control Part of the program, simple enough to be
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment