]>
Commit | Line | Data |
---|---|---|
e53b6e56 | 1 | /* Preamble and helpers for the autogenerated gimple-match.cc file. |
a945c346 | 2 | Copyright (C) 2014-2024 Free Software Foundation, Inc. |
3d2cf79f RB |
3 | |
4 | This file is part of GCC. | |
5 | ||
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 | |
8 | Software Foundation; either version 3, or (at your option) any later | |
9 | version. | |
10 | ||
11 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 | for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GCC; see the file COPYING3. If not see | |
18 | <http://www.gnu.org/licenses/>. */ | |
19 | ||
20 | #include "config.h" | |
21 | #include "system.h" | |
22 | #include "coretypes.h" | |
c7131fb2 | 23 | #include "backend.h" |
957060b5 AM |
24 | #include "target.h" |
25 | #include "rtl.h" | |
c7131fb2 AM |
26 | #include "tree.h" |
27 | #include "gimple.h" | |
c7131fb2 | 28 | #include "ssa.h" |
957060b5 | 29 | #include "cgraph.h" |
ebd733a7 | 30 | #include "vec-perm-indices.h" |
40e23961 | 31 | #include "fold-const.h" |
c9e926ce | 32 | #include "fold-const-call.h" |
3d2cf79f | 33 | #include "stor-layout.h" |
ba206889 | 34 | #include "gimple-iterator.h" |
3d2cf79f | 35 | #include "gimple-fold.h" |
36566b39 | 36 | #include "calls.h" |
3d2cf79f RB |
37 | #include "tree-dfa.h" |
38 | #include "builtins.h" | |
3d2cf79f | 39 | #include "gimple-match.h" |
53f3cd25 | 40 | #include "tree-pass.h" |
c9e926ce RS |
41 | #include "internal-fn.h" |
42 | #include "case-cfn-macros.h" | |
a3ca1bc5 | 43 | #include "gimplify.h" |
71f82be9 | 44 | #include "optabs-tree.h" |
6a86928d | 45 | #include "tree-eh.h" |
d398999d | 46 | #include "dbgcnt.h" |
75f89001 | 47 | #include "tm.h" |
45f4e2b0 | 48 | #include "gimple-range.h" |
b2bb611d | 49 | #include "langhooks.h" |
d1c072a1 RB |
50 | #include "attribs.h" |
51 | #include "asan.h" | |
3d2cf79f | 52 | |
27fcf994 TC |
53 | tree do_valueize (tree, tree (*)(tree), bool &); |
54 | tree do_valueize (tree (*)(tree), tree); | |
3d2cf79f | 55 | |
4f450a2b RB |
56 | /* Helper for the autogenerated code, get at the definition of NAME when |
57 | VALUEIZE allows that. */ | |
58 | ||
59 | inline gimple * | |
60 | get_def (tree (*valueize)(tree), tree name) | |
61 | { | |
62 | if (valueize && ! valueize (name)) | |
63 | return NULL; | |
64 | return SSA_NAME_DEF_STMT (name); | |
65 | } | |
66 | ||
48451e8f | 67 | /* Routine to determine if the types T1 and T2 are effectively |
aea417d7 MG |
68 | the same for GIMPLE. If T1 or T2 is not a type, the test |
69 | applies to their TREE_TYPE. */ | |
48451e8f JL |
70 | |
71 | static inline bool | |
72 | types_match (tree t1, tree t2) | |
73 | { | |
aea417d7 MG |
74 | if (!TYPE_P (t1)) |
75 | t1 = TREE_TYPE (t1); | |
76 | if (!TYPE_P (t2)) | |
77 | t2 = TREE_TYPE (t2); | |
78 | ||
48451e8f JL |
79 | return types_compatible_p (t1, t2); |
80 | } | |
81 | ||
dca3e6b9 PL |
82 | /* Routine to determine if the types T1, T2 and T3 are effectively |
83 | the same for GIMPLE. If T1, T2 or T2 is not a type, the test | |
84 | applies to their TREE_TYPE. */ | |
85 | ||
86 | static inline bool | |
87 | types_match (tree t1, tree t2, tree t3) | |
88 | { | |
89 | return types_match (t1, t2) && types_match (t2, t3); | |
90 | } | |
91 | ||
48451e8f JL |
92 | /* Return if T has a single use. For GIMPLE, we also allow any |
93 | non-SSA_NAME (ie constants) and zero uses to cope with uses | |
94 | that aren't linked up yet. */ | |
95 | ||
6aef670e RS |
96 | static bool |
97 | single_use (const_tree) ATTRIBUTE_PURE; | |
98 | ||
99 | static bool | |
100 | single_use (const_tree t) | |
48451e8f | 101 | { |
6aef670e RS |
102 | if (TREE_CODE (t) != SSA_NAME) |
103 | return true; | |
104 | ||
105 | /* Inline return has_zero_uses (t) || has_single_use (t); */ | |
106 | const ssa_use_operand_t *const head = &(SSA_NAME_IMM_USE_NODE (t)); | |
107 | const ssa_use_operand_t *ptr; | |
108 | bool single = false; | |
109 | ||
110 | for (ptr = head->next; ptr != head; ptr = ptr->next) | |
111 | if (USE_STMT(ptr) && !is_gimple_debug (USE_STMT (ptr))) | |
112 | { | |
113 | if (single) | |
114 | return false; | |
115 | single = true; | |
116 | } | |
117 | return true; | |
48451e8f | 118 | } |
53f3cd25 RS |
119 | |
120 | /* Return true if math operations should be canonicalized, | |
121 | e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */ | |
122 | ||
123 | static inline bool | |
124 | canonicalize_math_p () | |
125 | { | |
126 | return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0; | |
127 | } | |
848bb6fc JJ |
128 | |
129 | /* Return true if math operations that are beneficial only after | |
130 | vectorization should be canonicalized. */ | |
131 | ||
132 | static inline bool | |
133 | canonicalize_math_after_vectorization_p () | |
134 | { | |
135 | return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0; | |
136 | } | |
30a2c10e | 137 | |
a1ee6d50 MG |
138 | /* Return true if we can still perform transformations that may introduce |
139 | vector operations that are not supported by the target. Vector lowering | |
140 | normally handles those, but after that pass, it becomes unsafe. */ | |
141 | ||
142 | static inline bool | |
143 | optimize_vectors_before_lowering_p () | |
144 | { | |
145 | return !cfun || (cfun->curr_properties & PROP_gimple_lvec) == 0; | |
146 | } | |
147 | ||
30a2c10e JJ |
148 | /* Return true if pow(cst, x) should be optimized into exp(log(cst) * x). |
149 | As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0 | |
150 | is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...> | |
151 | where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1) | |
152 | will likely be exact, while exp (log (arg0) * arg1) might be not. | |
153 | Also don't do it if arg1 is phi_res above and cst2 is an exact integer. */ | |
154 | ||
155 | static bool | |
156 | optimize_pow_to_exp (tree arg0, tree arg1) | |
157 | { | |
158 | gcc_assert (TREE_CODE (arg0) == REAL_CST); | |
159 | if (!real_isinteger (TREE_REAL_CST_PTR (arg0), TYPE_MODE (TREE_TYPE (arg0)))) | |
160 | return true; | |
161 | ||
162 | if (TREE_CODE (arg1) != SSA_NAME) | |
163 | return true; | |
164 | ||
165 | gimple *def = SSA_NAME_DEF_STMT (arg1); | |
166 | gphi *phi = dyn_cast <gphi *> (def); | |
167 | tree cst1 = NULL_TREE; | |
168 | enum tree_code code = ERROR_MARK; | |
169 | if (!phi) | |
170 | { | |
171 | if (!is_gimple_assign (def)) | |
172 | return true; | |
173 | code = gimple_assign_rhs_code (def); | |
174 | switch (code) | |
175 | { | |
176 | case PLUS_EXPR: | |
177 | case MINUS_EXPR: | |
178 | break; | |
179 | default: | |
180 | return true; | |
181 | } | |
182 | if (TREE_CODE (gimple_assign_rhs1 (def)) != SSA_NAME | |
183 | || TREE_CODE (gimple_assign_rhs2 (def)) != REAL_CST) | |
184 | return true; | |
185 | ||
186 | cst1 = gimple_assign_rhs2 (def); | |
187 | ||
188 | phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def))); | |
189 | if (!phi) | |
190 | return true; | |
191 | } | |
192 | ||
193 | tree cst2 = NULL_TREE; | |
194 | int n = gimple_phi_num_args (phi); | |
195 | for (int i = 0; i < n; i++) | |
196 | { | |
197 | tree arg = PHI_ARG_DEF (phi, i); | |
198 | if (TREE_CODE (arg) != REAL_CST) | |
199 | continue; | |
200 | else if (cst2 == NULL_TREE) | |
201 | cst2 = arg; | |
202 | else if (!operand_equal_p (cst2, arg, 0)) | |
203 | return true; | |
204 | } | |
205 | ||
206 | if (cst1 && cst2) | |
207 | cst2 = const_binop (code, TREE_TYPE (cst2), cst2, cst1); | |
208 | if (cst2 | |
209 | && TREE_CODE (cst2) == REAL_CST | |
210 | && real_isinteger (TREE_REAL_CST_PTR (cst2), | |
211 | TYPE_MODE (TREE_TYPE (cst2)))) | |
212 | return false; | |
213 | return true; | |
214 | } | |
98610dc5 JJ |
215 | |
216 | /* Return true if a division INNER_DIV / DIVISOR where INNER_DIV | |
217 | is another division can be optimized. Don't optimize if INNER_DIV | |
218 | is used in a TRUNC_MOD_EXPR with DIVISOR as second operand. */ | |
219 | ||
220 | static bool | |
221 | optimize_successive_divisions_p (tree divisor, tree inner_div) | |
222 | { | |
223 | if (!gimple_in_ssa_p (cfun)) | |
224 | return false; | |
225 | ||
226 | imm_use_iterator imm_iter; | |
227 | use_operand_p use_p; | |
228 | FOR_EACH_IMM_USE_FAST (use_p, imm_iter, inner_div) | |
229 | { | |
230 | gimple *use_stmt = USE_STMT (use_p); | |
231 | if (!is_gimple_assign (use_stmt) | |
232 | || gimple_assign_rhs_code (use_stmt) != TRUNC_MOD_EXPR | |
233 | || !operand_equal_p (gimple_assign_rhs2 (use_stmt), divisor, 0)) | |
234 | continue; | |
235 | return false; | |
236 | } | |
237 | return true; | |
238 | } | |
2a355637 DR |
239 | |
240 | /* Return true if EXPR1 and EXPR2 have the same value, but not necessarily | |
241 | same type. The types can differ through nop conversions. */ | |
242 | #define bitwise_equal_p(expr1, expr2) \ | |
243 | gimple_bitwise_equal_p (expr1, expr2, valueize) | |
244 | ||
245 | bool gimple_nop_convert (tree, tree *, tree (*) (tree)); | |
0256121e | 246 | bool gimple_maybe_truncate (tree, tree *, tree (*) (tree)); |
2a355637 DR |
247 | |
248 | /* Helper function for bitwise_equal_p macro. */ | |
249 | ||
250 | static inline bool | |
251 | gimple_bitwise_equal_p (tree expr1, tree expr2, tree (*valueize) (tree)) | |
252 | { | |
253 | if (expr1 == expr2) | |
254 | return true; | |
255 | if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2))) | |
256 | return false; | |
257 | if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST) | |
258 | return wi::to_wide (expr1) == wi::to_wide (expr2); | |
259 | if (operand_equal_p (expr1, expr2, 0)) | |
260 | return true; | |
261 | tree expr3, expr4; | |
262 | if (!gimple_nop_convert (expr1, &expr3, valueize)) | |
263 | expr3 = expr1; | |
264 | if (!gimple_nop_convert (expr2, &expr4, valueize)) | |
265 | expr4 = expr2; | |
266 | if (expr1 != expr3) | |
267 | { | |
268 | if (operand_equal_p (expr3, expr2, 0)) | |
269 | return true; | |
270 | if (expr2 != expr4 && operand_equal_p (expr3, expr4, 0)) | |
271 | return true; | |
272 | } | |
273 | if (expr2 != expr4 && operand_equal_p (expr1, expr4, 0)) | |
274 | return true; | |
0256121e AP |
275 | if (gimple_maybe_truncate (expr3, &expr3, valueize) |
276 | && gimple_maybe_truncate (expr4, &expr4, valueize) | |
277 | && operand_equal_p (expr3, expr4, 0)) | |
278 | return true; | |
2a355637 DR |
279 | return false; |
280 | } | |
b9237226 AP |
281 | |
282 | /* Return true if EXPR1 and EXPR2 have the bitwise opposite value, | |
283 | but not necessarily same type. | |
284 | The types can differ through nop conversions. */ | |
f956c232 AP |
285 | #define bitwise_inverted_equal_p(expr1, expr2, wascmp) \ |
286 | gimple_bitwise_inverted_equal_p (expr1, expr2, wascmp, valueize) | |
b9237226 | 287 | |
91c963ea AP |
288 | |
289 | bool gimple_bit_not_with_nop (tree, tree *, tree (*) (tree)); | |
290 | bool gimple_maybe_cmp (tree, tree *, tree (*) (tree)); | |
547143df | 291 | bool gimple_bit_xor_cst (tree, tree *, tree (*) (tree)); |
91c963ea | 292 | |
1e681507 | 293 | /* Helper function for bitwise_inverted_equal_p macro. */ |
b9237226 AP |
294 | |
295 | static inline bool | |
f956c232 | 296 | gimple_bitwise_inverted_equal_p (tree expr1, tree expr2, bool &wascmp, tree (*valueize) (tree)) |
b9237226 | 297 | { |
f956c232 | 298 | wascmp = false; |
b9237226 AP |
299 | if (expr1 == expr2) |
300 | return false; | |
301 | if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2))) | |
302 | return false; | |
c5a76284 AP |
303 | tree cst1 = uniform_integer_cst_p (expr1); |
304 | tree cst2 = uniform_integer_cst_p (expr2); | |
305 | if (cst1 && cst2) | |
306 | return wi::to_wide (cst1) == ~wi::to_wide (cst2); | |
b9237226 AP |
307 | if (operand_equal_p (expr1, expr2, 0)) |
308 | return false; | |
309 | ||
547143df AP |
310 | tree xor1[2]; |
311 | tree xor2[2]; | |
312 | /* `X ^ CST` and `X ^ ~CST` match for ~. */ | |
313 | if (gimple_bit_xor_cst (expr1, xor1, valueize) | |
314 | && gimple_bit_xor_cst (expr2, xor2, valueize)) | |
315 | { | |
316 | if (operand_equal_p (xor1[0], xor2[0], 0) | |
317 | && (wi::to_wide (uniform_integer_cst_p (xor1[1])) | |
318 | == ~wi::to_wide (uniform_integer_cst_p (xor2[1])))) | |
319 | return true; | |
320 | } | |
321 | ||
b9237226 | 322 | tree other; |
91c963ea AP |
323 | /* Try if EXPR1 was defined as ~EXPR2. */ |
324 | if (gimple_bit_not_with_nop (expr1, &other, valueize)) | |
325 | { | |
0256121e | 326 | if (gimple_bitwise_equal_p (other, expr2, valueize)) |
b9237226 | 327 | return true; |
91c963ea AP |
328 | } |
329 | /* Try if EXPR2 was defined as ~EXPR1. */ | |
330 | if (gimple_bit_not_with_nop (expr2, &other, valueize)) | |
b9237226 | 331 | { |
0256121e | 332 | if (gimple_bitwise_equal_p (other, expr1, valueize)) |
b9237226 AP |
333 | return true; |
334 | } | |
91c963ea AP |
335 | |
336 | /* If neither are defined by BIT_NOT, try to see if | |
337 | both are defined by comparisons and see if they are | |
338 | complementary (inversion) of each other. */ | |
339 | tree newexpr1, newexpr2; | |
340 | if (!gimple_maybe_cmp (expr1, &newexpr1, valueize)) | |
341 | return false; | |
342 | if (!gimple_maybe_cmp (expr2, &newexpr2, valueize)) | |
343 | return false; | |
344 | ||
345 | gimple *d1 = get_def (valueize, newexpr1); | |
346 | gassign *a1 = dyn_cast <gassign *> (d1); | |
347 | gimple *d2 = get_def (valueize, newexpr2); | |
348 | gassign *a2 = dyn_cast <gassign *> (d2); | |
349 | tree op10 = do_valueize (valueize, gimple_assign_rhs1 (a1)); | |
350 | tree op20 = do_valueize (valueize, gimple_assign_rhs1 (a2)); | |
351 | if (!operand_equal_p (op10, op20)) | |
352 | return false; | |
353 | tree op11 = do_valueize (valueize, gimple_assign_rhs2 (a1)); | |
354 | tree op21 = do_valueize (valueize, gimple_assign_rhs2 (a2)); | |
355 | if (!operand_equal_p (op11, op21)) | |
356 | return false; | |
f956c232 | 357 | wascmp = true; |
97def769 AP |
358 | tree_code ac1 = gimple_assign_rhs_code (a1); |
359 | tree_code ac2 = gimple_assign_rhs_code (a2); | |
360 | /* Match `^` against `==` but this should only | |
361 | happen when the type is a 1bit precision integer. */ | |
362 | if (ac1 == BIT_XOR_EXPR) | |
363 | { | |
364 | tree type = TREE_TYPE (newexpr1); | |
365 | gcc_assert (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1); | |
366 | return ac2 == EQ_EXPR; | |
367 | } | |
368 | if (ac2 == BIT_XOR_EXPR) | |
369 | { | |
370 | tree type = TREE_TYPE (newexpr1); | |
371 | gcc_assert (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1); | |
372 | return ac1 == EQ_EXPR; | |
373 | } | |
374 | if (invert_tree_comparison (ac1, HONOR_NANS (op10)) == ac2) | |
91c963ea | 375 | return true; |
b9237226 AP |
376 | return false; |
377 | } |