Fix PR47654: Loop blocking should strip-mine at least two loops.
PR tree-optimization/47654 * graphite-blocking.c (pbb_strip_mine_time_depth): Do not return bool. (lst_do_strip_mine_loop): Return an int. (lst_do_strip_mine): Same. (scop_do_strip_mine): Same. (scop_do_block): Loop blocking should strip-mine at least two loops. * graphite-interchange.c (lst_interchange_select_outer): Return an int. (scop_do_interchange): Same. * graphite-poly.h (scop_do_interchange): Update declaration. (scop_do_strip_mine): Same. * gcc.dg/graphite/block-pr47654.c: New. From-SVN: r175861
This commit is contained in:
parent
9b0d314a45
commit
cec11ec414
@ -1,3 +1,16 @@
|
||||
2011-07-05 Sebastian Pop <sebastian.pop@amd.com>
|
||||
|
||||
PR tree-optimization/47654
|
||||
* graphite-blocking.c (pbb_strip_mine_time_depth): Do not return bool.
|
||||
(lst_do_strip_mine_loop): Return an int.
|
||||
(lst_do_strip_mine): Same.
|
||||
(scop_do_strip_mine): Same.
|
||||
(scop_do_block): Loop blocking should strip-mine at least two loops.
|
||||
* graphite-interchange.c (lst_interchange_select_outer): Return an int.
|
||||
(scop_do_interchange): Same.
|
||||
* graphite-poly.h (scop_do_interchange): Update declaration.
|
||||
(scop_do_strip_mine): Same.
|
||||
|
||||
2011-07-05 Sebastian Pop <sebastian.pop@amd.com>
|
||||
|
||||
* graphite-clast-to-gimple.c (precision_for_value): Removed.
|
||||
|
@ -89,7 +89,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
# }
|
||||
*/
|
||||
|
||||
static bool
|
||||
static void
|
||||
pbb_strip_mine_time_depth (poly_bb_p pbb, int time_depth, int stride)
|
||||
{
|
||||
ppl_dimension_type iter, dim, strip;
|
||||
@ -151,8 +151,6 @@ pbb_strip_mine_time_depth (poly_bb_p pbb, int time_depth, int stride)
|
||||
ppl_Polyhedron_add_constraint (res, new_cstr);
|
||||
ppl_delete_Constraint (new_cstr);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Returns true when strip mining with STRIDE of the loop LST is
|
||||
@ -177,10 +175,10 @@ lst_strip_mine_profitable_p (lst_p lst, int stride)
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Strip-mines all the loops of LST with STRIDE. Return true if it
|
||||
did strip-mined some loops. */
|
||||
/* Strip-mines all the loops of LST with STRIDE. Return the number of
|
||||
loops strip-mined. */
|
||||
|
||||
static bool
|
||||
static int
|
||||
lst_do_strip_mine_loop (lst_p lst, int depth, int stride)
|
||||
{
|
||||
int i;
|
||||
@ -188,26 +186,26 @@ lst_do_strip_mine_loop (lst_p lst, int depth, int stride)
|
||||
poly_bb_p pbb;
|
||||
|
||||
if (!lst)
|
||||
return false;
|
||||
return 0;
|
||||
|
||||
if (LST_LOOP_P (lst))
|
||||
{
|
||||
bool res = false;
|
||||
int res = 0;
|
||||
|
||||
FOR_EACH_VEC_ELT (lst_p, LST_SEQ (lst), i, l)
|
||||
res |= lst_do_strip_mine_loop (l, depth, stride);
|
||||
res += lst_do_strip_mine_loop (l, depth, stride);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
pbb = LST_PBB (lst);
|
||||
return pbb_strip_mine_time_depth (pbb, psct_dynamic_dim (pbb, depth),
|
||||
stride);
|
||||
pbb_strip_mine_time_depth (pbb, psct_dynamic_dim (pbb, depth), stride);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Strip-mines all the loops of LST with STRIDE. When STRIDE is zero,
|
||||
read the stride from the PARAM_LOOP_BLOCK_TILE_SIZE. Return true
|
||||
if it did strip-mined some loops.
|
||||
read the stride from the PARAM_LOOP_BLOCK_TILE_SIZE. Return the
|
||||
number of strip-mined loops.
|
||||
|
||||
Strip mining transforms a loop
|
||||
|
||||
@ -221,12 +219,12 @@ lst_do_strip_mine_loop (lst_p lst, int depth, int stride)
|
||||
| S (i = k + j);
|
||||
*/
|
||||
|
||||
static bool
|
||||
static int
|
||||
lst_do_strip_mine (lst_p lst, int stride)
|
||||
{
|
||||
int i;
|
||||
lst_p l;
|
||||
bool res = false;
|
||||
int res = 0;
|
||||
int depth;
|
||||
|
||||
if (!stride)
|
||||
@ -237,23 +235,23 @@ lst_do_strip_mine (lst_p lst, int stride)
|
||||
return false;
|
||||
|
||||
FOR_EACH_VEC_ELT (lst_p, LST_SEQ (lst), i, l)
|
||||
res |= lst_do_strip_mine (l, stride);
|
||||
res += lst_do_strip_mine (l, stride);
|
||||
|
||||
depth = lst_depth (lst);
|
||||
if (depth >= 0
|
||||
&& lst_strip_mine_profitable_p (lst, stride))
|
||||
{
|
||||
res |= lst_do_strip_mine_loop (lst, lst_depth (lst), stride);
|
||||
res += lst_do_strip_mine_loop (lst, lst_depth (lst), stride);
|
||||
lst_add_loop_under_loop (lst);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Strip mines all the loops in SCOP. Returns true when some loops
|
||||
have been strip-mined. */
|
||||
/* Strip mines all the loops in SCOP. Returns the number of
|
||||
strip-mined loops. */
|
||||
|
||||
bool
|
||||
int
|
||||
scop_do_strip_mine (scop_p scop, int stride)
|
||||
{
|
||||
return lst_do_strip_mine (SCOP_TRANSFORMED_SCHEDULE (scop), stride);
|
||||
@ -265,27 +263,22 @@ scop_do_strip_mine (scop_p scop, int stride)
|
||||
bool
|
||||
scop_do_block (scop_p scop)
|
||||
{
|
||||
bool strip_mined = false;
|
||||
bool interchanged = false;
|
||||
|
||||
store_scattering (scop);
|
||||
|
||||
strip_mined = lst_do_strip_mine (SCOP_TRANSFORMED_SCHEDULE (scop), 0);
|
||||
interchanged = scop_do_interchange (scop);
|
||||
|
||||
/* If we don't interchange loops, the strip mine alone will not be
|
||||
profitable, and the transform is not a loop blocking: so revert
|
||||
the transform. */
|
||||
if (!interchanged)
|
||||
/* If we don't strip mine at least two loops, or not interchange
|
||||
loops, the strip mine alone will not be profitable, and the
|
||||
transform is not a loop blocking: so revert the transform. */
|
||||
if (lst_do_strip_mine (SCOP_TRANSFORMED_SCHEDULE (scop), 0) < 2
|
||||
|| scop_do_interchange (scop) == 0)
|
||||
{
|
||||
restore_scattering (scop);
|
||||
return false;
|
||||
}
|
||||
else if (strip_mined && interchanged
|
||||
&& dump_file && (dump_flags & TDF_DETAILS))
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, "SCoP will be loop blocked.\n");
|
||||
|
||||
return strip_mined || interchanged;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -664,27 +664,27 @@ lst_interchange_select_inner (scop_p scop, lst_p outer_father, int outer,
|
||||
}
|
||||
|
||||
/* 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. OUTER is the index in LST_SEQ (LOOP) that
|
||||
are considered profitable to interchange. Return the number of
|
||||
interchanged loops. OUTER is the index in LST_SEQ (LOOP) that
|
||||
points to the next outer loop to be considered for interchange. */
|
||||
|
||||
static bool
|
||||
static int
|
||||
lst_interchange_select_outer (scop_p scop, lst_p loop, int outer)
|
||||
{
|
||||
lst_p l;
|
||||
bool res = false;
|
||||
int res = 0;
|
||||
int i = 0;
|
||||
lst_p father;
|
||||
|
||||
if (!loop || !LST_LOOP_P (loop))
|
||||
return false;
|
||||
return 0;
|
||||
|
||||
father = LST_LOOP_FATHER (loop);
|
||||
if (father)
|
||||
{
|
||||
while (lst_interchange_select_inner (scop, father, outer, loop))
|
||||
{
|
||||
res = true;
|
||||
res++;
|
||||
loop = VEC_index (lst_p, LST_SEQ (father), outer);
|
||||
}
|
||||
}
|
||||
@ -692,17 +692,18 @@ lst_interchange_select_outer (scop_p scop, lst_p loop, int outer)
|
||||
if (LST_LOOP_P (loop))
|
||||
FOR_EACH_VEC_ELT (lst_p, LST_SEQ (loop), i, l)
|
||||
if (LST_LOOP_P (l))
|
||||
res |= lst_interchange_select_outer (scop, l, i);
|
||||
res += lst_interchange_select_outer (scop, l, i);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Interchanges all the loop depths that are considered profitable for SCOP. */
|
||||
/* Interchanges all the loop depths that are considered profitable for
|
||||
SCOP. Return the number of interchanged loops. */
|
||||
|
||||
bool
|
||||
int
|
||||
scop_do_interchange (scop_p scop)
|
||||
{
|
||||
bool res = lst_interchange_select_outer
|
||||
int res = lst_interchange_select_outer
|
||||
(scop, SCOP_TRANSFORMED_SCHEDULE (scop), 0);
|
||||
|
||||
lst_update_scattering (SCOP_TRANSFORMED_SCHEDULE (scop));
|
||||
|
@ -410,8 +410,8 @@ extern void print_iteration_domain (FILE *, poly_bb_p, int);
|
||||
extern void print_iteration_domains (FILE *, scop_p, int);
|
||||
extern void debug_iteration_domain (poly_bb_p, int);
|
||||
extern void debug_iteration_domains (scop_p, int);
|
||||
extern bool scop_do_interchange (scop_p);
|
||||
extern bool scop_do_strip_mine (scop_p, int);
|
||||
extern int scop_do_interchange (scop_p);
|
||||
extern int scop_do_strip_mine (scop_p, int);
|
||||
extern bool scop_do_block (scop_p);
|
||||
extern bool flatten_all_loops (scop_p);
|
||||
extern void pbb_number_of_iterations_at_time (poly_bb_p, graphite_dim_t, mpz_t);
|
||||
|
@ -1,3 +1,8 @@
|
||||
2011-07-05 Sebastian Pop <sebastian.pop@amd.com>
|
||||
|
||||
PR tree-optimization/47654
|
||||
* gcc.dg/graphite/block-pr47654.c: New.
|
||||
|
||||
2011-07-05 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/cpp0x/lambda/lambda-ref2.C: New.
|
||||
@ -39,7 +44,7 @@
|
||||
* gcc.dg/pr49602.c: New test.
|
||||
|
||||
2011-07-04 Georg-Johann Lay <avr@gjlay.de>
|
||||
|
||||
|
||||
PR target/34734
|
||||
PR target/44643
|
||||
* gcc.target/avr/avr.exp: Run over cpp files, too.
|
||||
|
25
gcc/testsuite/gcc.dg/graphite/block-pr47654.c
Normal file
25
gcc/testsuite/gcc.dg/graphite/block-pr47654.c
Normal file
@ -0,0 +1,25 @@
|
||||
int a[128][40];
|
||||
|
||||
void __attribute__ ((noinline, noclone))
|
||||
foo (void)
|
||||
{
|
||||
int i, j;
|
||||
for (i = 0; i < 40; i++)
|
||||
for (j = 0; j < 128; j++)
|
||||
a[j][i] = 4;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int i, j;
|
||||
foo ();
|
||||
for (i = 0; i < 40; i++)
|
||||
for (j = 0; j < 128; j++)
|
||||
if (a[j][i] != 4)
|
||||
__builtin_abort ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-not "will be loop blocked" "graphite" } } */
|
||||
/* { dg-final { cleanup-tree-dump "graphite" } } */
|
Loading…
Reference in New Issue
Block a user