aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/expr.cc')
-rw-r--r--gcc/expr.cc103
1 files changed, 58 insertions, 45 deletions
diff --git a/gcc/expr.cc b/gcc/expr.cc
index 502518d..ee822c1 100644
--- a/gcc/expr.cc
+++ b/gcc/expr.cc
@@ -11038,6 +11038,62 @@ stmt_is_replaceable_p (gimple *stmt)
return false;
}
+/* A subroutine of expand_expr_real_1. Expand gimple assignment G,
+ which is known to set an SSA_NAME result. The other arguments are
+ as for expand_expr_real_1. */
+
+rtx
+expand_expr_real_gassign (gassign *g, rtx target, machine_mode tmode,
+ enum expand_modifier modifier, rtx *alt_rtl,
+ bool inner_reference_p)
+{
+ separate_ops ops;
+ rtx r;
+ location_t saved_loc = curr_insn_location ();
+ auto loc = gimple_location (g);
+ if (loc != UNKNOWN_LOCATION)
+ set_curr_insn_location (loc);
+ tree lhs = gimple_assign_lhs (g);
+ ops.code = gimple_assign_rhs_code (g);
+ ops.type = TREE_TYPE (lhs);
+ switch (get_gimple_rhs_class (ops.code))
+ {
+ case GIMPLE_TERNARY_RHS:
+ ops.op2 = gimple_assign_rhs3 (g);
+ /* Fallthru */
+ case GIMPLE_BINARY_RHS:
+ ops.op1 = gimple_assign_rhs2 (g);
+
+ /* Try to expand conditonal compare. */
+ if (targetm.gen_ccmp_first)
+ {
+ gcc_checking_assert (targetm.gen_ccmp_next != NULL);
+ r = expand_ccmp_expr (g, TYPE_MODE (ops.type));
+ if (r)
+ break;
+ }
+ /* Fallthru */
+ case GIMPLE_UNARY_RHS:
+ ops.op0 = gimple_assign_rhs1 (g);
+ ops.location = loc;
+ r = expand_expr_real_2 (&ops, target, tmode, modifier);
+ break;
+ case GIMPLE_SINGLE_RHS:
+ {
+ r = expand_expr_real (gimple_assign_rhs1 (g), target,
+ tmode, modifier, alt_rtl,
+ inner_reference_p);
+ break;
+ }
+ default:
+ gcc_unreachable ();
+ }
+ set_curr_insn_location (saved_loc);
+ if (REG_P (r) && !REG_EXPR (r))
+ set_reg_attrs_for_decl_rtl (lhs, r);
+ return r;
+}
+
rtx
expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
enum expand_modifier modifier, rtx *alt_rtl,
@@ -11201,51 +11257,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
&& stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
g = SSA_NAME_DEF_STMT (exp);
if (g)
- {
- rtx r;
- location_t saved_loc = curr_insn_location ();
- loc = gimple_location (g);
- if (loc != UNKNOWN_LOCATION)
- set_curr_insn_location (loc);
- ops.code = gimple_assign_rhs_code (g);
- switch (get_gimple_rhs_class (ops.code))
- {
- case GIMPLE_TERNARY_RHS:
- ops.op2 = gimple_assign_rhs3 (g);
- /* Fallthru */
- case GIMPLE_BINARY_RHS:
- ops.op1 = gimple_assign_rhs2 (g);
-
- /* Try to expand conditonal compare. */
- if (targetm.gen_ccmp_first)
- {
- gcc_checking_assert (targetm.gen_ccmp_next != NULL);
- r = expand_ccmp_expr (g, mode);
- if (r)
- break;
- }
- /* Fallthru */
- case GIMPLE_UNARY_RHS:
- ops.op0 = gimple_assign_rhs1 (g);
- ops.type = TREE_TYPE (gimple_assign_lhs (g));
- ops.location = loc;
- r = expand_expr_real_2 (&ops, target, tmode, modifier);
- break;
- case GIMPLE_SINGLE_RHS:
- {
- r = expand_expr_real (gimple_assign_rhs1 (g), target,
- tmode, modifier, alt_rtl,
- inner_reference_p);
- break;
- }
- default:
- gcc_unreachable ();
- }
- set_curr_insn_location (saved_loc);
- if (REG_P (r) && !REG_EXPR (r))
- set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (exp), r);
- return r;
- }
+ return expand_expr_real_gassign (as_a<gassign *> (g), target, tmode,
+ modifier, alt_rtl, inner_reference_p);
ssa_name = exp;
decl_rtl = get_rtx_for_ssa_name (ssa_name);