1 /* D-specific tree lowering bits; see also gimple.cc. 2 Copyright (C) 2020-2022 Free Software Foundation, Inc. 3 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) 7 any later version. 8 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. 13 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/>. */ 17 18 #include "config.h" 19 #include "system.h" 20 #include "coretypes.h" 21 22 #include "dmd/globals.h" 23 24 #include "tree.h" 25 #include "gimple-expr.h" 26 #include "gimplify.h" 27 28 #include "d-tree.h" 29 30 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. */ 33 34 static bool 35 empty_modify_p (tree type, tree op) 36 { 37 tree_code code = TREE_CODE (op); 38 switch (code) 39 { 40 case COMPOUND_EXPR: 41 return empty_modify_p (type, TREE_OPERAND (op, 1)); 42 43 case CONSTRUCTOR: 44 /* Non-empty construcors are valid. */ 45 if (CONSTRUCTOR_NELTS (op) != 0 || TREE_CLOBBER_P (op)) 46 return false; 47 break; 48 49 case CALL_EXPR: 50 /* Leave nrvo alone because it isn't a copy. */ 51 if (CALL_EXPR_RETURN_SLOT_OPT (op)) 52 return false; 53 break; 54 55 default: 56 /* If the operand doesn't have a simple form. */ 57 if (!is_gimple_lvalue (op) && !INDIRECT_REF_P (op)) 58 return false; 59 break; 60 } 61 62 return empty_aggregate_p (type); 63 } 64 65 /* Return TRUE if EXPR is a COMPONENT_REF to a bit-field declaration. */ 66 67 static bool 68 bit_field_ref (const_tree expr) 69 { 70 if (TREE_CODE (expr) == COMPONENT_REF 71 && DECL_BIT_FIELD (TREE_OPERAND (expr, 1))) 72 return true; 73 74 return false; 75 } 76 77 /* Gimplify assignment from an INIT_EXPR or MODIFY_EXPR. */ 78 79 static gimplify_status 80 d_gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 81 { 82 tree op0 = TREE_OPERAND (*expr_p, 0); 83 tree op1 = TREE_OPERAND (*expr_p, 1); 84 85 if (error_operand_p (op0) || error_operand_p (op1)) 86 return GS_UNHANDLED; 87 88 /* Remove any copies of empty aggregates. */ 89 if (empty_modify_p (TREE_TYPE (op0), op1)) 90 { 91 gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p, 92 is_gimple_lvalue, fb_lvalue); 93 94 if (TREE_SIDE_EFFECTS (op1)) 95 gimplify_and_add (op1, pre_p); 96 97 *expr_p = TREE_OPERAND (*expr_p, 0); 98 return GS_OK; 99 } 100 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))) 105 { 106 TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR, 107 TREE_TYPE (op0), op1); 108 return GS_OK; 109 } 110 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)) 114 { 115 TREE_OPERAND (*expr_p, 1) = convert (TREE_TYPE (op0), op1); 116 return GS_OK; 117 } 118 119 return GS_UNHANDLED; 120 } 121 122 /* Gimplify an ADDR_EXPR node. */ 123 124 static gimplify_status 125 d_gimplify_addr_expr (tree *expr_p) 126 { 127 tree op0 = TREE_OPERAND (*expr_p, 0); 128 /* Constructors are not lvalues, so make them one. */ 129 if (TREE_CODE (op0) == CONSTRUCTOR) 130 { 131 TREE_OPERAND (*expr_p, 0) = force_target_expr (op0); 132 return GS_OK; 133 } 134 135 return GS_UNHANDLED; 136 } 137 138 /* Gimplify a CALL_EXPR node. */ 139 140 static gimplify_status 141 d_gimplify_call_expr (tree *expr_p, gimple_seq *pre_p) 142 { 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); 146 147 /* No need to enforce evaluation order if only one argument. */ 148 if (nargs < 2) 149 return GS_UNHANDLED; 150 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++) 154 { 155 if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i))) 156 { 157 has_side_effects = true; 158 break; 159 } 160 } 161 162 if (!has_side_effects) 163 return GS_UNHANDLED; 164 165 /* Leave the last argument for gimplify_call_expr. */ 166 for (int i = 0; i < nargs - 1; i++) 167 { 168 tree new_arg = CALL_EXPR_ARG (*expr_p, i); 169 170 /* If argument has a side-effect, gimplify_arg will handle it. */ 171 if (gimplify_arg (&new_arg, pre_p, loc) == GS_ERROR) 172 return GS_ERROR; 173 174 /* Even if an argument itself doesn't have any side-effects, it 175 might be altered by another argument in the list. */ 176 if (new_arg == CALL_EXPR_ARG (*expr_p, i) 177 && !really_constant_p (new_arg)) 178 new_arg = get_formal_tmp_var (new_arg, pre_p); 179 180 CALL_EXPR_ARG (*expr_p, i) = new_arg; 181 } 182 183 return GS_OK; 184 } 185 186 /* Gimplify an UNSIGNED_RSHIFT_EXPR node. */ 187 188 static gimplify_status 189 d_gimplify_unsigned_rshift_expr (tree *expr_p) 190 { 191 /* Convert op0 to an unsigned type. */ 192 tree op0 = TREE_OPERAND (*expr_p, 0); 193 tree op1 = TREE_OPERAND (*expr_p, 1); 194 tree type = d_unsigned_type (TREE_TYPE (op0)); 195 196 *expr_p = convert (TREE_TYPE (*expr_p), 197 build2 (RSHIFT_EXPR, type, convert (type, op0), op1)); 198 return GS_OK; 199 } 200 201 /* Gimplify an unary expression node. */ 202 203 static gimplify_status 204 d_gimplify_unary_expr (tree *expr_p) 205 { 206 tree op0 = TREE_OPERAND (*expr_p, 0); 207 208 if (error_operand_p (op0)) 209 return GS_UNHANDLED; 210 211 /* Front end doesn't know that bit-field types are really different 212 from basic types, add an explicit conversion in unary expressions. */ 213 if (bit_field_ref (op0) && TREE_TYPE (op0) != TREE_TYPE (*expr_p)) 214 { 215 TREE_OPERAND (*expr_p, 0) = convert (TREE_TYPE (*expr_p), op0); 216 return GS_OK; 217 } 218 219 return GS_UNHANDLED; 220 } 221 222 /* Gimplify a binary expression node. */ 223 224 static gimplify_status 225 d_gimplify_binary_expr (tree *expr_p) 226 { 227 tree op0 = TREE_OPERAND (*expr_p, 0); 228 tree op1 = TREE_OPERAND (*expr_p, 1); 229 230 if (error_operand_p (op0) || error_operand_p (op1)) 231 return GS_UNHANDLED; 232 233 /* Front end doesn't know that bit-field types are really different 234 from basic types, add an explicit conversion in binary expressions. */ 235 if (bit_field_ref (op0) || bit_field_ref (op1)) 236 { 237 if (TREE_TYPE (op0) != TREE_TYPE (*expr_p)) 238 TREE_OPERAND (*expr_p, 0) = convert (TREE_TYPE (*expr_p), op0); 239 240 if (TREE_TYPE (op1) != TREE_TYPE (*expr_p)) 241 TREE_OPERAND (*expr_p, 1) = convert (TREE_TYPE (*expr_p), op1); 242 243 return GS_OK; 244 } 245 246 return GS_UNHANDLED; 247 } 248 249 /* Implements the lang_hooks.gimplify_expr routine for language D. 250 Do gimplification of D specific expression trees in EXPR_P. */ 251 252 int 253 d_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) 254 { 255 switch (TREE_CODE (*expr_p)) 256 { 257 case INIT_EXPR: 258 case MODIFY_EXPR: 259 return d_gimplify_modify_expr (expr_p, pre_p, post_p); 260 261 case ADDR_EXPR: 262 return d_gimplify_addr_expr (expr_p); 263 264 case CALL_EXPR: 265 return d_gimplify_call_expr (expr_p, pre_p); 266 267 case UNSIGNED_RSHIFT_EXPR: 268 return d_gimplify_unsigned_rshift_expr (expr_p); 269 270 case FLOAT_MOD_EXPR: 271 gcc_unreachable (); 272 273 default: 274 if (UNARY_CLASS_P (*expr_p) && !CONVERT_EXPR_P (*expr_p)) 275 return d_gimplify_unary_expr (expr_p); 276 if (BINARY_CLASS_P (*expr_p)) 277 return d_gimplify_binary_expr (expr_p); 278 break; 279 } 280 281 return GS_UNHANDLED; 282 } 283