1 /* D-specific tree lowering bits; see also gimple.cc.
2 Copyright (C) 2020-2023 Free Software Foundation, Inc.
4 GCC is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
9 GCC is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with GCC; see the file COPYING3. If not see
16 <http://www.gnu.org/licenses/>. */
20 #include "coretypes.h"
22 #include "dmd/globals.h"
25 #include "gimple-expr.h"
31 /* Return TRUE if an operand OP of a given TYPE being copied has no data.
32 The middle-end does a similar check with zero sized types. */
35 empty_modify_p (tree type
, tree op
)
37 tree_code code
= TREE_CODE (op
);
41 return empty_modify_p (type
, TREE_OPERAND (op
, 1));
44 /* Non-empty construcors are valid. */
45 if (CONSTRUCTOR_NELTS (op
) != 0 || TREE_CLOBBER_P (op
))
50 /* Leave nrvo alone because it isn't a copy. */
51 if (CALL_EXPR_RETURN_SLOT_OPT (op
))
56 /* If the operand doesn't have a simple form. */
57 if (!is_gimple_lvalue (op
) && !INDIRECT_REF_P (op
))
62 return empty_aggregate_p (type
);
65 /* Return TRUE if EXPR is a COMPONENT_REF to a bit-field declaration. */
68 bit_field_ref (const_tree expr
)
70 if (TREE_CODE (expr
) == COMPONENT_REF
71 && DECL_BIT_FIELD (TREE_OPERAND (expr
, 1)))
77 /* Gimplify assignment from an INIT_EXPR or MODIFY_EXPR. */
79 static gimplify_status
80 d_gimplify_modify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
82 tree op0
= TREE_OPERAND (*expr_p
, 0);
83 tree op1
= TREE_OPERAND (*expr_p
, 1);
85 if (error_operand_p (op0
) || error_operand_p (op1
))
88 /* Remove any copies of empty aggregates. */
89 if (empty_modify_p (TREE_TYPE (op0
), op1
))
91 gimplify_expr (&TREE_OPERAND (*expr_p
, 0), pre_p
, post_p
,
92 is_gimple_lvalue
, fb_lvalue
);
94 if (TREE_SIDE_EFFECTS (op1
))
95 gimplify_and_add (op1
, pre_p
);
97 *expr_p
= TREE_OPERAND (*expr_p
, 0);
101 /* If the back end isn't clever enough to know that the lhs and rhs
102 types are the same, add an explicit conversion. */
103 if ((AGGREGATE_TYPE_P (TREE_TYPE (op0
)) || AGGREGATE_TYPE_P (TREE_TYPE (op1
)))
104 && !useless_type_conversion_p (TREE_TYPE (op1
), TREE_TYPE (op0
)))
106 TREE_OPERAND (*expr_p
, 1) = build1 (VIEW_CONVERT_EXPR
,
107 TREE_TYPE (op0
), op1
);
111 /* Same as above, but for bit-field assignments. */
112 if ((bit_field_ref (op0
) || bit_field_ref (op1
))
113 && TREE_TYPE (op0
) != TREE_TYPE (op1
))
115 TREE_OPERAND (*expr_p
, 1) = convert (TREE_TYPE (op0
), op1
);
122 /* Gimplify an ADDR_EXPR node. */
124 static gimplify_status
125 d_gimplify_addr_expr (tree
*expr_p
)
127 tree op0
= TREE_OPERAND (*expr_p
, 0);
128 /* Constructors are not lvalues, so make them one. */
129 if (TREE_CODE (op0
) == CONSTRUCTOR
)
131 TREE_OPERAND (*expr_p
, 0) = force_target_expr (op0
);
138 /* Gimplify a CALL_EXPR node. */
140 static gimplify_status
141 d_gimplify_call_expr (tree
*expr_p
, gimple_seq
*pre_p
)
143 /* Strictly evaluate all arguments from left to right. */
144 int nargs
= call_expr_nargs (*expr_p
);
145 location_t loc
= EXPR_LOC_OR_LOC (*expr_p
, input_location
);
147 /* No need to enforce evaluation order if only one argument. */
151 /* Or if all arguments are already free of side-effects. */
152 bool has_side_effects
= false;
153 for (int i
= 0; i
< nargs
; i
++)
155 if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p
, i
)))
157 has_side_effects
= true;
162 if (!has_side_effects
)
165 /* Evaluate the callee before calling it. */
166 tree new_call_fn
= CALL_EXPR_FN (*expr_p
);
168 if (gimplify_expr (&new_call_fn
, pre_p
, NULL
,
169 is_gimple_call_addr
, fb_rvalue
) == GS_ERROR
)
172 CALL_EXPR_FN (*expr_p
) = new_call_fn
;
174 /* Leave the last argument for gimplify_call_expr. */
175 for (int i
= 0; i
< nargs
- 1; i
++)
177 tree new_arg
= CALL_EXPR_ARG (*expr_p
, i
);
179 /* If argument has a side-effect, gimplify_arg will handle it. */
180 if (gimplify_arg (&new_arg
, pre_p
, loc
) == GS_ERROR
)
183 /* Even if an argument itself doesn't have any side-effects, it
184 might be altered by another argument in the list. */
185 if (new_arg
== CALL_EXPR_ARG (*expr_p
, i
)
186 && !really_constant_p (new_arg
))
187 new_arg
= get_formal_tmp_var (new_arg
, pre_p
);
189 CALL_EXPR_ARG (*expr_p
, i
) = new_arg
;
195 /* Gimplify an UNSIGNED_RSHIFT_EXPR node. */
197 static gimplify_status
198 d_gimplify_unsigned_rshift_expr (tree
*expr_p
)
200 /* Convert op0 to an unsigned type. */
201 tree op0
= TREE_OPERAND (*expr_p
, 0);
202 tree op1
= TREE_OPERAND (*expr_p
, 1);
203 tree type
= d_unsigned_type (TREE_TYPE (op0
));
205 *expr_p
= convert (TREE_TYPE (*expr_p
),
206 build2 (RSHIFT_EXPR
, type
, convert (type
, op0
), op1
));
210 /* Gimplify an unary expression node. */
212 static gimplify_status
213 d_gimplify_unary_expr (tree
*expr_p
)
215 tree op0
= TREE_OPERAND (*expr_p
, 0);
217 if (error_operand_p (op0
))
220 /* Front end doesn't know that bit-field types are really different
221 from basic types, add an explicit conversion in unary expressions. */
222 if (bit_field_ref (op0
) && TREE_TYPE (op0
) != TREE_TYPE (*expr_p
))
224 TREE_OPERAND (*expr_p
, 0) = convert (TREE_TYPE (*expr_p
), op0
);
231 /* Gimplify a binary expression node. */
233 static gimplify_status
234 d_gimplify_binary_expr (tree
*expr_p
)
236 tree op0
= TREE_OPERAND (*expr_p
, 0);
237 tree op1
= TREE_OPERAND (*expr_p
, 1);
239 if (error_operand_p (op0
) || error_operand_p (op1
))
242 /* Front end doesn't know that bit-field types are really different
243 from basic types, add an explicit conversion in binary expressions. */
244 if (bit_field_ref (op0
) || bit_field_ref (op1
))
246 if (TREE_TYPE (op0
) != TREE_TYPE (*expr_p
))
247 TREE_OPERAND (*expr_p
, 0) = convert (TREE_TYPE (*expr_p
), op0
);
249 if (TREE_TYPE (op1
) != TREE_TYPE (*expr_p
))
250 TREE_OPERAND (*expr_p
, 1) = convert (TREE_TYPE (*expr_p
), op1
);
258 /* Implements the lang_hooks.gimplify_expr routine for language D.
259 Do gimplification of D specific expression trees in EXPR_P. */
262 d_gimplify_expr (tree
*expr_p
, gimple_seq
*pre_p
, gimple_seq
*post_p
)
264 switch (TREE_CODE (*expr_p
))
268 return d_gimplify_modify_expr (expr_p
, pre_p
, post_p
);
271 return d_gimplify_addr_expr (expr_p
);
274 return d_gimplify_call_expr (expr_p
, pre_p
);
276 case UNSIGNED_RSHIFT_EXPR
:
277 return d_gimplify_unsigned_rshift_expr (expr_p
);
283 if (UNARY_CLASS_P (*expr_p
) && !CONVERT_EXPR_P (*expr_p
))
284 return d_gimplify_unary_expr (expr_p
);
285 if (BINARY_CLASS_P (*expr_p
))
286 return d_gimplify_binary_expr (expr_p
);