static void remove_duplicate_close_phi (gphi *phi, gphi_iterator *gsi) { gimple *use_stmt; use_operand_p use_p; imm_use_iterator imm_iter; tree res = gimple_phi_result (phi); tree def = gimple_phi_result (gsi->phi ()); gcc_assert (same_close_phi_node (phi, gsi->phi ())); FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, def) { FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter) SET_USE (use_p, res); update_stmt (use_stmt); /* It is possible that we just created a duplicate close-phi for an already-processed containing loop. Check for this case and clean it up. */ if (gimple_code (use_stmt) == GIMPLE_PHI && gimple_phi_num_args (use_stmt) == 1) make_close_phi_nodes_unique (gimple_bb (use_stmt)); }
static void prop_phis (basic_block b) { gimple_stmt_iterator psi; gimple_seq phis = phi_nodes (b); for (psi = gsi_start (phis); !gsi_end_p (psi); ) { gimple phi = gsi_stmt (psi); tree def = gimple_phi_result (phi), use = gimple_phi_arg_def (phi, 0); gcc_assert (gimple_phi_num_args (phi) == 1); if (!is_gimple_reg (def)) { imm_use_iterator iter; use_operand_p use_p; gimple stmt; FOR_EACH_IMM_USE_STMT (stmt, iter, def) FOR_EACH_IMM_USE_ON_STMT (use_p, iter) SET_USE (use_p, use); } else replace_uses_by (def, use); remove_phi_node (&psi, true); } }
static void replace_exp_1 (use_operand_p op_p, tree val, bool for_propagation ATTRIBUTE_UNUSED) { #if defined ENABLE_CHECKING tree op = USE_FROM_PTR (op_p); gcc_assert (!(for_propagation && TREE_CODE (op) == SSA_NAME && TREE_CODE (val) == SSA_NAME && !may_propagate_copy (op, val))); #endif if (TREE_CODE (val) == SSA_NAME) SET_USE (op_p, val); else SET_USE (op_p, unsave_expr_now (val)); }
static void replace_exp_1 (use_operand_p op_p, tree val, bool for_propagation ATTRIBUTE_UNUSED) { tree op = USE_FROM_PTR (op_p); #if defined ENABLE_CHECKING gcc_assert (!(for_propagation && TREE_CODE (op) == SSA_NAME && TREE_CODE (val) == SSA_NAME && !may_propagate_copy (op, val))); #endif if (TREE_CODE (val) == SSA_NAME) { if (TREE_CODE (op) == SSA_NAME && POINTER_TYPE_P (TREE_TYPE (op))) merge_alias_info (op, val); SET_USE (op_p, val); } else SET_USE (op_p, unsave_expr_now (val)); }
static inline void replace_reciprocal (use_operand_p use_p) { gimple use_stmt = USE_STMT (use_p); basic_block bb = gimple_bb (use_stmt); struct occurrence *occ = (struct occurrence *) bb->aux; if (optimize_bb_for_speed_p (bb) && occ->recip_def && use_stmt != occ->recip_def_stmt) { gimple_assign_set_rhs_code (use_stmt, MULT_EXPR); SET_USE (use_p, occ->recip_def); fold_stmt_inplace (use_stmt); update_stmt (use_stmt); } }
void unlink_stmt_vdef (gimple stmt) { use_operand_p use_p; imm_use_iterator iter; gimple use_stmt; tree vdef = gimple_vdef (stmt); if (!vdef || TREE_CODE (vdef) != SSA_NAME) return; FOR_EACH_IMM_USE_STMT (use_stmt, iter, gimple_vdef (stmt)) { FOR_EACH_IMM_USE_ON_STMT (use_p, iter) SET_USE (use_p, gimple_vuse (stmt)); }
static void replace_phi_edge_with_variable (basic_block cond_block, edge e, gimple phi, tree new_tree) { basic_block bb = gimple_bb (phi); basic_block block_to_remove; gimple_stmt_iterator gsi; /* Change the PHI argument to new. */ SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new_tree); /* Remove the empty basic block. */ if (EDGE_SUCC (cond_block, 0)->dest == bb) { EDGE_SUCC (cond_block, 0)->flags |= EDGE_FALLTHRU; EDGE_SUCC (cond_block, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE); EDGE_SUCC (cond_block, 0)->probability = REG_BR_PROB_BASE; EDGE_SUCC (cond_block, 0)->count += EDGE_SUCC (cond_block, 1)->count; block_to_remove = EDGE_SUCC (cond_block, 1)->dest; } else { EDGE_SUCC (cond_block, 1)->flags |= EDGE_FALLTHRU; EDGE_SUCC (cond_block, 1)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE); EDGE_SUCC (cond_block, 1)->probability = REG_BR_PROB_BASE; EDGE_SUCC (cond_block, 1)->count += EDGE_SUCC (cond_block, 0)->count; block_to_remove = EDGE_SUCC (cond_block, 0)->dest; } delete_basic_block (block_to_remove); /* Eliminate the COND_EXPR at the end of COND_BLOCK. */ gsi = gsi_last_bb (cond_block); gsi_remove (&gsi, true); if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n", cond_block->index, bb->index); }
static tree rewrite_bittest (block_stmt_iterator *bsi) { tree stmt, lhs, rhs, var, name, use_stmt, stmt1, stmt2, t; use_operand_p use; stmt = bsi_stmt (*bsi); lhs = GENERIC_TREE_OPERAND (stmt, 0); rhs = GENERIC_TREE_OPERAND (stmt, 1); /* Verify that the single use of lhs is a comparison against zero. */ if (TREE_CODE (lhs) != SSA_NAME || !single_imm_use (lhs, &use, &use_stmt) || TREE_CODE (use_stmt) != COND_EXPR) return stmt; t = COND_EXPR_COND (use_stmt); if (TREE_OPERAND (t, 0) != lhs || (TREE_CODE (t) != NE_EXPR && TREE_CODE (t) != EQ_EXPR) || !integer_zerop (TREE_OPERAND (t, 1))) return stmt; /* Get at the operands of the shift. The rhs is TMP1 & 1. */ stmt1 = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0)); if (TREE_CODE (stmt1) != GIMPLE_MODIFY_STMT) return stmt; /* There is a conversion in between possibly inserted by fold. */ t = GIMPLE_STMT_OPERAND (stmt1, 1); if (TREE_CODE (t) == NOP_EXPR || TREE_CODE (t) == CONVERT_EXPR) { t = TREE_OPERAND (t, 0); if (TREE_CODE (t) != SSA_NAME || !has_single_use (t)) return stmt; stmt1 = SSA_NAME_DEF_STMT (t); if (TREE_CODE (stmt1) != GIMPLE_MODIFY_STMT) return stmt; t = GIMPLE_STMT_OPERAND (stmt1, 1); } /* Verify that B is loop invariant but A is not. Verify that with all the stmt walking we are still in the same loop. */ if (TREE_CODE (t) == RSHIFT_EXPR && loop_containing_stmt (stmt1) == loop_containing_stmt (stmt) && outermost_invariant_loop_expr (TREE_OPERAND (t, 1), loop_containing_stmt (stmt1)) != NULL && outermost_invariant_loop_expr (TREE_OPERAND (t, 0), loop_containing_stmt (stmt1)) == NULL) { tree a = TREE_OPERAND (t, 0); tree b = TREE_OPERAND (t, 1); /* 1 << B */ var = create_tmp_var (TREE_TYPE (a), "shifttmp"); add_referenced_var (var); t = fold_build2 (LSHIFT_EXPR, TREE_TYPE (a), build_int_cst (TREE_TYPE (a), 1), b); stmt1 = build_gimple_modify_stmt (var, t); name = make_ssa_name (var, stmt1); GIMPLE_STMT_OPERAND (stmt1, 0) = name; /* A & (1 << B) */ t = fold_build2 (BIT_AND_EXPR, TREE_TYPE (a), a, name); stmt2 = build_gimple_modify_stmt (var, t); name = make_ssa_name (var, stmt2); GIMPLE_STMT_OPERAND (stmt2, 0) = name; /* Replace the SSA_NAME we compare against zero. Adjust the type of zero accordingly. */ SET_USE (use, name); TREE_OPERAND (COND_EXPR_COND (use_stmt), 1) = build_int_cst_type (TREE_TYPE (name), 0); bsi_insert_before (bsi, stmt1, BSI_SAME_STMT); bsi_replace (bsi, stmt2, true); return stmt1; } return stmt; }