void backprop::optimize_assign (gassign *assign, tree lhs, const usage_info *info) { switch (gimple_assign_rhs_code (assign)) { case MULT_EXPR: case RDIV_EXPR: /* If the sign of the result doesn't matter, strip sign operations from both inputs. */ if (info->flags.ignore_sign) replace_assign_rhs (assign, lhs, strip_sign_op (gimple_assign_rhs1 (assign)), strip_sign_op (gimple_assign_rhs2 (assign)), NULL_TREE); break; case COND_EXPR: /* If the sign of A ? B : C doesn't matter, strip sign operations from both B and C. */ if (info->flags.ignore_sign) replace_assign_rhs (assign, lhs, NULL_TREE, strip_sign_op (gimple_assign_rhs2 (assign)), strip_sign_op (gimple_assign_rhs3 (assign))); break; default: break; } }
void backprop::optimize_phi (gphi *phi, tree var, const usage_info *info) { /* If the sign of the result doesn't matter, try to strip sign operations from arguments. */ if (info->flags.ignore_sign) { basic_block bb = gimple_bb (phi); use_operand_p use; ssa_op_iter oi; bool replaced = false; FOR_EACH_PHI_ARG (use, phi, oi, SSA_OP_USE) { /* Propagating along abnormal edges is delicate, punt for now. */ const int index = PHI_ARG_INDEX_FROM_USE (use); if (EDGE_PRED (bb, index)->flags & EDGE_ABNORMAL) continue; tree new_arg = strip_sign_op (USE_FROM_PTR (use)); if (new_arg) { if (!replaced) prepare_change (var); if (dump_file && (dump_flags & TDF_DETAILS)) note_replacement (phi, USE_FROM_PTR (use), new_arg); replace_exp (use, new_arg); replaced = true; } } }
void backprop::optimize_builtin_call (gcall *call, tree lhs, const usage_info *info) { /* If we have an f such that -f(x) = f(-x), and if the sign of the result doesn't matter, strip any sign operations from the input. */ if (info->flags.ignore_sign && negate_mathfn_p (gimple_call_combined_fn (call))) { tree new_arg = strip_sign_op (gimple_call_arg (call, 0)); if (new_arg) { prepare_change (lhs); gimple_call_set_arg (call, 0, new_arg); complete_change (call); } } }
void backprop::optimize_phi (gphi *phi, tree var, const usage_info *info) { /* If the sign of the result doesn't matter, strip sign operations from all arguments. */ if (info->flags.ignore_sign) { use_operand_p use; ssa_op_iter oi; bool replaced = false; FOR_EACH_PHI_ARG (use, phi, oi, SSA_OP_USE) { tree new_arg = strip_sign_op (USE_FROM_PTR (use)); if (new_arg) { if (!replaced) prepare_change (var); if (dump_file && (dump_flags & TDF_DETAILS)) note_replacement (phi, USE_FROM_PTR (use), new_arg); replace_exp (use, new_arg); replaced = true; } }