tree def = PHI_RESULT (phi);
affine_iv iv;
- if (is_gimple_reg (def) && !simple_iv (loop, phi, def, &iv, true))
+ if (is_gimple_reg (def) && !simple_iv (loop, loop, def, &iv, true))
{
struct reduction_info *red;
return decl;
}
-/* Bases all the induction variables in LOOP on a single induction variable
- (unsigned with base 0 and step 1), whose final value is compared with
- NIT. The induction variable is incremented in the loop latch.
- REDUCTION_LIST describes the reductions in LOOP. Return the induction
- variable that was created. */
+/* Bases all the induction variables in LOOP on a single induction
+ variable (unsigned with base 0 and step 1), whose final value is
+ compared with *NIT. When the IV type precision has to be larger
+ than *NIT type precision, *NIT is converted to the larger type, the
+ conversion code is inserted before the loop, and *NIT is updated to
+ the new definition. The induction variable is incremented in the
+ loop latch. REDUCTION_LIST describes the reductions in LOOP.
+ Return the induction variable that was created. */
tree
-canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
+canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree *nit)
{
- unsigned precision = TYPE_PRECISION (TREE_TYPE (nit));
+ unsigned precision = TYPE_PRECISION (TREE_TYPE (*nit));
+ unsigned original_precision = precision;
tree res, type, var_before, val, atype, mtype;
gimple_stmt_iterator gsi, psi;
gimple phi, stmt;
affine_iv iv;
edge exit = single_dom_exit (loop);
struct reduction_info *red;
+ gimple_seq stmts;
for (psi = gsi_start_phis (loop->header);
!gsi_end_p (psi); gsi_next (&psi))
type = lang_hooks.types.type_for_size (precision, 1);
+ if (original_precision != precision)
+ {
+ *nit = fold_convert (type, *nit);
+ *nit = force_gimple_operand (*nit, &stmts, true, NULL_TREE);
+ if (stmts)
+ gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
+ }
+
gsi = gsi_last_bb (loop->latch);
create_iv (build_int_cst_type (type, 0), build_int_cst (type, 1), NULL_TREE,
loop, &gsi, true, &var_before, NULL);
continue;
}
- ok = simple_iv (loop, phi, res, &iv, true);
+ ok = simple_iv (loop, loop, res, &iv, true);
if (reduction_list)
red = reduction_phi (reduction_list, phi);
}
gimple_cond_set_code (stmt, LT_EXPR);
gimple_cond_set_lhs (stmt, var_before);
- gimple_cond_set_rhs (stmt, nit);
+ gimple_cond_set_rhs (stmt, *nit);
update_stmt (stmt);
return var_before;
free_original_copy_tables ();
/* Base all the induction variables in LOOP on a single control one. */
- canonicalize_loop_ivs (loop, reduction_list, nit);
+ canonicalize_loop_ivs (loop, reduction_list, &nit);
/* Ensure that the exit condition is the first statement in the loop. */
transform_to_exit_first_loop (loop, reduction_list, nit);