+ tree tmp = create_tmp_var (ret_type, label);
+ gimple stmt = gimple_build_assign_with_ops (code, tmp, op0, op1);
+ tree result;
+
+ if (TREE_CODE (ret_type) == COMPLEX_TYPE
+ || TREE_CODE (ret_type) == VECTOR_TYPE)
+ DECL_GIMPLE_REG_P (tmp) = 1;
+ add_referenced_var (tmp);
+ result = make_ssa_name (tmp, stmt);
+ gimple_assign_set_lhs (stmt, result);
+ update_stmt (stmt);
+ gsi_insert_before (&gsi, stmt, update);
+ return result;
+}
+
+/* Creates a new GIMPLE statement that adjusts the value of accumulator ACC by
+ the computation specified by CODE and OP1 and insert the statement
+ at the position specified by GSI as a new statement. Returns new SSA name
+ of updated accumulator. */
+
+static tree
+update_accumulator_with_ops (enum tree_code code, tree acc, tree op1,
+ gimple_stmt_iterator gsi)
+{
+ gimple stmt = gimple_build_assign_with_ops (code, SSA_NAME_VAR (acc), acc,
+ op1);
+ tree 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 = a_acc, m_acc_arg = m_acc;