re PR tree-optimization/23820 (ICE in lambda_loopnest_to_gcc_loopnest, at lambda-code.c:1982)
2007-10-19 Sebastian Pop <sebastian.pop@amd.com> PR tree-optimization/23820 PR tree-optimization/24309 PR tree-optimization/33766 * testsuite/gcc.dg/tree-ssa/pr23820.c: New. * testsuite/gcc.dg/tree-ssa/pr24309.c: New. * testsuite/gcc.dg/tree-ssa/pr33766.c: New. * testsuite/gcc.dg/tree-ssa/ltrans-3.c: XFAILed. * tree-loop-linear.c (perfect_loop_nest_depth): New. (linear_transform_loops): Use perfect_loop_nest_depth. * lambda-code.c (perfect_nest_p): Outer loops in perfect nests should have a single condition: their exit. From-SVN: r129494
This commit is contained in:
parent
23e8722aed
commit
671633e949
|
@ -1,3 +1,17 @@
|
|||
2007-10-19 Sebastian Pop <sebastian.pop@amd.com>
|
||||
|
||||
PR tree-optimization/23820
|
||||
PR tree-optimization/24309
|
||||
PR tree-optimization/33766
|
||||
* testsuite/gcc.dg/tree-ssa/pr23820.c: New.
|
||||
* testsuite/gcc.dg/tree-ssa/pr24309.c: New.
|
||||
* testsuite/gcc.dg/tree-ssa/pr33766.c: New.
|
||||
* testsuite/gcc.dg/tree-ssa/ltrans-3.c: XFAILed.
|
||||
* tree-loop-linear.c (perfect_loop_nest_depth): New.
|
||||
(linear_transform_loops): Use perfect_loop_nest_depth.
|
||||
* lambda-code.c (perfect_nest_p): Outer loops in perfect nests
|
||||
should have a single condition: their exit.
|
||||
|
||||
2007-10-19 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR middle-end/33816
|
||||
|
|
|
@ -1972,32 +1972,42 @@ perfect_nest_p (struct loop *loop)
|
|||
size_t i;
|
||||
tree exit_cond;
|
||||
|
||||
/* Loops at depth 0 are perfect nests. */
|
||||
if (!loop->inner)
|
||||
return true;
|
||||
|
||||
bbs = get_loop_body (loop);
|
||||
exit_cond = get_loop_exit_condition (loop);
|
||||
|
||||
for (i = 0; i < loop->num_nodes; i++)
|
||||
{
|
||||
if (bbs[i]->loop_father == loop)
|
||||
{
|
||||
block_stmt_iterator bsi;
|
||||
|
||||
for (bsi = bsi_start (bbs[i]); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
{
|
||||
tree stmt = bsi_stmt (bsi);
|
||||
|
||||
if (TREE_CODE (stmt) == COND_EXPR
|
||||
&& exit_cond != stmt)
|
||||
goto non_perfectly_nested;
|
||||
|
||||
if (stmt == exit_cond
|
||||
|| not_interesting_stmt (stmt)
|
||||
|| stmt_is_bumper_for_loop (loop, stmt))
|
||||
continue;
|
||||
|
||||
non_perfectly_nested:
|
||||
free (bbs);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free (bbs);
|
||||
/* See if the inner loops are perfectly nested as well. */
|
||||
if (loop->inner)
|
||||
return perfect_nest_p (loop->inner);
|
||||
return true;
|
||||
|
||||
return perfect_nest_p (loop->inner);
|
||||
}
|
||||
|
||||
/* Replace the USES of X in STMT, or uses with the same step as X with Y.
|
||||
|
|
|
@ -17,5 +17,5 @@ int foo(int N, int *res)
|
|||
*res = sum + N;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump-times "transformed loop" 1 "ltrans"} } */
|
||||
/* { dg-final { scan-tree-dump-times "transformed loop" 1 "ltrans" { xfail *-*-* } } } */
|
||||
/* { dg-final { cleanup-tree-dump "ltrans" } } */
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -ftree-loop-linear" } */
|
||||
|
||||
int t [2][4];
|
||||
|
||||
void foo (void)
|
||||
{
|
||||
int i, j, k, v;
|
||||
float e;
|
||||
for (;;)
|
||||
{
|
||||
v = 0;
|
||||
for (j = 0; j < 2; j ++)
|
||||
{
|
||||
for (k = 2; k < 4; k ++)
|
||||
{
|
||||
e = 0.0;
|
||||
for (i = 0; i < 4; i ++)
|
||||
e += t [j][i];
|
||||
if (e)
|
||||
v = j;
|
||||
}
|
||||
}
|
||||
t [v][0] = 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -ftree-loop-linear" } */
|
||||
|
||||
float weight[10];
|
||||
void lsp_weight_quant(float *x, char *cdbk)
|
||||
{
|
||||
int i,j;
|
||||
float dist;
|
||||
int best_id=0;
|
||||
for (i=0;i<16;i++)
|
||||
{
|
||||
for (j=0;j<10;j++)
|
||||
dist=dist+weight[j];
|
||||
if (dist<0)
|
||||
best_id=i;
|
||||
}
|
||||
x[j] = cdbk[best_id*10+j];
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2 -ftree-loop-linear" } */
|
||||
|
||||
float
|
||||
fxt1_quantize_ALPHA1()
|
||||
{
|
||||
int j1;
|
||||
int i;
|
||||
float *tv;
|
||||
for (j1 = 1; j1; j1++) {
|
||||
float e;
|
||||
for (i = 1; i; i++)
|
||||
e = tv[i];
|
||||
if (e)
|
||||
i = j1;
|
||||
}
|
||||
return tv[i];
|
||||
}
|
||||
|
|
@ -244,6 +244,46 @@ try_interchange_loops (lambda_trans_matrix trans,
|
|||
return trans;
|
||||
}
|
||||
|
||||
/* Return the number of nested loops in LOOP_NEST, or 0 if the loops
|
||||
are not perfectly nested. */
|
||||
|
||||
static unsigned int
|
||||
perfect_loop_nest_depth (struct loop *loop_nest)
|
||||
{
|
||||
struct loop *temp;
|
||||
unsigned int depth = 1;
|
||||
|
||||
/* If it's not a loop nest, we don't want it. We also don't handle
|
||||
sibling loops properly, which are loops of the following form:
|
||||
|
||||
| for (i = 0; i < 50; i++)
|
||||
| {
|
||||
| for (j = 0; j < 50; j++)
|
||||
| {
|
||||
| ...
|
||||
| }
|
||||
| for (j = 0; j < 50; j++)
|
||||
| {
|
||||
| ...
|
||||
| }
|
||||
| }
|
||||
*/
|
||||
|
||||
if (!loop_nest->inner || !single_exit (loop_nest))
|
||||
return 0;
|
||||
|
||||
for (temp = loop_nest->inner; temp; temp = temp->inner)
|
||||
{
|
||||
/* If we have a sibling loop or multiple exit edges, jump ship. */
|
||||
if (temp->next || !single_exit (temp))
|
||||
return 0;
|
||||
|
||||
depth++;
|
||||
}
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
/* Perform a set of linear transforms on loops. */
|
||||
|
||||
void
|
||||
|
@ -263,47 +303,18 @@ linear_transform_loops (void)
|
|||
unsigned int depth = 0;
|
||||
VEC (ddr_p, heap) *dependence_relations;
|
||||
VEC (data_reference_p, heap) *datarefs;
|
||||
struct loop *temp;
|
||||
lambda_loopnest before, after;
|
||||
lambda_trans_matrix trans;
|
||||
bool problem = false;
|
||||
struct obstack lambda_obstack;
|
||||
gcc_obstack_init (&lambda_obstack);
|
||||
|
||||
/* If it's not a loop nest, we don't want it.
|
||||
We also don't handle sibling loops properly,
|
||||
which are loops of the following form:
|
||||
for (i = 0; i < 50; i++)
|
||||
{
|
||||
for (j = 0; j < 50; j++)
|
||||
{
|
||||
...
|
||||
}
|
||||
for (j = 0; j < 50; j++)
|
||||
{
|
||||
...
|
||||
}
|
||||
} */
|
||||
if (!loop_nest->inner || !single_exit (loop_nest))
|
||||
continue;
|
||||
VEC_truncate (tree, oldivs, 0);
|
||||
VEC_truncate (tree, invariants, 0);
|
||||
depth = 1;
|
||||
for (temp = loop_nest->inner; temp; temp = temp->inner)
|
||||
{
|
||||
/* If we have a sibling loop or multiple exit edges, jump ship. */
|
||||
if (temp->next || !single_exit (temp))
|
||||
{
|
||||
problem = true;
|
||||
break;
|
||||
}
|
||||
depth ++;
|
||||
}
|
||||
if (problem)
|
||||
depth = perfect_loop_nest_depth (loop_nest);
|
||||
if (depth == 0)
|
||||
continue;
|
||||
|
||||
/* Analyze data references and dependence relations using scev. */
|
||||
|
||||
VEC_truncate (tree, oldivs, 0);
|
||||
VEC_truncate (tree, invariants, 0);
|
||||
|
||||
datarefs = VEC_alloc (data_reference_p, heap, 10);
|
||||
dependence_relations = VEC_alloc (ddr_p, heap, 10 * 10);
|
||||
compute_data_dependences_for_loop (loop_nest, true, &datarefs,
|
||||
|
|
Loading…
Reference in New Issue