Mercurial > hg > CbC > CbC_gcc
comparison gcc/c/c-fold.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Support for fully folding sub-trees of an expression for C compiler. | 1 /* Support for fully folding sub-trees of an expression for C compiler. |
2 Copyright (C) 1992-2017 Free Software Foundation, Inc. | 2 Copyright (C) 1992-2018 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
7 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
25 #include "bitmap.h" | 25 #include "bitmap.h" |
26 #include "c-tree.h" | 26 #include "c-tree.h" |
27 #include "intl.h" | 27 #include "intl.h" |
28 #include "gimplify.h" | 28 #include "gimplify.h" |
29 | 29 |
30 static tree c_fully_fold_internal (tree expr, bool, bool *, bool *, bool); | 30 static tree c_fully_fold_internal (tree expr, bool, bool *, bool *, bool, |
31 bool); | |
31 | 32 |
32 /* If DISABLE is true, stop issuing warnings. This is used when | 33 /* If DISABLE is true, stop issuing warnings. This is used when |
33 parsing code that we know will not be executed. This function may | 34 parsing code that we know will not be executed. This function may |
34 be called multiple times, and works as a stack. */ | 35 be called multiple times, and works as a stack. */ |
35 | 36 |
51 if (enable) | 52 if (enable) |
52 { | 53 { |
53 --c_inhibit_evaluation_warnings; | 54 --c_inhibit_evaluation_warnings; |
54 fold_undefer_and_ignore_overflow_warnings (); | 55 fold_undefer_and_ignore_overflow_warnings (); |
55 } | 56 } |
57 } | |
58 | |
59 /* Try to fold ARRAY_REF ary[index] if possible and not handled by | |
60 normal fold, return NULL_TREE otherwise. */ | |
61 | |
62 static tree | |
63 c_fold_array_ref (tree type, tree ary, tree index) | |
64 { | |
65 if (TREE_CODE (ary) != STRING_CST | |
66 || TREE_CODE (index) != INTEGER_CST | |
67 || TREE_OVERFLOW (index) | |
68 || TREE_CODE (TREE_TYPE (ary)) != ARRAY_TYPE | |
69 || !tree_fits_uhwi_p (index)) | |
70 return NULL_TREE; | |
71 | |
72 tree elem_type = TREE_TYPE (TREE_TYPE (ary)); | |
73 unsigned elem_nchars = (TYPE_PRECISION (elem_type) | |
74 / TYPE_PRECISION (char_type_node)); | |
75 unsigned len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars; | |
76 tree nelts = array_type_nelts (TREE_TYPE (ary)); | |
77 bool dummy1 = true, dummy2 = true; | |
78 nelts = c_fully_fold_internal (nelts, true, &dummy1, &dummy2, false, false); | |
79 unsigned HOST_WIDE_INT i = tree_to_uhwi (index); | |
80 if (!tree_int_cst_le (index, nelts) | |
81 || i >= len | |
82 || i + elem_nchars > len) | |
83 return NULL_TREE; | |
84 | |
85 if (elem_nchars == 1) | |
86 return build_int_cst (type, TREE_STRING_POINTER (ary)[i]); | |
87 | |
88 const unsigned char *ptr | |
89 = ((const unsigned char *)TREE_STRING_POINTER (ary) + i * elem_nchars); | |
90 return native_interpret_expr (type, ptr, elem_nchars); | |
56 } | 91 } |
57 | 92 |
58 /* Fully fold EXPR, an expression that was not folded (beyond integer | 93 /* Fully fold EXPR, an expression that was not folded (beyond integer |
59 constant expressions and null pointer constants) when being built | 94 constant expressions and null pointer constants) when being built |
60 up. If IN_INIT, this is in a static initializer and certain | 95 up. If IN_INIT, this is in a static initializer and certain |
66 evaluated arithmetic overflow. (*MAYBE_CONST should typically be | 101 evaluated arithmetic overflow. (*MAYBE_CONST should typically be |
67 set to true by callers before calling this function.) Return the | 102 set to true by callers before calling this function.) Return the |
68 folded expression. Function arguments have already been folded | 103 folded expression. Function arguments have already been folded |
69 before calling this function, as have the contents of SAVE_EXPR, | 104 before calling this function, as have the contents of SAVE_EXPR, |
70 TARGET_EXPR, BIND_EXPR, VA_ARG_EXPR, OBJ_TYPE_REF and | 105 TARGET_EXPR, BIND_EXPR, VA_ARG_EXPR, OBJ_TYPE_REF and |
71 C_MAYBE_CONST_EXPR. */ | 106 C_MAYBE_CONST_EXPR. LVAL is true if it should be treated as an |
107 lvalue. */ | |
72 | 108 |
73 tree | 109 tree |
74 c_fully_fold (tree expr, bool in_init, bool *maybe_const) | 110 c_fully_fold (tree expr, bool in_init, bool *maybe_const, bool lval) |
75 { | 111 { |
76 tree ret; | 112 tree ret; |
77 tree eptype = NULL_TREE; | 113 tree eptype = NULL_TREE; |
78 bool dummy = true; | 114 bool dummy = true; |
79 bool maybe_const_itself = true; | 115 bool maybe_const_itself = true; |
85 { | 121 { |
86 eptype = TREE_TYPE (expr); | 122 eptype = TREE_TYPE (expr); |
87 expr = TREE_OPERAND (expr, 0); | 123 expr = TREE_OPERAND (expr, 0); |
88 } | 124 } |
89 ret = c_fully_fold_internal (expr, in_init, maybe_const, | 125 ret = c_fully_fold_internal (expr, in_init, maybe_const, |
90 &maybe_const_itself, false); | 126 &maybe_const_itself, false, lval); |
91 if (eptype) | 127 if (eptype) |
92 ret = fold_convert_loc (loc, eptype, ret); | 128 ret = fold_convert_loc (loc, eptype, ret); |
93 *maybe_const &= maybe_const_itself; | 129 *maybe_const &= maybe_const_itself; |
94 return ret; | 130 return ret; |
95 } | 131 } |
100 arithmetic overflow (for C90, *MAYBE_CONST_OPERANDS is carried from | 136 arithmetic overflow (for C90, *MAYBE_CONST_OPERANDS is carried from |
101 both evaluated and unevaluated subexpressions while | 137 both evaluated and unevaluated subexpressions while |
102 *MAYBE_CONST_ITSELF is carried from only evaluated | 138 *MAYBE_CONST_ITSELF is carried from only evaluated |
103 subexpressions). FOR_INT_CONST indicates if EXPR is an expression | 139 subexpressions). FOR_INT_CONST indicates if EXPR is an expression |
104 with integer constant operands, and if any of the operands doesn't | 140 with integer constant operands, and if any of the operands doesn't |
105 get folded to an integer constant, don't fold the expression itself. */ | 141 get folded to an integer constant, don't fold the expression itself. |
142 LVAL indicates folding of lvalue, where we can't replace it with | |
143 an rvalue. */ | |
106 | 144 |
107 static tree | 145 static tree |
108 c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, | 146 c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, |
109 bool *maybe_const_itself, bool for_int_const) | 147 bool *maybe_const_itself, bool for_int_const, bool lval) |
110 { | 148 { |
111 tree ret = expr; | 149 tree ret = expr; |
112 enum tree_code code = TREE_CODE (expr); | 150 enum tree_code code = TREE_CODE (expr); |
113 enum tree_code_class kind = TREE_CODE_CLASS (code); | 151 enum tree_code_class kind = TREE_CODE_CLASS (code); |
114 location_t loc = EXPR_LOCATION (expr); | 152 location_t loc = EXPR_LOCATION (expr); |
116 tree orig_op0, orig_op1, orig_op2; | 154 tree orig_op0, orig_op1, orig_op2; |
117 bool op0_const = true, op1_const = true, op2_const = true; | 155 bool op0_const = true, op1_const = true, op2_const = true; |
118 bool op0_const_self = true, op1_const_self = true, op2_const_self = true; | 156 bool op0_const_self = true, op1_const_self = true, op2_const_self = true; |
119 bool nowarning = TREE_NO_WARNING (expr); | 157 bool nowarning = TREE_NO_WARNING (expr); |
120 bool unused_p; | 158 bool unused_p; |
159 bool op0_lval = false; | |
121 source_range old_range; | 160 source_range old_range; |
122 | 161 |
123 /* Constants, declarations, statements, errors, and anything else not | 162 /* Constants, declarations, statements, errors, and anything else not |
124 counted as an expression cannot usefully be folded further at this | 163 counted as an expression cannot usefully be folded further at this |
125 point. */ | 164 point. */ |
126 if (!IS_EXPR_CODE_CLASS (kind) | 165 if (!IS_EXPR_CODE_CLASS (kind) || kind == tcc_statement) |
127 || kind == tcc_statement) | 166 { |
128 return expr; | 167 /* Except for variables which we can optimize to its initializer. */ |
168 if (VAR_P (expr) && !lval && (optimize || in_init)) | |
169 { | |
170 if (in_init) | |
171 ret = decl_constant_value_1 (expr, true); | |
172 else | |
173 { | |
174 ret = decl_constant_value (expr); | |
175 if (ret != expr | |
176 && (TYPE_MODE (TREE_TYPE (ret)) == BLKmode | |
177 || TREE_CODE (TREE_TYPE (ret)) == ARRAY_TYPE)) | |
178 return expr; | |
179 } | |
180 /* Avoid unwanted tree sharing between the initializer and current | |
181 function's body where the tree can be modified e.g. by the | |
182 gimplifier. */ | |
183 if (ret != expr && TREE_STATIC (expr)) | |
184 ret = unshare_expr (ret); | |
185 return ret; | |
186 } | |
187 return expr; | |
188 } | |
129 | 189 |
130 if (IS_EXPR_CODE_CLASS (kind)) | 190 if (IS_EXPR_CODE_CLASS (kind)) |
131 old_range = EXPR_LOCATION_RANGE (expr); | 191 old_range = EXPR_LOCATION_RANGE (expr); |
132 | 192 |
133 /* Operands of variable-length expressions (function calls) have | 193 /* Operands of variable-length expressions (function calls) have |
148 *maybe_const_operands = false; | 208 *maybe_const_operands = false; |
149 if (C_MAYBE_CONST_EXPR_INT_OPERANDS (expr)) | 209 if (C_MAYBE_CONST_EXPR_INT_OPERANDS (expr)) |
150 { | 210 { |
151 *maybe_const_itself = false; | 211 *maybe_const_itself = false; |
152 inner = c_fully_fold_internal (inner, in_init, maybe_const_operands, | 212 inner = c_fully_fold_internal (inner, in_init, maybe_const_operands, |
153 maybe_const_itself, true); | 213 maybe_const_itself, true, lval); |
154 } | 214 } |
155 if (pre && !in_init) | 215 if (pre && !in_init) |
156 ret = build2 (COMPOUND_EXPR, TREE_TYPE (expr), pre, inner); | 216 ret = build2 (COMPOUND_EXPR, TREE_TYPE (expr), pre, inner); |
157 else | 217 else |
158 ret = inner; | 218 ret = inner; |
199 case COMPONENT_REF: | 259 case COMPONENT_REF: |
200 orig_op0 = op0 = TREE_OPERAND (expr, 0); | 260 orig_op0 = op0 = TREE_OPERAND (expr, 0); |
201 op1 = TREE_OPERAND (expr, 1); | 261 op1 = TREE_OPERAND (expr, 1); |
202 op2 = TREE_OPERAND (expr, 2); | 262 op2 = TREE_OPERAND (expr, 2); |
203 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, | 263 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, |
204 maybe_const_itself, for_int_const); | 264 maybe_const_itself, for_int_const, lval); |
205 STRIP_TYPE_NOPS (op0); | 265 STRIP_TYPE_NOPS (op0); |
206 if (op0 != orig_op0) | 266 if (op0 != orig_op0) |
207 ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2); | 267 ret = build3 (COMPONENT_REF, TREE_TYPE (expr), op0, op1, op2); |
208 if (ret != expr) | 268 if (ret != expr) |
209 { | 269 { |
210 TREE_READONLY (ret) = TREE_READONLY (expr); | 270 TREE_READONLY (ret) = TREE_READONLY (expr); |
211 TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr); | 271 TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr); |
212 } | 272 } |
273 if (!lval) | |
274 ret = fold (ret); | |
213 goto out; | 275 goto out; |
214 | 276 |
215 case ARRAY_REF: | 277 case ARRAY_REF: |
216 orig_op0 = op0 = TREE_OPERAND (expr, 0); | 278 orig_op0 = op0 = TREE_OPERAND (expr, 0); |
217 orig_op1 = op1 = TREE_OPERAND (expr, 1); | 279 orig_op1 = op1 = TREE_OPERAND (expr, 1); |
218 op2 = TREE_OPERAND (expr, 2); | 280 op2 = TREE_OPERAND (expr, 2); |
219 op3 = TREE_OPERAND (expr, 3); | 281 op3 = TREE_OPERAND (expr, 3); |
220 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, | 282 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, |
221 maybe_const_itself, for_int_const); | 283 maybe_const_itself, for_int_const, lval); |
222 STRIP_TYPE_NOPS (op0); | 284 STRIP_TYPE_NOPS (op0); |
223 op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, | 285 op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, |
224 maybe_const_itself, for_int_const); | 286 maybe_const_itself, for_int_const, false); |
225 STRIP_TYPE_NOPS (op1); | 287 STRIP_TYPE_NOPS (op1); |
226 op1 = decl_constant_value_for_optimization (op1); | 288 /* Fold "foo"[2] in initializers. */ |
289 if (!lval && in_init) | |
290 { | |
291 ret = c_fold_array_ref (TREE_TYPE (expr), op0, op1); | |
292 if (ret) | |
293 goto out; | |
294 ret = expr; | |
295 } | |
227 if (op0 != orig_op0 || op1 != orig_op1) | 296 if (op0 != orig_op0 || op1 != orig_op1) |
228 ret = build4 (ARRAY_REF, TREE_TYPE (expr), op0, op1, op2, op3); | 297 ret = build4 (ARRAY_REF, TREE_TYPE (expr), op0, op1, op2, op3); |
229 if (ret != expr) | 298 if (ret != expr) |
230 { | 299 { |
231 TREE_READONLY (ret) = TREE_READONLY (expr); | 300 TREE_READONLY (ret) = TREE_READONLY (expr); |
232 TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr); | 301 TREE_SIDE_EFFECTS (ret) = TREE_SIDE_EFFECTS (expr); |
233 TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr); | 302 TREE_THIS_VOLATILE (ret) = TREE_THIS_VOLATILE (expr); |
234 } | 303 } |
235 ret = fold (ret); | 304 if (!lval) |
236 goto out; | 305 ret = fold (ret); |
237 | 306 goto out; |
238 case COMPOUND_EXPR: | 307 |
239 case MODIFY_EXPR: | 308 case MODIFY_EXPR: |
240 case PREDECREMENT_EXPR: | 309 case PREDECREMENT_EXPR: |
241 case PREINCREMENT_EXPR: | 310 case PREINCREMENT_EXPR: |
242 case POSTDECREMENT_EXPR: | 311 case POSTDECREMENT_EXPR: |
243 case POSTINCREMENT_EXPR: | 312 case POSTINCREMENT_EXPR: |
313 op0_lval = true; | |
314 /* FALLTHRU */ | |
315 case COMPOUND_EXPR: | |
244 case PLUS_EXPR: | 316 case PLUS_EXPR: |
245 case MINUS_EXPR: | 317 case MINUS_EXPR: |
246 case MULT_EXPR: | 318 case MULT_EXPR: |
247 case POINTER_PLUS_EXPR: | 319 case POINTER_PLUS_EXPR: |
320 case POINTER_DIFF_EXPR: | |
248 case TRUNC_DIV_EXPR: | 321 case TRUNC_DIV_EXPR: |
249 case CEIL_DIV_EXPR: | 322 case CEIL_DIV_EXPR: |
250 case FLOOR_DIV_EXPR: | 323 case FLOOR_DIV_EXPR: |
251 case TRUNC_MOD_EXPR: | 324 case TRUNC_MOD_EXPR: |
252 case RDIV_EXPR: | 325 case RDIV_EXPR: |
276 /* Binary operations evaluating both arguments (increment and | 349 /* Binary operations evaluating both arguments (increment and |
277 decrement are binary internally in GCC). */ | 350 decrement are binary internally in GCC). */ |
278 orig_op0 = op0 = TREE_OPERAND (expr, 0); | 351 orig_op0 = op0 = TREE_OPERAND (expr, 0); |
279 orig_op1 = op1 = TREE_OPERAND (expr, 1); | 352 orig_op1 = op1 = TREE_OPERAND (expr, 1); |
280 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, | 353 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, |
281 maybe_const_itself, for_int_const); | 354 maybe_const_itself, for_int_const, |
355 op0_lval); | |
282 STRIP_TYPE_NOPS (op0); | 356 STRIP_TYPE_NOPS (op0); |
283 if (code != MODIFY_EXPR | |
284 && code != PREDECREMENT_EXPR | |
285 && code != PREINCREMENT_EXPR | |
286 && code != POSTDECREMENT_EXPR | |
287 && code != POSTINCREMENT_EXPR) | |
288 op0 = decl_constant_value_for_optimization (op0); | |
289 /* The RHS of a MODIFY_EXPR was fully folded when building that | 357 /* The RHS of a MODIFY_EXPR was fully folded when building that |
290 expression for the sake of conversion warnings. */ | 358 expression for the sake of conversion warnings. */ |
291 if (code != MODIFY_EXPR) | 359 if (code != MODIFY_EXPR) |
292 op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, | 360 op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, |
293 maybe_const_itself, for_int_const); | 361 maybe_const_itself, for_int_const, false); |
294 STRIP_TYPE_NOPS (op1); | 362 STRIP_TYPE_NOPS (op1); |
295 op1 = decl_constant_value_for_optimization (op1); | |
296 | 363 |
297 if (for_int_const && (TREE_CODE (op0) != INTEGER_CST | 364 if (for_int_const && (TREE_CODE (op0) != INTEGER_CST |
298 || TREE_CODE (op1) != INTEGER_CST)) | 365 || TREE_CODE (op1) != INTEGER_CST)) |
299 goto out; | 366 goto out; |
300 | 367 |
368 || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE) | 435 || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE) |
369 && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE) | 436 && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE) |
370 warn_for_div_by_zero (loc, op1); | 437 warn_for_div_by_zero (loc, op1); |
371 goto out; | 438 goto out; |
372 | 439 |
440 case ADDR_EXPR: | |
441 op0_lval = true; | |
442 goto unary; | |
443 case REALPART_EXPR: | |
444 case IMAGPART_EXPR: | |
445 case VIEW_CONVERT_EXPR: | |
446 op0_lval = lval; | |
447 /* FALLTHRU */ | |
373 case INDIRECT_REF: | 448 case INDIRECT_REF: |
374 case FIX_TRUNC_EXPR: | 449 case FIX_TRUNC_EXPR: |
375 case FLOAT_EXPR: | 450 case FLOAT_EXPR: |
376 CASE_CONVERT: | 451 CASE_CONVERT: |
377 case ADDR_SPACE_CONVERT_EXPR: | 452 case ADDR_SPACE_CONVERT_EXPR: |
378 case VIEW_CONVERT_EXPR: | |
379 case NON_LVALUE_EXPR: | 453 case NON_LVALUE_EXPR: |
380 case NEGATE_EXPR: | 454 case NEGATE_EXPR: |
381 case BIT_NOT_EXPR: | 455 case BIT_NOT_EXPR: |
382 case TRUTH_NOT_EXPR: | 456 case TRUTH_NOT_EXPR: |
383 case ADDR_EXPR: | |
384 case CONJ_EXPR: | 457 case CONJ_EXPR: |
385 case REALPART_EXPR: | 458 unary: |
386 case IMAGPART_EXPR: | |
387 /* Unary operations. */ | 459 /* Unary operations. */ |
388 orig_op0 = op0 = TREE_OPERAND (expr, 0); | 460 orig_op0 = op0 = TREE_OPERAND (expr, 0); |
389 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, | 461 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, |
390 maybe_const_itself, for_int_const); | 462 maybe_const_itself, for_int_const, |
463 op0_lval); | |
391 STRIP_TYPE_NOPS (op0); | 464 STRIP_TYPE_NOPS (op0); |
392 if (code != ADDR_EXPR && code != REALPART_EXPR && code != IMAGPART_EXPR) | |
393 op0 = decl_constant_value_for_optimization (op0); | |
394 | 465 |
395 if (for_int_const && TREE_CODE (op0) != INTEGER_CST) | 466 if (for_int_const && TREE_CODE (op0) != INTEGER_CST) |
396 goto out; | 467 goto out; |
397 | 468 |
398 /* ??? Cope with user tricks that amount to offsetof. The middle-end is | 469 /* ??? Cope with user tricks that amount to offsetof. The middle-end is |
400 if (op0 != orig_op0 | 471 if (op0 != orig_op0 |
401 && code == ADDR_EXPR | 472 && code == ADDR_EXPR |
402 && (op1 = get_base_address (op0)) != NULL_TREE | 473 && (op1 = get_base_address (op0)) != NULL_TREE |
403 && INDIRECT_REF_P (op1) | 474 && INDIRECT_REF_P (op1) |
404 && TREE_CONSTANT (TREE_OPERAND (op1, 0))) | 475 && TREE_CONSTANT (TREE_OPERAND (op1, 0))) |
405 ret = fold_convert_loc (loc, TREE_TYPE (expr), fold_offsetof_1 (op0)); | 476 ret = fold_offsetof (op0, TREE_TYPE (expr)); |
406 else if (op0 != orig_op0 || in_init) | 477 else if (op0 != orig_op0 || in_init) |
407 ret = in_init | 478 ret = in_init |
408 ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0) | 479 ? fold_build1_initializer_loc (loc, code, TREE_TYPE (expr), op0) |
409 : fold_build1_loc (loc, code, TREE_TYPE (expr), op0); | 480 : fold_build1_loc (loc, code, TREE_TYPE (expr), op0); |
410 else | 481 else |
438 /* Binary operations not necessarily evaluating both | 509 /* Binary operations not necessarily evaluating both |
439 arguments. */ | 510 arguments. */ |
440 orig_op0 = op0 = TREE_OPERAND (expr, 0); | 511 orig_op0 = op0 = TREE_OPERAND (expr, 0); |
441 orig_op1 = op1 = TREE_OPERAND (expr, 1); | 512 orig_op1 = op1 = TREE_OPERAND (expr, 1); |
442 op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self, | 513 op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self, |
443 for_int_const); | 514 for_int_const, false); |
444 STRIP_TYPE_NOPS (op0); | 515 STRIP_TYPE_NOPS (op0); |
445 | 516 |
446 unused_p = (op0 == (code == TRUTH_ANDIF_EXPR | 517 unused_p = (op0 == (code == TRUTH_ANDIF_EXPR |
447 ? truthvalue_false_node | 518 ? truthvalue_false_node |
448 : truthvalue_true_node)); | 519 : truthvalue_true_node)); |
449 c_disable_warnings (unused_p); | 520 c_disable_warnings (unused_p); |
450 op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self, | 521 op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self, |
451 for_int_const); | 522 for_int_const, false); |
452 STRIP_TYPE_NOPS (op1); | 523 STRIP_TYPE_NOPS (op1); |
453 c_enable_warnings (unused_p); | 524 c_enable_warnings (unused_p); |
454 | 525 |
455 if (for_int_const | 526 if (for_int_const |
456 && (TREE_CODE (op0) != INTEGER_CST | 527 && (TREE_CODE (op0) != INTEGER_CST |
484 case COND_EXPR: | 555 case COND_EXPR: |
485 orig_op0 = op0 = TREE_OPERAND (expr, 0); | 556 orig_op0 = op0 = TREE_OPERAND (expr, 0); |
486 orig_op1 = op1 = TREE_OPERAND (expr, 1); | 557 orig_op1 = op1 = TREE_OPERAND (expr, 1); |
487 orig_op2 = op2 = TREE_OPERAND (expr, 2); | 558 orig_op2 = op2 = TREE_OPERAND (expr, 2); |
488 op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self, | 559 op0 = c_fully_fold_internal (op0, in_init, &op0_const, &op0_const_self, |
489 for_int_const); | 560 for_int_const, false); |
490 | 561 |
491 STRIP_TYPE_NOPS (op0); | 562 STRIP_TYPE_NOPS (op0); |
492 c_disable_warnings (op0 == truthvalue_false_node); | 563 c_disable_warnings (op0 == truthvalue_false_node); |
493 op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self, | 564 op1 = c_fully_fold_internal (op1, in_init, &op1_const, &op1_const_self, |
494 for_int_const); | 565 for_int_const, false); |
495 STRIP_TYPE_NOPS (op1); | 566 STRIP_TYPE_NOPS (op1); |
496 c_enable_warnings (op0 == truthvalue_false_node); | 567 c_enable_warnings (op0 == truthvalue_false_node); |
497 | 568 |
498 c_disable_warnings (op0 == truthvalue_true_node); | 569 c_disable_warnings (op0 == truthvalue_true_node); |
499 op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self, | 570 op2 = c_fully_fold_internal (op2, in_init, &op2_const, &op2_const_self, |
500 for_int_const); | 571 for_int_const, false); |
501 STRIP_TYPE_NOPS (op2); | 572 STRIP_TYPE_NOPS (op2); |
502 c_enable_warnings (op0 == truthvalue_true_node); | 573 c_enable_warnings (op0 == truthvalue_true_node); |
503 | 574 |
504 if (for_int_const | 575 if (for_int_const |
505 && (TREE_CODE (op0) != INTEGER_CST | 576 && (TREE_CODE (op0) != INTEGER_CST |
538 case VEC_COND_EXPR: | 609 case VEC_COND_EXPR: |
539 orig_op0 = op0 = TREE_OPERAND (expr, 0); | 610 orig_op0 = op0 = TREE_OPERAND (expr, 0); |
540 orig_op1 = op1 = TREE_OPERAND (expr, 1); | 611 orig_op1 = op1 = TREE_OPERAND (expr, 1); |
541 orig_op2 = op2 = TREE_OPERAND (expr, 2); | 612 orig_op2 = op2 = TREE_OPERAND (expr, 2); |
542 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, | 613 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, |
543 maybe_const_itself, for_int_const); | 614 maybe_const_itself, for_int_const, false); |
544 STRIP_TYPE_NOPS (op0); | 615 STRIP_TYPE_NOPS (op0); |
545 op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, | 616 op1 = c_fully_fold_internal (op1, in_init, maybe_const_operands, |
546 maybe_const_itself, for_int_const); | 617 maybe_const_itself, for_int_const, false); |
547 STRIP_TYPE_NOPS (op1); | 618 STRIP_TYPE_NOPS (op1); |
548 op2 = c_fully_fold_internal (op2, in_init, maybe_const_operands, | 619 op2 = c_fully_fold_internal (op2, in_init, maybe_const_operands, |
549 maybe_const_itself, for_int_const); | 620 maybe_const_itself, for_int_const, false); |
550 STRIP_TYPE_NOPS (op2); | 621 STRIP_TYPE_NOPS (op2); |
551 | 622 |
552 if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2) | 623 if (op0 != orig_op0 || op1 != orig_op1 || op2 != orig_op2) |
553 ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2); | 624 ret = fold_build3_loc (loc, code, TREE_TYPE (expr), op0, op1, op2); |
554 else | 625 else |
568 /* Make sure to fold the contents of a SAVE_EXPR exactly once. */ | 639 /* Make sure to fold the contents of a SAVE_EXPR exactly once. */ |
569 op0 = TREE_OPERAND (expr, 0); | 640 op0 = TREE_OPERAND (expr, 0); |
570 if (!SAVE_EXPR_FOLDED_P (expr)) | 641 if (!SAVE_EXPR_FOLDED_P (expr)) |
571 { | 642 { |
572 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, | 643 op0 = c_fully_fold_internal (op0, in_init, maybe_const_operands, |
573 maybe_const_itself, for_int_const); | 644 maybe_const_itself, for_int_const, |
645 false); | |
574 TREE_OPERAND (expr, 0) = op0; | 646 TREE_OPERAND (expr, 0) = op0; |
575 SAVE_EXPR_FOLDED_P (expr) = true; | 647 SAVE_EXPR_FOLDED_P (expr) = true; |
576 } | 648 } |
577 /* Return the SAVE_EXPR operand if it is invariant. */ | 649 /* Return the SAVE_EXPR operand if it is invariant. */ |
578 if (tree_invariant_p (op0)) | 650 if (tree_invariant_p (op0)) |
603 set_source_range (ret, old_range.m_start, old_range.m_finish); | 675 set_source_range (ret, old_range.m_start, old_range.m_finish); |
604 } | 676 } |
605 return ret; | 677 return ret; |
606 } | 678 } |
607 | 679 |
608 /* If not optimizing, EXP is not a VAR_DECL, or EXP has array type, | 680 /* Fold X for consideration by one of the warning functions when checking |
609 return EXP. Otherwise, return either EXP or its known constant | 681 whether an expression has a constant value. */ |
610 value (if it has one), but return EXP if EXP has mode BLKmode. ??? | |
611 Is the BLKmode test appropriate? */ | |
612 | 682 |
613 tree | 683 tree |
614 decl_constant_value_for_optimization (tree exp) | 684 fold_for_warn (tree x) |
615 { | 685 { |
616 tree ret; | 686 /* The C front-end has already folded X appropriately. */ |
617 | 687 return x; |
618 if (!optimize | |
619 || !VAR_P (exp) | |
620 || TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE | |
621 || DECL_MODE (exp) == BLKmode) | |
622 return exp; | |
623 | |
624 ret = decl_constant_value (exp); | |
625 /* Avoid unwanted tree sharing between the initializer and current | |
626 function's body where the tree can be modified e.g. by the | |
627 gimplifier. */ | |
628 if (ret != exp && TREE_STATIC (exp)) | |
629 ret = unshare_expr (ret); | |
630 return ret; | |
631 } | 688 } |