summaryrefslogtreecommitdiff
path: root/gcc/lambda-code.c
diff options
context:
space:
mode:
authorJan Sjodin <jan.sjodin@amd.com>2007-06-06 06:08:58 +0000
committerSebastian Pop <spop@gcc.gnu.org>2007-06-06 06:08:58 +0000
commit69f2880c76592888802df4ab3621b9f32cf1523b (patch)
treebd5186af1c19a3521332d48b13b46ab6820faad1 /gcc/lambda-code.c
parent518a0b783878a8e1056a79ff31f18170775530a3 (diff)
downloadgcc-69f2880c76592888802df4ab3621b9f32cf1523b.tar.gz
lambda.h (build_linear_expr): New.
* lambda.h (build_linear_expr): New. * lambda-code.c (lbv_to_gcc_expression, lle_to_gcc_expression): Use build_linear_expr, call fold and force_gimple_operand. (lambda_loopnest_to_gcc_loopnest): Check that there is something to insert. * testsuite/gcc.dg/tree-ssa/ltrans-6.c: New. Co-Authored-By: Sebastian Pop <sebpop@gmail.com> From-SVN: r125355
Diffstat (limited to 'gcc/lambda-code.c')
-rw-r--r--gcc/lambda-code.c290
1 files changed, 59 insertions, 231 deletions
diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c
index 291d1d91e5b..96aaaa07e55 100644
--- a/gcc/lambda-code.c
+++ b/gcc/lambda-code.c
@@ -1528,71 +1528,18 @@ lbv_to_gcc_expression (lambda_body_vector lbv,
tree type, VEC(tree,heap) *induction_vars,
tree *stmts_to_insert)
{
- tree stmts, stmt, resvar, name;
- tree iv;
- size_t i;
- tree_stmt_iterator tsi;
+ int k;
+ tree resvar;
+ tree expr = build_linear_expr (type, LBV_COEFFICIENTS (lbv), induction_vars);
+
+ k = LBV_DENOMINATOR (lbv);
+ gcc_assert (k != 0);
+ if (k != 1)
+ expr = fold_build2 (CEIL_DIV_EXPR, type, expr, build_int_cst (type, k));
- /* Create a statement list and a linear expression temporary. */
- stmts = alloc_stmt_list ();
resvar = create_tmp_var (type, "lbvtmp");
add_referenced_var (resvar);
-
- /* Start at 0. */
- stmt = build_gimple_modify_stmt (resvar,
- fold_convert (type, integer_zero_node));
- name = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
-
- for (i = 0; VEC_iterate (tree, induction_vars, i, iv); i++)
- {
- if (LBV_COEFFICIENTS (lbv)[i] != 0)
- {
- tree newname;
- tree coeffmult;
-
- /* newname = coefficient * induction_variable */
- coeffmult = build_int_cst (type, LBV_COEFFICIENTS (lbv)[i]);
- stmt = build_gimple_modify_stmt (resvar,
- fold_build2 (MULT_EXPR, type,
- iv, coeffmult));
-
- newname = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = newname;
- fold_stmt (&stmt);
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
-
- /* name = name + newname */
- stmt = build_gimple_modify_stmt (resvar,
- build2 (PLUS_EXPR, type,
- name, newname));
- name = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
- fold_stmt (&stmt);
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
-
- }
- }
-
- /* Handle any denominator that occurs. */
- if (LBV_DENOMINATOR (lbv) != 1)
- {
- tree denominator = build_int_cst (type, LBV_DENOMINATOR (lbv));
- stmt = build_gimple_modify_stmt (resvar,
- build2 (CEIL_DIV_EXPR, type,
- name, denominator));
- name = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
- fold_stmt (&stmt);
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
- }
- *stmts_to_insert = stmts;
- return name;
+ return force_gimple_operand (fold (expr), stmts_to_insert, true, resvar);
}
/* Convert a linear expression from coefficient and constant form to a
@@ -1616,182 +1563,57 @@ lle_to_gcc_expression (lambda_linear_expression lle,
VEC(tree,heap) *invariants,
enum tree_code wrap, tree *stmts_to_insert)
{
- tree stmts, stmt, resvar, name;
- size_t i;
- tree_stmt_iterator tsi;
- tree iv, invar;
+ int k;
+ tree resvar;
+ tree expr = NULL_TREE;
VEC(tree,heap) *results = NULL;
gcc_assert (wrap == MAX_EXPR || wrap == MIN_EXPR);
- name = NULL_TREE;
- /* Create a statement list and a linear expression temporary. */
- stmts = alloc_stmt_list ();
- resvar = create_tmp_var (type, "lletmp");
- add_referenced_var (resvar);
- /* Build up the linear expressions, and put the variable representing the
- result in the results array. */
+ /* Build up the linear expressions. */
for (; lle != NULL; lle = LLE_NEXT (lle))
{
- /* Start at name = 0. */
- stmt = build_gimple_modify_stmt (resvar,
- fold_convert (type, integer_zero_node));
- name = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
- fold_stmt (&stmt);
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
-
- /* First do the induction variables.
- at the end, name = name + all the induction variables added
- together. */
- for (i = 0; VEC_iterate (tree, induction_vars, i, iv); i++)
- {
- if (LLE_COEFFICIENTS (lle)[i] != 0)
- {
- tree newname;
- tree mult;
- tree coeff;
-
- /* mult = induction variable * coefficient. */
- if (LLE_COEFFICIENTS (lle)[i] == 1)
- {
- mult = VEC_index (tree, induction_vars, i);
- }
- else
- {
- coeff = build_int_cst (type,
- LLE_COEFFICIENTS (lle)[i]);
- mult = fold_build2 (MULT_EXPR, type, iv, coeff);
- }
-
- /* newname = mult */
- stmt = build_gimple_modify_stmt (resvar, mult);
- newname = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = newname;
- fold_stmt (&stmt);
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
-
- /* name = name + newname */
- stmt = build_gimple_modify_stmt (resvar,
- build2 (PLUS_EXPR, type,
- name, newname));
- name = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
- fold_stmt (&stmt);
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
- }
- }
-
- /* Handle our invariants.
- At the end, we have name = name + result of adding all multiplied
- invariants. */
- for (i = 0; VEC_iterate (tree, invariants, i, invar); i++)
- {
- if (LLE_INVARIANT_COEFFICIENTS (lle)[i] != 0)
- {
- tree newname;
- tree mult;
- tree coeff;
- int invcoeff = LLE_INVARIANT_COEFFICIENTS (lle)[i];
- /* mult = invariant * coefficient */
- if (invcoeff == 1)
- {
- mult = invar;
- }
- else
- {
- coeff = build_int_cst (type, invcoeff);
- mult = fold_build2 (MULT_EXPR, type, invar, coeff);
- }
-
- /* newname = mult */
- stmt = build_gimple_modify_stmt (resvar, mult);
- newname = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = newname;
- fold_stmt (&stmt);
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
-
- /* name = name + newname */
- stmt = build_gimple_modify_stmt (resvar,
- build2 (PLUS_EXPR, type,
- name, newname));
- name = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
- fold_stmt (&stmt);
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
- }
- }
-
- /* Now handle the constant.
- name = name + constant. */
- if (LLE_CONSTANT (lle) != 0)
- {
- tree incr = build_int_cst (type, LLE_CONSTANT (lle));
- stmt = build_gimple_modify_stmt (resvar, build2 (PLUS_EXPR, type,
- name, incr));
- name = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
- fold_stmt (&stmt);
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
- }
-
- /* Now handle the offset.
- name = name + linear offset. */
- if (LLE_CONSTANT (offset) != 0)
- {
- tree incr = build_int_cst (type, LLE_CONSTANT (offset));
- stmt = build_gimple_modify_stmt (resvar, build2 (PLUS_EXPR, type,
- name, incr));
- name = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
- fold_stmt (&stmt);
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
- }
-
- /* Handle any denominator that occurs. */
- if (LLE_DENOMINATOR (lle) != 1)
- {
- stmt = build_int_cst (type, LLE_DENOMINATOR (lle));
- stmt = build2 (wrap == MAX_EXPR ? CEIL_DIV_EXPR : FLOOR_DIV_EXPR,
- type, name, stmt);
- stmt = build_gimple_modify_stmt (resvar, stmt);
-
- /* name = {ceil, floor}(name/denominator) */
- name = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
- }
- VEC_safe_push (tree, heap, results, name);
+ expr = build_linear_expr (type, LLE_COEFFICIENTS (lle), induction_vars);
+ expr = fold_build2 (PLUS_EXPR, type, expr,
+ build_linear_expr (type,
+ LLE_INVARIANT_COEFFICIENTS (lle),
+ invariants));
+
+ k = LLE_CONSTANT (lle);
+ if (k)
+ expr = fold_build2 (PLUS_EXPR, type, expr, build_int_cst (type, k));
+
+ k = LLE_CONSTANT (offset);
+ if (k)
+ expr = fold_build2 (PLUS_EXPR, type, expr, build_int_cst (type, k));
+
+ k = LLE_DENOMINATOR (lle);
+ if (k != 1)
+ expr = fold_build2 (wrap == MAX_EXPR ? CEIL_DIV_EXPR : FLOOR_DIV_EXPR,
+ type, expr, build_int_cst (type, k));
+
+ expr = fold (expr);
+ VEC_safe_push (tree, heap, results, expr);
}
- /* Again, out of laziness, we don't handle this case yet. It's not
- hard, it just hasn't occurred. */
- gcc_assert (VEC_length (tree, results) <= 2);
-
+ gcc_assert (expr);
+
/* We may need to wrap the results in a MAX_EXPR or MIN_EXPR. */
if (VEC_length (tree, results) > 1)
{
- tree op1 = VEC_index (tree, results, 0);
- tree op2 = VEC_index (tree, results, 1);
- stmt = build_gimple_modify_stmt (resvar, build2 (wrap, type, op1, op2));
- name = make_ssa_name (resvar, stmt);
- GIMPLE_STMT_OPERAND (stmt, 0) = name;
- tsi = tsi_last (stmts);
- tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
+ size_t i;
+ tree op;
+
+ expr = VEC_index (tree, results, 0);
+ for (i = 1; VEC_iterate (tree, results, i, op); i++)
+ expr = fold_build2 (wrap, type, expr, op);
}
VEC_free (tree, heap, results);
-
- *stmts_to_insert = stmts;
- return name;
+
+ resvar = create_tmp_var (type, "lletmp");
+ add_referenced_var (resvar);
+ return force_gimple_operand (fold (expr), stmts_to_insert, true, resvar);
}
/* Transform a lambda loopnest NEW_LOOPNEST, which had TRANSFORM applied to
@@ -1869,8 +1691,12 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
type,
new_ivs,
invariants, MAX_EXPR, &stmts);
- bsi_insert_on_edge (loop_preheader_edge (temp), stmts);
- bsi_commit_edge_inserts ();
+
+ if (stmts)
+ {
+ bsi_insert_on_edge (loop_preheader_edge (temp), stmts);
+ bsi_commit_edge_inserts ();
+ }
/* Build the new upper bound and insert its statements in the
basic block of the exit condition */
newupperbound = lle_to_gcc_expression (LL_UPPER_BOUND (newloop),
@@ -1882,7 +1708,8 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
exitcond = get_loop_exit_condition (temp);
bb = bb_for_stmt (exitcond);
bsi = bsi_after_labels (bb);
- bsi_insert_before (&bsi, stmts, BSI_NEW_STMT);
+ if (stmts)
+ bsi_insert_before (&bsi, stmts, BSI_NEW_STMT);
/* Create the new iv. */
@@ -1960,10 +1787,11 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
newiv = lbv_to_gcc_expression (newlbv, TREE_TYPE (oldiv),
new_ivs, &stmts);
- bsi = bsi_for_stmt (stmt);
- /* Insert the statements to build that
- expression. */
- bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
+ 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);