This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[patch] Fix PR34017: ICE in lambda_loopnest_to_gcc_loopnest
- From: "Sebastian Pop" <sebpop at gmail dot com>
- To: "Daniel Berlin" <dberlin at dberlin dot org>, "GCC Patches" <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 9 Jan 2008 00:17:58 -0600
- Subject: [patch] Fix PR34017: ICE in lambda_loopnest_to_gcc_loopnest
Hi,
We used to abort when the expression to be rewritten was a PHI_NODE,
but as Jakub remarked in the PR comments, there is no reason we cannot
transform the PHI_NODE expressions. The attached patch is fixing this
bug by implementing the translation of PHI_NODEs in function of the
new induction variables.
The patch passed tree-ssa.exp, and I'm going to regstrap it tonight.
Okay for trunk after regtest?
Sebastian
--
AMD - GNU Tools
2008-01-09 Sebastian Pop <sebastian.pop@amd.com>
PR tree-optimization/34017
* lambda-code.c (rewrite_expr_new_ivs, rewrite_phi_new_ivs): New.
(lambda_loopnest_to_gcc_loopnest): Use these functions.
* gcc.dg/tree-ssa/pr34017.c: New.
email:sebpop@gmail.com
branch:trunk
revision:HEAD
configure:
make:
check:
Index: testsuite/gcc.dg/tree-ssa/pr34017.c
===================================================================
--- testsuite/gcc.dg/tree-ssa/pr34017.c (revision 0)
+++ testsuite/gcc.dg/tree-ssa/pr34017.c (revision 0)
@@ -0,0 +1,26 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-linear" } */
+
+extern int s;
+
+void
+foo (int *x, int y, int z)
+{
+ int m, n;
+ int o;
+ int p = x[0];
+ o = s;
+ for (m = 0; m < s; m++)
+ for (n = 0; n < s; n++)
+ {
+ if (x[n] != p)
+ continue;
+ if (m > z)
+ z = m;
+ if (n < o)
+ o = n;
+ }
+ for (m = y; m <= z; m++)
+ {
+ }
+}
Index: lambda-code.c
===================================================================
--- lambda-code.c (revision 131307)
+++ lambda-code.c (working copy)
@@ -1675,6 +1675,61 @@ remove_iv (tree iv_stmt)
}
}
+/* Rewrite the expression with the new induction variables. */
+
+static void
+rewrite_expr_new_ivs (imm_use_iterator *imm_iter, tree stmt, size_t iv,
+ tree type, lambda_trans_matrix transform,
+ VEC(tree,heap) *new_ivs, struct obstack *lambda_obstack)
+{
+ use_operand_p use_p;
+ tree newiv, stmts;
+ lambda_body_vector newlbv;
+ lambda_body_vector lbv = lambda_body_vector_new (VEC_length (tree, new_ivs),
+ lambda_obstack);
+
+ LBV_COEFFICIENTS (lbv)[iv] = 1;
+ newlbv = lambda_body_vector_compute_new (transform, lbv, lambda_obstack);
+ newiv = lbv_to_gcc_expression (newlbv, type, new_ivs, &stmts);
+
+ if (stmts)
+ {
+ block_stmt_iterator bsi = bsi_for_stmt (stmt);
+ bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
+ }
+
+ FOR_EACH_IMM_USE_ON_STMT (use_p, *imm_iter)
+ propagate_value (use_p, newiv);
+
+ update_stmt (stmt);
+}
+
+/* Rewrite the phi node with the new induction variables. */
+
+static void
+rewrite_phi_new_ivs (imm_use_iterator *imm_iter, tree phi, size_t iv,
+ tree type, lambda_trans_matrix transform,
+ VEC(tree,heap) *new_ivs, struct obstack *lambda_obstack)
+{
+ int i;
+ use_operand_p use_p;
+ tree newiv, stmts;
+ lambda_body_vector newlbv;
+ lambda_body_vector lbv = lambda_body_vector_new (VEC_length (tree, new_ivs),
+ lambda_obstack);
+
+ LBV_COEFFICIENTS (lbv)[iv] = 1;
+ newlbv = lambda_body_vector_compute_new (transform, lbv, lambda_obstack);
+ newiv = lbv_to_gcc_expression (newlbv, type, new_ivs, &stmts);
+
+ FOR_EACH_IMM_USE_ON_STMT (use_p, *imm_iter)
+ propagate_value (use_p, newiv);
+
+ if (stmts)
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ if (PHI_ARG_DEF (phi, i) == newiv)
+ bsi_insert_on_edge (PHI_ARG_EDGE (phi, i), stmts);
+}
/* Transform a lambda loopnest NEW_LOOPNEST, which had TRANSFORM applied to
it, back into gcc code. This changes the
@@ -1698,7 +1753,7 @@ lambda_loopnest_to_gcc_loopnest (struct
struct obstack * lambda_obstack)
{
struct loop *temp;
- size_t i = 0;
+ size_t iv, i = 0;
size_t depth = 0;
VEC(tree,heap) *new_ivs = NULL;
tree oldiv;
@@ -1818,10 +1873,9 @@ lambda_loopnest_to_gcc_loopnest (struct
/* Rewrite uses of the old ivs so that they are now specified in terms of
the new ivs. */
- for (i = 0; VEC_iterate (tree, old_ivs, i, oldiv); i++)
+ for (iv = 0; VEC_iterate (tree, old_ivs, iv, oldiv); iv++)
{
imm_use_iterator imm_iter;
- use_operand_p use_p;
tree oldiv_def;
tree oldiv_stmt = SSA_NAME_DEF_STMT (oldiv);
tree stmt;
@@ -1833,33 +1887,12 @@ lambda_loopnest_to_gcc_loopnest (struct
gcc_assert (oldiv_def != NULL_TREE);
FOR_EACH_IMM_USE_STMT (stmt, imm_iter, oldiv_def)
- {
- tree newiv, stmts;
- lambda_body_vector lbv, newlbv;
-
- gcc_assert (TREE_CODE (stmt) != PHI_NODE);
-
- /* Compute the new expression for the induction
- variable. */
- depth = VEC_length (tree, new_ivs);
- lbv = lambda_body_vector_new (depth, lambda_obstack);
- LBV_COEFFICIENTS (lbv)[i] = 1;
-
- newlbv = lambda_body_vector_compute_new (transform, lbv,
- lambda_obstack);
-
- newiv = lbv_to_gcc_expression (newlbv, TREE_TYPE (oldiv),
- new_ivs, &stmts);
- if (stmts)
- {
- bsi = bsi_for_stmt (stmt);
- bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
- }
-
- FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
- propagate_value (use_p, newiv);
- update_stmt (stmt);
- }
+ if (TREE_CODE (stmt) != PHI_NODE)
+ rewrite_expr_new_ivs (&imm_iter, stmt, iv, TREE_TYPE (oldiv),
+ transform, new_ivs, lambda_obstack);
+ else
+ rewrite_phi_new_ivs (&imm_iter, stmt, iv, TREE_TYPE (oldiv),
+ transform, new_ivs, lambda_obstack);
/* Remove the now unused induction variable. */
VEC_safe_push (tree, heap, *remove_ivs, oldiv_stmt);