Branch data Line data Source code
1 : : /* Preamble and helpers for the autogenerated gimple-match.cc file.
2 : : Copyright (C) 2014-2024 Free Software Foundation, Inc.
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"
23 : : #include "backend.h"
24 : : #include "target.h"
25 : : #include "rtl.h"
26 : : #include "tree.h"
27 : : #include "gimple.h"
28 : : #include "ssa.h"
29 : : #include "cgraph.h"
30 : : #include "vec-perm-indices.h"
31 : : #include "fold-const.h"
32 : : #include "fold-const-call.h"
33 : : #include "stor-layout.h"
34 : : #include "gimple-iterator.h"
35 : : #include "gimple-fold.h"
36 : : #include "calls.h"
37 : : #include "tree-dfa.h"
38 : : #include "builtins.h"
39 : : #include "gimple-match.h"
40 : : #include "tree-pass.h"
41 : : #include "internal-fn.h"
42 : : #include "case-cfn-macros.h"
43 : : #include "gimplify.h"
44 : : #include "optabs-tree.h"
45 : : #include "tree-eh.h"
46 : : #include "dbgcnt.h"
47 : : #include "tm.h"
48 : : #include "gimple-range.h"
49 : : #include "langhooks.h"
50 : : #include "attribs.h"
51 : : #include "asan.h"
52 : :
53 : : tree do_valueize (tree, tree (*)(tree), bool &);
54 : : tree do_valueize (tree (*)(tree), tree);
55 : :
56 : : /* Helper for the autogenerated code, get at the definition of NAME when
57 : : VALUEIZE allows that. */
58 : :
59 : : inline gimple *
60 : 8956133825 : get_def (tree (*valueize)(tree), tree name)
61 : : {
62 : 8956133825 : if (valueize && ! valueize (name))
63 : : return NULL;
64 : 3628263466 : return SSA_NAME_DEF_STMT (name);
65 : : }
66 : :
67 : : /* Routine to determine if the types T1 and T2 are effectively
68 : : the same for GIMPLE. If T1 or T2 is not a type, the test
69 : : applies to their TREE_TYPE. */
70 : :
71 : : static inline bool
72 : 44494560 : types_match (tree t1, tree t2)
73 : : {
74 : 44494560 : if (!TYPE_P (t1))
75 : 1171051 : t1 = TREE_TYPE (t1);
76 : 44494560 : if (!TYPE_P (t2))
77 : 1672883 : t2 = TREE_TYPE (t2);
78 : :
79 : 44494560 : return types_compatible_p (t1, t2);
80 : : }
81 : :
82 : : /* Return if T has a single use. For GIMPLE, we also allow any
83 : : non-SSA_NAME (ie constants) and zero uses to cope with uses
84 : : that aren't linked up yet. */
85 : :
86 : : static bool
87 : : single_use (const_tree) ATTRIBUTE_PURE;
88 : :
89 : : static bool
90 : 9363325 : single_use (const_tree t)
91 : : {
92 : 9363325 : if (TREE_CODE (t) != SSA_NAME)
93 : : return true;
94 : :
95 : : /* Inline return has_zero_uses (t) || has_single_use (t); */
96 : 9363325 : const ssa_use_operand_t *const head = &(SSA_NAME_IMM_USE_NODE (t));
97 : 9363325 : const ssa_use_operand_t *ptr;
98 : 9363325 : bool single = false;
99 : :
100 : 19946163 : for (ptr = head->next; ptr != head; ptr = ptr->next)
101 : 15419407 : if (USE_STMT(ptr) && !is_gimple_debug (USE_STMT (ptr)))
102 : : {
103 : 14183544 : if (single)
104 : : return false;
105 : : single = true;
106 : : }
107 : : return true;
108 : : }
109 : :
110 : : /* Return true if math operations should be canonicalized,
111 : : e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
112 : :
113 : : static inline bool
114 : 33487 : canonicalize_math_p ()
115 : : {
116 : 33487 : return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
117 : : }
118 : :
119 : : /* Return true if math operations that are beneficial only after
120 : : vectorization should be canonicalized. */
121 : :
122 : : static inline bool
123 : 44136 : canonicalize_math_after_vectorization_p ()
124 : : {
125 : 44136 : return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
126 : : }
127 : :
128 : : /* Return true if we can still perform transformations that may introduce
129 : : vector operations that are not supported by the target. Vector lowering
130 : : normally handles those, but after that pass, it becomes unsafe. */
131 : :
132 : : static inline bool
133 : 3903 : optimize_vectors_before_lowering_p ()
134 : : {
135 : 3903 : return !cfun || (cfun->curr_properties & PROP_gimple_lvec) == 0;
136 : : }
137 : :
138 : : /* Return true if pow(cst, x) should be optimized into exp(log(cst) * x).
139 : : As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0
140 : : is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...>
141 : : where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1)
142 : : will likely be exact, while exp (log (arg0) * arg1) might be not.
143 : : Also don't do it if arg1 is phi_res above and cst2 is an exact integer. */
144 : :
145 : : static bool
146 : 5 : optimize_pow_to_exp (tree arg0, tree arg1)
147 : : {
148 : 5 : gcc_assert (TREE_CODE (arg0) == REAL_CST);
149 : 5 : if (!real_isinteger (TREE_REAL_CST_PTR (arg0), TYPE_MODE (TREE_TYPE (arg0))))
150 : : return true;
151 : :
152 : 5 : if (TREE_CODE (arg1) != SSA_NAME)
153 : : return true;
154 : :
155 : 5 : gimple *def = SSA_NAME_DEF_STMT (arg1);
156 : 5 : gphi *phi = dyn_cast <gphi *> (def);
157 : 5 : tree cst1 = NULL_TREE;
158 : 5 : enum tree_code code = ERROR_MARK;
159 : 5 : if (!phi)
160 : : {
161 : 5 : if (!is_gimple_assign (def))
162 : : return true;
163 : 5 : code = gimple_assign_rhs_code (def);
164 : 5 : switch (code)
165 : : {
166 : 5 : case PLUS_EXPR:
167 : 5 : case MINUS_EXPR:
168 : 5 : break;
169 : : default:
170 : : return true;
171 : : }
172 : 5 : if (TREE_CODE (gimple_assign_rhs1 (def)) != SSA_NAME
173 : 5 : || TREE_CODE (gimple_assign_rhs2 (def)) != REAL_CST)
174 : : return true;
175 : :
176 : 5 : cst1 = gimple_assign_rhs2 (def);
177 : :
178 : 5 : phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def)));
179 : : if (!phi)
180 : : return true;
181 : : }
182 : :
183 : 5 : tree cst2 = NULL_TREE;
184 : 5 : int n = gimple_phi_num_args (phi);
185 : 15 : for (int i = 0; i < n; i++)
186 : : {
187 : 10 : tree arg = PHI_ARG_DEF (phi, i);
188 : 10 : if (TREE_CODE (arg) != REAL_CST)
189 : 5 : continue;
190 : 5 : else if (cst2 == NULL_TREE)
191 : : cst2 = arg;
192 : 0 : else if (!operand_equal_p (cst2, arg, 0))
193 : : return true;
194 : : }
195 : :
196 : 5 : if (cst1 && cst2)
197 : 5 : cst2 = const_binop (code, TREE_TYPE (cst2), cst2, cst1);
198 : 5 : if (cst2
199 : 5 : && TREE_CODE (cst2) == REAL_CST
200 : 10 : && real_isinteger (TREE_REAL_CST_PTR (cst2),
201 : 5 : TYPE_MODE (TREE_TYPE (cst2))))
202 : 5 : return false;
203 : : return true;
204 : : }
205 : :
206 : : /* Return true if a division INNER_DIV / DIVISOR where INNER_DIV
207 : : is another division can be optimized. Don't optimize if INNER_DIV
208 : : is used in a TRUNC_MOD_EXPR with DIVISOR as second operand. */
209 : :
210 : : static bool
211 : 15576 : optimize_successive_divisions_p (tree divisor, tree inner_div)
212 : : {
213 : 28195 : if (!gimple_in_ssa_p (cfun))
214 : : return false;
215 : :
216 : 15576 : imm_use_iterator imm_iter;
217 : 15576 : use_operand_p use_p;
218 : 35200 : FOR_EACH_IMM_USE_FAST (use_p, imm_iter, inner_div)
219 : : {
220 : 32243 : gimple *use_stmt = USE_STMT (use_p);
221 : 32243 : if (!is_gimple_assign (use_stmt)
222 : 25325 : || gimple_assign_rhs_code (use_stmt) != TRUNC_MOD_EXPR
223 : 45272 : || !operand_equal_p (gimple_assign_rhs2 (use_stmt), divisor, 0))
224 : 19624 : continue;
225 : : return false;
226 : : }
227 : : return true;
228 : : }
229 : :
230 : : /* Return true if EXPR1 and EXPR2 have the same value, but not necessarily
231 : : same type. The types can differ through nop conversions. */
232 : : #define bitwise_equal_p(expr1, expr2) \
233 : : gimple_bitwise_equal_p (expr1, expr2, valueize)
234 : :
235 : : bool gimple_nop_convert (tree, tree *, tree (*) (tree));
236 : :
237 : : /* Helper function for bitwise_equal_p macro. */
238 : :
239 : : static inline bool
240 : 678572 : gimple_bitwise_equal_p (tree expr1, tree expr2, tree (*valueize) (tree))
241 : : {
242 : 678572 : if (expr1 == expr2)
243 : : return true;
244 : 677735 : if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
245 : : return false;
246 : 666902 : if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST)
247 : 67 : return wi::to_wide (expr1) == wi::to_wide (expr2);
248 : 666835 : if (operand_equal_p (expr1, expr2, 0))
249 : : return true;
250 : 666835 : tree expr3, expr4;
251 : 666835 : if (!gimple_nop_convert (expr1, &expr3, valueize))
252 : 663981 : expr3 = expr1;
253 : 666835 : if (!gimple_nop_convert (expr2, &expr4, valueize))
254 : 662912 : expr4 = expr2;
255 : 666835 : if (expr1 != expr3)
256 : : {
257 : 2854 : if (operand_equal_p (expr3, expr2, 0))
258 : : return true;
259 : 2615 : if (expr2 != expr4 && operand_equal_p (expr3, expr4, 0))
260 : : return true;
261 : : }
262 : 666582 : if (expr2 != expr4 && operand_equal_p (expr1, expr4, 0))
263 : : return true;
264 : : return false;
265 : : }
266 : :
267 : : /* Return true if EXPR1 and EXPR2 have the bitwise opposite value,
268 : : but not necessarily same type.
269 : : The types can differ through nop conversions. */
270 : : #define bitwise_inverted_equal_p(expr1, expr2, wascmp) \
271 : : gimple_bitwise_inverted_equal_p (expr1, expr2, wascmp, valueize)
272 : :
273 : :
274 : : bool gimple_bit_not_with_nop (tree, tree *, tree (*) (tree));
275 : : bool gimple_maybe_cmp (tree, tree *, tree (*) (tree));
276 : :
277 : : /* Helper function for bitwise_inverted_equal_p macro. */
278 : :
279 : : static inline bool
280 : 16272985 : gimple_bitwise_inverted_equal_p (tree expr1, tree expr2, bool &wascmp, tree (*valueize) (tree))
281 : : {
282 : 16272985 : wascmp = false;
283 : 16272985 : if (expr1 == expr2)
284 : : return false;
285 : 16245321 : if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
286 : : return false;
287 : 16245321 : if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST)
288 : 288412 : return wi::to_wide (expr1) == ~wi::to_wide (expr2);
289 : 15956909 : if (operand_equal_p (expr1, expr2, 0))
290 : : return false;
291 : :
292 : 15956823 : tree other;
293 : : /* Try if EXPR1 was defined as ~EXPR2. */
294 : 15956823 : if (gimple_bit_not_with_nop (expr1, &other, valueize))
295 : : {
296 : 295113 : if (operand_equal_p (other, expr2, 0))
297 : 924 : return true;
298 : 294189 : tree expr4;
299 : 294189 : if (gimple_nop_convert (expr2, &expr4, valueize)
300 : 294189 : && operand_equal_p (other, expr4, 0))
301 : : return true;
302 : : }
303 : : /* Try if EXPR2 was defined as ~EXPR1. */
304 : 15955899 : if (gimple_bit_not_with_nop (expr2, &other, valueize))
305 : : {
306 : 508965 : if (operand_equal_p (other, expr1, 0))
307 : 1571 : return true;
308 : 507394 : tree expr3;
309 : 507394 : if (gimple_nop_convert (expr1, &expr3, valueize)
310 : 507394 : && operand_equal_p (other, expr3, 0))
311 : : return true;
312 : : }
313 : :
314 : : /* If neither are defined by BIT_NOT, try to see if
315 : : both are defined by comparisons and see if they are
316 : : complementary (inversion) of each other. */
317 : 15954328 : tree newexpr1, newexpr2;
318 : 15954328 : if (!gimple_maybe_cmp (expr1, &newexpr1, valueize))
319 : : return false;
320 : 3084199 : if (!gimple_maybe_cmp (expr2, &newexpr2, valueize))
321 : : return false;
322 : :
323 : 2712898 : gimple *d1 = get_def (valueize, newexpr1);
324 : 2712898 : gassign *a1 = dyn_cast <gassign *> (d1);
325 : 2712898 : gimple *d2 = get_def (valueize, newexpr2);
326 : 2712898 : gassign *a2 = dyn_cast <gassign *> (d2);
327 : 2712898 : tree op10 = do_valueize (valueize, gimple_assign_rhs1 (a1));
328 : 2712898 : tree op20 = do_valueize (valueize, gimple_assign_rhs1 (a2));
329 : 2712898 : if (!operand_equal_p (op10, op20))
330 : : return false;
331 : 1643540 : tree op11 = do_valueize (valueize, gimple_assign_rhs2 (a1));
332 : 1643540 : tree op21 = do_valueize (valueize, gimple_assign_rhs2 (a2));
333 : 821770 : if (!operand_equal_p (op11, op21))
334 : : return false;
335 : 20649 : wascmp = true;
336 : 20649 : tree_code ac1 = gimple_assign_rhs_code (a1);
337 : 20649 : tree_code ac2 = gimple_assign_rhs_code (a2);
338 : : /* Match `^` against `==` but this should only
339 : : happen when the type is a 1bit precision integer. */
340 : 20649 : if (ac1 == BIT_XOR_EXPR)
341 : : {
342 : 1 : tree type = TREE_TYPE (newexpr1);
343 : 1 : gcc_assert (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1);
344 : 1 : return ac2 == EQ_EXPR;
345 : : }
346 : 20648 : if (ac2 == BIT_XOR_EXPR)
347 : : {
348 : 0 : tree type = TREE_TYPE (newexpr1);
349 : 0 : gcc_assert (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1);
350 : 0 : return ac1 == EQ_EXPR;
351 : : }
352 : 20648 : if (invert_tree_comparison (ac1, HONOR_NANS (op10)) == ac2)
353 : : return true;
354 : : return false;
355 : : }
|