+static tree
+update_accumulator_with_ops (enum tree_code code, tree acc, tree op1,
+ gimple_stmt_iterator gsi)
+{
+ gimple stmt;
+ tree var;
+ if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1)))
+ stmt = gimple_build_assign_with_ops (code, SSA_NAME_VAR (acc), acc, op1);
+ else
+ {
+ tree rhs = fold_convert (TREE_TYPE (acc),
+ fold_build2 (code,
+ TREE_TYPE (op1),
+ fold_convert (TREE_TYPE (op1), acc),
+ op1));
+ rhs = force_gimple_operand_gsi (&gsi, rhs,
+ false, NULL, false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (NULL_TREE, rhs);
+ }
+ var = make_ssa_name (SSA_NAME_VAR (acc), stmt);
+ gimple_assign_set_lhs (stmt, var);
+ update_stmt (stmt);
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ return var;
+}
+
+/* Adjust the accumulator values according to A and M after GSI, and update
+ the phi nodes on edge BACK. */
+
+static void
+adjust_accumulator_values (gimple_stmt_iterator gsi, tree m, tree a, edge back)
+{
+ tree var, a_acc_arg, m_acc_arg;
+
+ if (m)
+ m = force_gimple_operand_gsi (&gsi, m, true, NULL, true, GSI_SAME_STMT);
+ if (a)
+ a = force_gimple_operand_gsi (&gsi, a, true, NULL, true, GSI_SAME_STMT);
+
+ a_acc_arg = a_acc;
+ m_acc_arg = m_acc;