static void create_canonical_iv (struct loop *loop, edge exit, tree niter) { edge in; tree type, var; gcond *cond; gimple_stmt_iterator incr_at; enum tree_code cmp; if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Added canonical iv to loop %d, ", loop->num); print_generic_expr (dump_file, niter, TDF_SLIM); fprintf (dump_file, " iterations.\n"); } cond = as_a <gcond *> (last_stmt (exit->src)); in = EDGE_SUCC (exit->src, 0); if (in == exit) in = EDGE_SUCC (exit->src, 1); /* Note that we do not need to worry about overflows, since type of niter is always unsigned and all comparisons are just for equality/nonequality -- i.e. everything works with a modulo arithmetics. */ type = TREE_TYPE (niter); niter = fold_build2 (PLUS_EXPR, type, niter, build_int_cst (type, 1)); incr_at = gsi_last_bb (in->src); create_iv (niter, build_int_cst (type, -1), NULL_TREE, loop, &incr_at, false, NULL, &var); cmp = (exit->flags & EDGE_TRUE_VALUE) ? EQ_EXPR : NE_EXPR; gimple_cond_set_code (cond, cmp); gimple_cond_set_lhs (cond, var); gimple_cond_set_rhs (cond, build_int_cst (type, 0)); update_stmt (cond); }
void propagate_tree_value_into_stmt (gimple_stmt_iterator *gsi, tree val) { gimple stmt = gsi_stmt (*gsi); if (is_gimple_assign (stmt)) { tree expr = NULL_TREE; if (gimple_assign_single_p (stmt)) expr = gimple_assign_rhs1 (stmt); propagate_tree_value (&expr, val); gimple_assign_set_rhs_from_tree (gsi, expr); stmt = gsi_stmt (*gsi); } else if (gimple_code (stmt) == GIMPLE_COND) { tree lhs = NULL_TREE; tree rhs = fold_convert (TREE_TYPE (val), integer_zero_node); propagate_tree_value (&lhs, val); gimple_cond_set_code (stmt, NE_EXPR); gimple_cond_set_lhs (stmt, lhs); gimple_cond_set_rhs (stmt, rhs); } else if (is_gimple_call (stmt) && gimple_call_lhs (stmt) != NULL_TREE) { gimple new_stmt; tree expr = NULL_TREE; propagate_tree_value (&expr, val); new_stmt = gimple_build_assign (gimple_call_lhs (stmt), expr); copy_virtual_operands (new_stmt, stmt); move_ssa_defining_stmt_for_defs (new_stmt, stmt); gsi_replace (gsi, new_stmt, false); } else if (gimple_code (stmt) == GIMPLE_SWITCH) propagate_tree_value (gimple_switch_index_ptr (stmt), val); else gcc_unreachable (); }
void propagate_tree_value_into_stmt (gimple_stmt_iterator *gsi, tree val) { gimple stmt = gsi_stmt (*gsi); if (is_gimple_assign (stmt)) { tree expr = NULL_TREE; if (gimple_assign_single_p (stmt)) expr = gimple_assign_rhs1 (stmt); propagate_tree_value (&expr, val); gimple_assign_set_rhs_from_tree (gsi, expr); } else if (gimple_code (stmt) == GIMPLE_COND) { tree lhs = NULL_TREE; tree rhs = build_zero_cst (TREE_TYPE (val)); propagate_tree_value (&lhs, val); gimple_cond_set_code (stmt, NE_EXPR); gimple_cond_set_lhs (stmt, lhs); gimple_cond_set_rhs (stmt, rhs); } else if (is_gimple_call (stmt) && gimple_call_lhs (stmt) != NULL_TREE) { tree expr = NULL_TREE; bool res; propagate_tree_value (&expr, val); res = update_call_from_tree (gsi, expr); gcc_assert (res); } else if (gimple_code (stmt) == GIMPLE_SWITCH) propagate_tree_value (gimple_switch_index_ptr (stmt), val); else gcc_unreachable (); }