]> gcc.gnu.org Git - gcc.git/blame - gcc/gimple-match-head.cc
OpenACC: Fix reduction tree-sharing issue [PR106982]
[gcc.git] / gcc / gimple-match-head.cc
CommitLineData
e53b6e56 1/* Preamble and helpers for the autogenerated gimple-match.cc file.
7adcbafe 2 Copyright (C) 2014-2022 Free Software Foundation, Inc.
3d2cf79f
RB
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along 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"
3d2cf79f 34#include "gimple-fold.h"
36566b39 35#include "calls.h"
3d2cf79f
RB
36#include "tree-dfa.h"
37#include "builtins.h"
3d2cf79f 38#include "gimple-match.h"
53f3cd25 39#include "tree-pass.h"
c9e926ce
RS
40#include "internal-fn.h"
41#include "case-cfn-macros.h"
a3ca1bc5 42#include "gimplify.h"
71f82be9 43#include "optabs-tree.h"
6a86928d 44#include "tree-eh.h"
d398999d 45#include "dbgcnt.h"
75f89001 46#include "tm.h"
45f4e2b0 47#include "gimple-range.h"
3d2cf79f
RB
48
49/* Forward declarations of the private auto-generated matchers.
50 They expect valueized operands in canonical order and do not
51 perform simplification of all-constant operands. */
5d75ad95 52static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
3d2cf79f 53 code_helper, tree, tree);
5d75ad95 54static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
3d2cf79f 55 code_helper, tree, tree, tree);
5d75ad95 56static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
3d2cf79f 57 code_helper, tree, tree, tree, tree);
0d2b3bca
RS
58static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
59 code_helper, tree, tree, tree, tree, tree);
b41d1f6e
RS
60static bool gimple_simplify (gimple_match_op *, gimple_seq *, tree (*)(tree),
61 code_helper, tree, tree, tree, tree, tree, tree);
b7fe158a
RB
62static bool gimple_resimplify1 (gimple_seq *, gimple_match_op *,
63 tree (*)(tree));
64static bool gimple_resimplify2 (gimple_seq *, gimple_match_op *,
65 tree (*)(tree));
66static bool gimple_resimplify3 (gimple_seq *, gimple_match_op *,
67 tree (*)(tree));
68static bool gimple_resimplify4 (gimple_seq *, gimple_match_op *,
69 tree (*)(tree));
70static bool gimple_resimplify5 (gimple_seq *, gimple_match_op *,
71 tree (*)(tree));
3d2cf79f 72
5d75ad95 73const unsigned int gimple_match_op::MAX_NUM_OPS;
3d2cf79f
RB
74
75/* Return whether T is a constant that we'll dispatch to fold to
76 evaluate fully constant expressions. */
77
78static inline bool
79constant_for_folding (tree t)
80{
81 return (CONSTANT_CLASS_P (t)
82 /* The following is only interesting to string builtins. */
83 || (TREE_CODE (t) == ADDR_EXPR
84 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
85}
86
6a86928d
RS
87/* Try to convert conditional operation ORIG_OP into an IFN_COND_*
88 operation. Return true on success, storing the new operation in NEW_OP. */
89
90static bool
91convert_conditional_op (gimple_match_op *orig_op,
92 gimple_match_op *new_op)
93{
94 internal_fn ifn;
95 if (orig_op->code.is_tree_code ())
96 ifn = get_conditional_internal_fn ((tree_code) orig_op->code);
97 else
b41d1f6e 98 {
0c1fb64d 99 auto cfn = combined_fn (orig_op->code);
b41d1f6e
RS
100 if (!internal_fn_p (cfn))
101 return false;
102 ifn = get_conditional_internal_fn (as_internal_fn (cfn));
103 }
6a86928d
RS
104 if (ifn == IFN_LAST)
105 return false;
106 unsigned int num_ops = orig_op->num_ops;
107 new_op->set_op (as_combined_fn (ifn), orig_op->type, num_ops + 2);
108 new_op->ops[0] = orig_op->cond.cond;
109 for (unsigned int i = 0; i < num_ops; ++i)
110 new_op->ops[i + 1] = orig_op->ops[i];
111 tree else_value = orig_op->cond.else_value;
112 if (!else_value)
113 else_value = targetm.preferred_else_value (ifn, orig_op->type,
114 num_ops, orig_op->ops);
115 new_op->ops[num_ops + 1] = else_value;
116 return true;
117}
118
119/* RES_OP is the result of a simplification. If it is conditional,
120 try to replace it with the equivalent UNCOND form, such as an
121 IFN_COND_* call or a VEC_COND_EXPR. Also try to resimplify the
122 result of the replacement if appropriate, adding any new statements to
123 SEQ and using VALUEIZE as the valueization function. Return true if
124 this resimplification occurred and resulted in at least one change. */
125
126static bool
127maybe_resimplify_conditional_op (gimple_seq *seq, gimple_match_op *res_op,
128 tree (*valueize) (tree))
129{
130 if (!res_op->cond.cond)
131 return false;
132
133 if (!res_op->cond.else_value
134 && res_op->code.is_tree_code ())
135 {
136 /* The "else" value doesn't matter. If the "then" value is a
137 gimple value, just use it unconditionally. This isn't a
138 simplification in itself, since there was no operation to
139 build in the first place. */
140 if (gimple_simplified_result_is_gimple_val (res_op))
141 {
142 res_op->cond.cond = NULL_TREE;
143 return false;
144 }
145
146 /* Likewise if the operation would not trap. */
147 bool honor_trapv = (INTEGRAL_TYPE_P (res_op->type)
148 && TYPE_OVERFLOW_TRAPS (res_op->type));
6851de8b
FH
149 tree_code op_code = (tree_code) res_op->code;
150 bool op_could_trap;
151
35b2be21 152 /* COND_EXPR will trap if, and only if, the condition
6851de8b
FH
153 traps and hence we have to check this. For all other operations, we
154 don't need to consider the operands. */
35b2be21 155 if (op_code == COND_EXPR)
6851de8b
FH
156 op_could_trap = generic_expr_could_trap_p (res_op->ops[0]);
157 else
158 op_could_trap = operation_could_trap_p ((tree_code) res_op->code,
159 FLOAT_TYPE_P (res_op->type),
160 honor_trapv,
161 res_op->op_or_null (1));
162
163 if (!op_could_trap)
6a86928d
RS
164 {
165 res_op->cond.cond = NULL_TREE;
166 return false;
167 }
168 }
169
170 /* If the "then" value is a gimple value and the "else" value matters,
171 create a VEC_COND_EXPR between them, then see if it can be further
172 simplified. */
173 gimple_match_op new_op;
174 if (res_op->cond.else_value
175 && VECTOR_TYPE_P (res_op->type)
176 && gimple_simplified_result_is_gimple_val (res_op))
177 {
178 new_op.set_op (VEC_COND_EXPR, res_op->type,
179 res_op->cond.cond, res_op->ops[0],
180 res_op->cond.else_value);
181 *res_op = new_op;
182 return gimple_resimplify3 (seq, res_op, valueize);
183 }
184
185 /* Otherwise try rewriting the operation as an IFN_COND_* call.
186 Again, this isn't a simplification in itself, since it's what
187 RES_OP already described. */
188 if (convert_conditional_op (res_op, &new_op))
189 *res_op = new_op;
190
191 return false;
192}
3d2cf79f
RB
193
194/* Helper that matches and simplifies the toplevel result from
195 a gimple_simplify run (where we don't want to build
196 a stmt in case it's used in in-place folding). Replaces
5d75ad95
RS
197 RES_OP with a simplified and/or canonicalized result and
198 returns whether any change was made. */
3d2cf79f 199
b7fe158a 200static bool
5d75ad95 201gimple_resimplify1 (gimple_seq *seq, gimple_match_op *res_op,
3d2cf79f
RB
202 tree (*valueize)(tree))
203{
5d75ad95 204 if (constant_for_folding (res_op->ops[0]))
3d2cf79f
RB
205 {
206 tree tem = NULL_TREE;
5d75ad95 207 if (res_op->code.is_tree_code ())
c47bee97 208 {
0c1fb64d 209 auto code = tree_code (res_op->code);
c47bee97
JJ
210 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
211 && TREE_CODE_LENGTH (code) == 1)
0c1fb64d 212 tem = const_unop (code, res_op->type, res_op->ops[0]);
c47bee97 213 }
3d2cf79f 214 else
5d75ad95
RS
215 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
216 res_op->ops[0]);
3d2cf79f
RB
217 if (tem != NULL_TREE
218 && CONSTANT_CLASS_P (tem))
219 {
1f3131cb
RB
220 if (TREE_OVERFLOW_P (tem))
221 tem = drop_tree_overflow (tem);
5d75ad95 222 res_op->set_value (tem);
6a86928d 223 maybe_resimplify_conditional_op (seq, res_op, valueize);
3d2cf79f
RB
224 return true;
225 }
226 }
227
19353855
RB
228 /* Limit recursion, there are cases like PR80887 and others, for
229 example when value-numbering presents us with unfolded expressions
230 that we are really not prepared to handle without eventual
231 oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50
232 itself as available expression. */
233 static unsigned depth;
234 if (depth > 10)
235 {
236 if (dump_file && (dump_flags & TDF_FOLDING))
237 fprintf (dump_file, "Aborting expression simplification due to "
238 "deep recursion\n");
239 return false;
240 }
241
242 ++depth;
5d75ad95
RS
243 gimple_match_op res_op2 (*res_op);
244 if (gimple_simplify (&res_op2, seq, valueize,
245 res_op->code, res_op->type, res_op->ops[0]))
3d2cf79f 246 {
19353855 247 --depth;
5d75ad95 248 *res_op = res_op2;
3d2cf79f
RB
249 return true;
250 }
19353855 251 --depth;
3d2cf79f 252
6a86928d
RS
253 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
254 return true;
255
3d2cf79f
RB
256 return false;
257}
258
259/* Helper that matches and simplifies the toplevel result from
260 a gimple_simplify run (where we don't want to build
261 a stmt in case it's used in in-place folding). Replaces
5d75ad95
RS
262 RES_OP with a simplified and/or canonicalized result and
263 returns whether any change was made. */
3d2cf79f 264
b7fe158a 265static bool
5d75ad95 266gimple_resimplify2 (gimple_seq *seq, gimple_match_op *res_op,
3d2cf79f
RB
267 tree (*valueize)(tree))
268{
5d75ad95
RS
269 if (constant_for_folding (res_op->ops[0])
270 && constant_for_folding (res_op->ops[1]))
3d2cf79f
RB
271 {
272 tree tem = NULL_TREE;
5d75ad95 273 if (res_op->code.is_tree_code ())
c47bee97 274 {
0c1fb64d 275 auto code = tree_code (res_op->code);
c47bee97
JJ
276 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
277 && TREE_CODE_LENGTH (code) == 2)
0c1fb64d 278 tem = const_binop (code, res_op->type,
c47bee97
JJ
279 res_op->ops[0], res_op->ops[1]);
280 }
3d2cf79f 281 else
5d75ad95
RS
282 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
283 res_op->ops[0], res_op->ops[1]);
3d2cf79f
RB
284 if (tem != NULL_TREE
285 && CONSTANT_CLASS_P (tem))
286 {
1f3131cb
RB
287 if (TREE_OVERFLOW_P (tem))
288 tem = drop_tree_overflow (tem);
5d75ad95 289 res_op->set_value (tem);
6a86928d 290 maybe_resimplify_conditional_op (seq, res_op, valueize);
3d2cf79f
RB
291 return true;
292 }
293 }
294
295 /* Canonicalize operand order. */
296 bool canonicalized = false;
e9fff24c
RS
297 bool is_comparison
298 = (res_op->code.is_tree_code ()
299 && TREE_CODE_CLASS (tree_code (res_op->code)) == tcc_comparison);
300 if ((is_comparison || commutative_binary_op_p (res_op->code, res_op->type))
301 && tree_swap_operands_p (res_op->ops[0], res_op->ops[1]))
3d2cf79f 302 {
e9fff24c
RS
303 std::swap (res_op->ops[0], res_op->ops[1]);
304 if (is_comparison)
305 res_op->code = swap_tree_comparison (tree_code (res_op->code));
306 canonicalized = true;
3d2cf79f
RB
307 }
308
19353855
RB
309 /* Limit recursion, see gimple_resimplify1. */
310 static unsigned depth;
311 if (depth > 10)
312 {
313 if (dump_file && (dump_flags & TDF_FOLDING))
314 fprintf (dump_file, "Aborting expression simplification due to "
315 "deep recursion\n");
316 return false;
317 }
318
319 ++depth;
5d75ad95
RS
320 gimple_match_op res_op2 (*res_op);
321 if (gimple_simplify (&res_op2, seq, valueize,
322 res_op->code, res_op->type,
323 res_op->ops[0], res_op->ops[1]))
3d2cf79f 324 {
19353855 325 --depth;
5d75ad95 326 *res_op = res_op2;
3d2cf79f
RB
327 return true;
328 }
19353855 329 --depth;
3d2cf79f 330
6a86928d
RS
331 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
332 return true;
333
3d2cf79f
RB
334 return canonicalized;
335}
336
337/* Helper that matches and simplifies the toplevel result from
338 a gimple_simplify run (where we don't want to build
339 a stmt in case it's used in in-place folding). Replaces
5d75ad95
RS
340 RES_OP with a simplified and/or canonicalized result and
341 returns whether any change was made. */
3d2cf79f 342
b7fe158a 343static bool
5d75ad95 344gimple_resimplify3 (gimple_seq *seq, gimple_match_op *res_op,
3d2cf79f
RB
345 tree (*valueize)(tree))
346{
5d75ad95
RS
347 if (constant_for_folding (res_op->ops[0])
348 && constant_for_folding (res_op->ops[1])
349 && constant_for_folding (res_op->ops[2]))
3d2cf79f
RB
350 {
351 tree tem = NULL_TREE;
5d75ad95 352 if (res_op->code.is_tree_code ())
c47bee97 353 {
0c1fb64d 354 auto code = tree_code (res_op->code);
c47bee97
JJ
355 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
356 && TREE_CODE_LENGTH (code) == 3)
0c1fb64d 357 tem = fold_ternary/*_to_constant*/ (code, res_op->type,
c47bee97
JJ
358 res_op->ops[0], res_op->ops[1],
359 res_op->ops[2]);
360 }
3d2cf79f 361 else
5d75ad95
RS
362 tem = fold_const_call (combined_fn (res_op->code), res_op->type,
363 res_op->ops[0], res_op->ops[1], res_op->ops[2]);
3d2cf79f
RB
364 if (tem != NULL_TREE
365 && CONSTANT_CLASS_P (tem))
366 {
1f3131cb
RB
367 if (TREE_OVERFLOW_P (tem))
368 tem = drop_tree_overflow (tem);
5d75ad95 369 res_op->set_value (tem);
6a86928d 370 maybe_resimplify_conditional_op (seq, res_op, valueize);
3d2cf79f
RB
371 return true;
372 }
373 }
374
375 /* Canonicalize operand order. */
376 bool canonicalized = false;
e9fff24c
RS
377 int argno = first_commutative_argument (res_op->code, res_op->type);
378 if (argno >= 0
379 && tree_swap_operands_p (res_op->ops[argno], res_op->ops[argno + 1]))
3d2cf79f 380 {
e9fff24c 381 std::swap (res_op->ops[argno], res_op->ops[argno + 1]);
3d2cf79f
RB
382 canonicalized = true;
383 }
384
19353855
RB
385 /* Limit recursion, see gimple_resimplify1. */
386 static unsigned depth;
387 if (depth > 10)
388 {
389 if (dump_file && (dump_flags & TDF_FOLDING))
390 fprintf (dump_file, "Aborting expression simplification due to "
391 "deep recursion\n");
392 return false;
393 }
394
395 ++depth;
5d75ad95
RS
396 gimple_match_op res_op2 (*res_op);
397 if (gimple_simplify (&res_op2, seq, valueize,
398 res_op->code, res_op->type,
399 res_op->ops[0], res_op->ops[1], res_op->ops[2]))
3d2cf79f 400 {
19353855 401 --depth;
5d75ad95 402 *res_op = res_op2;
3d2cf79f
RB
403 return true;
404 }
19353855 405 --depth;
3d2cf79f 406
6a86928d
RS
407 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
408 return true;
409
3d2cf79f
RB
410 return canonicalized;
411}
412
0d2b3bca
RS
413/* Helper that matches and simplifies the toplevel result from
414 a gimple_simplify run (where we don't want to build
415 a stmt in case it's used in in-place folding). Replaces
416 RES_OP with a simplified and/or canonicalized result and
417 returns whether any change was made. */
418
b7fe158a 419static bool
0d2b3bca
RS
420gimple_resimplify4 (gimple_seq *seq, gimple_match_op *res_op,
421 tree (*valueize)(tree))
422{
423 /* No constant folding is defined for four-operand functions. */
424
e9fff24c
RS
425 /* Canonicalize operand order. */
426 bool canonicalized = false;
427 int argno = first_commutative_argument (res_op->code, res_op->type);
428 if (argno >= 0
429 && tree_swap_operands_p (res_op->ops[argno], res_op->ops[argno + 1]))
430 {
431 std::swap (res_op->ops[argno], res_op->ops[argno + 1]);
432 canonicalized = true;
433 }
434
19353855
RB
435 /* Limit recursion, see gimple_resimplify1. */
436 static unsigned depth;
437 if (depth > 10)
438 {
439 if (dump_file && (dump_flags & TDF_FOLDING))
440 fprintf (dump_file, "Aborting expression simplification due to "
441 "deep recursion\n");
442 return false;
443 }
444
445 ++depth;
0d2b3bca
RS
446 gimple_match_op res_op2 (*res_op);
447 if (gimple_simplify (&res_op2, seq, valueize,
448 res_op->code, res_op->type,
449 res_op->ops[0], res_op->ops[1], res_op->ops[2],
450 res_op->ops[3]))
451 {
19353855 452 --depth;
0d2b3bca
RS
453 *res_op = res_op2;
454 return true;
455 }
19353855 456 --depth;
0d2b3bca 457
6a86928d
RS
458 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
459 return true;
460
e9fff24c 461 return canonicalized;
0d2b3bca 462}
3d2cf79f 463
b41d1f6e
RS
464/* Helper that matches and simplifies the toplevel result from
465 a gimple_simplify run (where we don't want to build
466 a stmt in case it's used in in-place folding). Replaces
467 RES_OP with a simplified and/or canonicalized result and
468 returns whether any change was made. */
469
b7fe158a 470static bool
b41d1f6e
RS
471gimple_resimplify5 (gimple_seq *seq, gimple_match_op *res_op,
472 tree (*valueize)(tree))
473{
474 /* No constant folding is defined for five-operand functions. */
475
e9fff24c
RS
476 /* Canonicalize operand order. */
477 bool canonicalized = false;
478 int argno = first_commutative_argument (res_op->code, res_op->type);
479 if (argno >= 0
480 && tree_swap_operands_p (res_op->ops[argno], res_op->ops[argno + 1]))
481 {
482 std::swap (res_op->ops[argno], res_op->ops[argno + 1]);
483 canonicalized = true;
484 }
485
b41d1f6e
RS
486 gimple_match_op res_op2 (*res_op);
487 if (gimple_simplify (&res_op2, seq, valueize,
488 res_op->code, res_op->type,
489 res_op->ops[0], res_op->ops[1], res_op->ops[2],
490 res_op->ops[3], res_op->ops[4]))
491 {
492 *res_op = res_op2;
493 return true;
494 }
495
496 if (maybe_resimplify_conditional_op (seq, res_op, valueize))
497 return true;
498
e9fff24c 499 return canonicalized;
b41d1f6e
RS
500}
501
b7fe158a
RB
502/* Match and simplify the toplevel valueized operation THIS.
503 Replaces THIS with a simplified and/or canonicalized result and
504 returns whether any change was made. */
505
506bool
507gimple_match_op::resimplify (gimple_seq *seq, tree (*valueize)(tree))
508{
509 switch (num_ops)
510 {
511 case 1:
512 return gimple_resimplify1 (seq, this, valueize);
513 case 2:
514 return gimple_resimplify2 (seq, this, valueize);
515 case 3:
516 return gimple_resimplify3 (seq, this, valueize);
517 case 4:
518 return gimple_resimplify4 (seq, this, valueize);
519 case 5:
520 return gimple_resimplify5 (seq, this, valueize);
521 default:
522 gcc_unreachable ();
523 }
524}
525
5d75ad95
RS
526/* If in GIMPLE the operation described by RES_OP should be single-rhs,
527 build a GENERIC tree for that expression and update RES_OP accordingly. */
3d2cf79f
RB
528
529void
5d75ad95 530maybe_build_generic_op (gimple_match_op *res_op)
3d2cf79f 531{
5d75ad95 532 tree_code code = (tree_code) res_op->code;
de310193 533 tree val;
3d2cf79f
RB
534 switch (code)
535 {
536 case REALPART_EXPR:
537 case IMAGPART_EXPR:
538 case VIEW_CONVERT_EXPR:
de310193
EB
539 val = build1 (code, res_op->type, res_op->ops[0]);
540 res_op->set_value (val);
3d2cf79f
RB
541 break;
542 case BIT_FIELD_REF:
de310193
EB
543 val = build3 (code, res_op->type, res_op->ops[0], res_op->ops[1],
544 res_op->ops[2]);
545 REF_REVERSE_STORAGE_ORDER (val) = res_op->reverse;
546 res_op->set_value (val);
3d2cf79f
RB
547 break;
548 default:;
549 }
550}
551
5d75ad95 552tree (*mprts_hook) (gimple_match_op *);
34050b6b 553
5d75ad95
RS
554/* Try to build RES_OP, which is known to be a call to FN. Return null
555 if the target doesn't support the function. */
c9e926ce
RS
556
557static gcall *
5d75ad95 558build_call_internal (internal_fn fn, gimple_match_op *res_op)
c9e926ce
RS
559{
560 if (direct_internal_fn_p (fn))
561 {
5d75ad95
RS
562 tree_pair types = direct_internal_fn_types (fn, res_op->type,
563 res_op->ops);
d95ab70a 564 if (!direct_internal_fn_supported_p (fn, types, OPTIMIZE_FOR_BOTH))
c9e926ce
RS
565 return NULL;
566 }
5d75ad95
RS
567 return gimple_build_call_internal (fn, res_op->num_ops,
568 res_op->op_or_null (0),
569 res_op->op_or_null (1),
0d2b3bca 570 res_op->op_or_null (2),
b41d1f6e
RS
571 res_op->op_or_null (3),
572 res_op->op_or_null (4));
c9e926ce
RS
573}
574
5d75ad95
RS
575/* Push the exploded expression described by RES_OP as a statement to
576 SEQ if necessary and return a gimple value denoting the value of the
577 expression. If RES is not NULL then the result will be always RES
578 and even gimple values are pushed to SEQ. */
3d2cf79f
RB
579
580tree
5d75ad95 581maybe_push_res_to_seq (gimple_match_op *res_op, gimple_seq *seq, tree res)
3d2cf79f 582{
5d75ad95
RS
583 tree *ops = res_op->ops;
584 unsigned num_ops = res_op->num_ops;
585
6a86928d
RS
586 /* The caller should have converted conditional operations into an UNCOND
587 form and resimplified as appropriate. The conditional form only
588 survives this far if that conversion failed. */
589 if (res_op->cond.cond)
590 return NULL_TREE;
591
5d75ad95 592 if (res_op->code.is_tree_code ())
3d2cf79f
RB
593 {
594 if (!res
5d75ad95 595 && gimple_simplified_result_is_gimple_val (res_op))
3d2cf79f 596 return ops[0];
34050b6b
RB
597 if (mprts_hook)
598 {
5d75ad95 599 tree tem = mprts_hook (res_op);
34050b6b
RB
600 if (tem)
601 return tem;
602 }
5d75ad95
RS
603 }
604
605 if (!seq)
606 return NULL_TREE;
607
608 /* Play safe and do not allow abnormals to be mentioned in
609 newly created statements. */
610 for (unsigned int i = 0; i < num_ops; ++i)
611 if (TREE_CODE (ops[i]) == SSA_NAME
612 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[i]))
613 return NULL_TREE;
614
615 if (num_ops > 0 && COMPARISON_CLASS_P (ops[0]))
616 for (unsigned int i = 0; i < 2; ++i)
617 if (TREE_CODE (TREE_OPERAND (ops[0], i)) == SSA_NAME
618 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0], i)))
3d2cf79f 619 return NULL_TREE;
5d75ad95
RS
620
621 if (res_op->code.is_tree_code ())
622 {
0c1fb64d 623 auto code = tree_code (res_op->code);
3d2cf79f 624 if (!res)
4aecfe19
RS
625 {
626 if (gimple_in_ssa_p (cfun))
5d75ad95 627 res = make_ssa_name (res_op->type);
4aecfe19 628 else
5d75ad95 629 res = create_tmp_reg (res_op->type);
4aecfe19 630 }
5d75ad95 631 maybe_build_generic_op (res_op);
0c1fb64d 632 gimple *new_stmt = gimple_build_assign (res, code,
5d75ad95
RS
633 res_op->op_or_null (0),
634 res_op->op_or_null (1),
635 res_op->op_or_null (2));
3d2cf79f
RB
636 gimple_seq_add_stmt_without_update (seq, new_stmt);
637 return res;
638 }
639 else
640 {
5d75ad95 641 gcc_assert (num_ops != 0);
0c1fb64d 642 auto fn = combined_fn (res_op->code);
c9e926ce
RS
643 gcall *new_stmt = NULL;
644 if (internal_fn_p (fn))
645 {
646 /* Generate the given function if we can. */
647 internal_fn ifn = as_internal_fn (fn);
5d75ad95 648 new_stmt = build_call_internal (ifn, res_op);
c9e926ce
RS
649 if (!new_stmt)
650 return NULL_TREE;
651 }
652 else
653 {
654 /* Find the function we want to call. */
655 tree decl = builtin_decl_implicit (as_builtin_fn (fn));
656 if (!decl)
657 return NULL;
658
659 /* We can't and should not emit calls to non-const functions. */
660 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
661 return NULL;
662
5d75ad95
RS
663 new_stmt = gimple_build_call (decl, num_ops,
664 res_op->op_or_null (0),
665 res_op->op_or_null (1),
0d2b3bca 666 res_op->op_or_null (2),
b41d1f6e
RS
667 res_op->op_or_null (3),
668 res_op->op_or_null (4));
c9e926ce 669 }
3d2cf79f 670 if (!res)
4aecfe19
RS
671 {
672 if (gimple_in_ssa_p (cfun))
5d75ad95 673 res = make_ssa_name (res_op->type);
4aecfe19 674 else
5d75ad95 675 res = create_tmp_reg (res_op->type);
4aecfe19 676 }
3d2cf79f
RB
677 gimple_call_set_lhs (new_stmt, res);
678 gimple_seq_add_stmt_without_update (seq, new_stmt);
679 return res;
680 }
681}
682
683
684/* Public API overloads follow for operation being tree_code or
685 built_in_function and for one to three operands or arguments.
686 They return NULL_TREE if nothing could be simplified or
687 the resulting simplified value with parts pushed to SEQ.
688 If SEQ is NULL then if the simplification needs to create
689 new stmts it will fail. If VALUEIZE is non-NULL then all
690 SSA names will be valueized using that hook prior to
691 applying simplifications. */
692
693/* Unary ops. */
694
695tree
696gimple_simplify (enum tree_code code, tree type,
697 tree op0,
698 gimple_seq *seq, tree (*valueize)(tree))
699{
700 if (constant_for_folding (op0))
701 {
8006f46b 702 tree res = const_unop (code, type, op0);
3d2cf79f
RB
703 if (res != NULL_TREE
704 && CONSTANT_CLASS_P (res))
705 return res;
706 }
707
5d75ad95
RS
708 gimple_match_op res_op;
709 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0))
3d2cf79f 710 return NULL_TREE;
5d75ad95 711 return maybe_push_res_to_seq (&res_op, seq);
3d2cf79f
RB
712}
713
714/* Binary ops. */
715
716tree
717gimple_simplify (enum tree_code code, tree type,
718 tree op0, tree op1,
719 gimple_seq *seq, tree (*valueize)(tree))
720{
721 if (constant_for_folding (op0) && constant_for_folding (op1))
722 {
8006f46b 723 tree res = const_binop (code, type, op0, op1);
3d2cf79f
RB
724 if (res != NULL_TREE
725 && CONSTANT_CLASS_P (res))
726 return res;
727 }
728
729 /* Canonicalize operand order both for matching and fallback stmt
730 generation. */
731 if ((commutative_tree_code (code)
732 || TREE_CODE_CLASS (code) == tcc_comparison)
14e72812 733 && tree_swap_operands_p (op0, op1))
3d2cf79f 734 {
6b4db501 735 std::swap (op0, op1);
3d2cf79f
RB
736 if (TREE_CODE_CLASS (code) == tcc_comparison)
737 code = swap_tree_comparison (code);
738 }
739
5d75ad95
RS
740 gimple_match_op res_op;
741 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1))
3d2cf79f 742 return NULL_TREE;
5d75ad95 743 return maybe_push_res_to_seq (&res_op, seq);
3d2cf79f
RB
744}
745
746/* Ternary ops. */
747
748tree
749gimple_simplify (enum tree_code code, tree type,
750 tree op0, tree op1, tree op2,
751 gimple_seq *seq, tree (*valueize)(tree))
752{
753 if (constant_for_folding (op0) && constant_for_folding (op1)
754 && constant_for_folding (op2))
755 {
756 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
757 if (res != NULL_TREE
758 && CONSTANT_CLASS_P (res))
759 return res;
760 }
761
762 /* Canonicalize operand order both for matching and fallback stmt
763 generation. */
764 if (commutative_ternary_tree_code (code)
14e72812 765 && tree_swap_operands_p (op0, op1))
6b4db501 766 std::swap (op0, op1);
3d2cf79f 767
5d75ad95
RS
768 gimple_match_op res_op;
769 if (!gimple_simplify (&res_op, seq, valueize, code, type, op0, op1, op2))
3d2cf79f 770 return NULL_TREE;
5d75ad95 771 return maybe_push_res_to_seq (&res_op, seq);
3d2cf79f
RB
772}
773
eb69361d 774/* Builtin or internal function with one argument. */
3d2cf79f
RB
775
776tree
eb69361d 777gimple_simplify (combined_fn fn, tree type,
3d2cf79f
RB
778 tree arg0,
779 gimple_seq *seq, tree (*valueize)(tree))
780{
781 if (constant_for_folding (arg0))
782 {
eb69361d 783 tree res = fold_const_call (fn, type, arg0);
c9e926ce
RS
784 if (res && CONSTANT_CLASS_P (res))
785 return res;
3d2cf79f
RB
786 }
787
5d75ad95
RS
788 gimple_match_op res_op;
789 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0))
3d2cf79f 790 return NULL_TREE;
5d75ad95 791 return maybe_push_res_to_seq (&res_op, seq);
3d2cf79f
RB
792}
793
eb69361d 794/* Builtin or internal function with two arguments. */
3d2cf79f
RB
795
796tree
eb69361d 797gimple_simplify (combined_fn fn, tree type,
3d2cf79f
RB
798 tree arg0, tree arg1,
799 gimple_seq *seq, tree (*valueize)(tree))
800{
801 if (constant_for_folding (arg0)
802 && constant_for_folding (arg1))
803 {
eb69361d 804 tree res = fold_const_call (fn, type, arg0, arg1);
c9e926ce
RS
805 if (res && CONSTANT_CLASS_P (res))
806 return res;
3d2cf79f
RB
807 }
808
5d75ad95
RS
809 gimple_match_op res_op;
810 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1))
3d2cf79f 811 return NULL_TREE;
5d75ad95 812 return maybe_push_res_to_seq (&res_op, seq);
3d2cf79f
RB
813}
814
eb69361d 815/* Builtin or internal function with three arguments. */
3d2cf79f
RB
816
817tree
eb69361d 818gimple_simplify (combined_fn fn, tree type,
3d2cf79f
RB
819 tree arg0, tree arg1, tree arg2,
820 gimple_seq *seq, tree (*valueize)(tree))
821{
822 if (constant_for_folding (arg0)
823 && constant_for_folding (arg1)
824 && constant_for_folding (arg2))
825 {
eb69361d 826 tree res = fold_const_call (fn, type, arg0, arg1, arg2);
c9e926ce
RS
827 if (res && CONSTANT_CLASS_P (res))
828 return res;
3d2cf79f
RB
829 }
830
5d75ad95
RS
831 gimple_match_op res_op;
832 if (!gimple_simplify (&res_op, seq, valueize, fn, type, arg0, arg1, arg2))
3d2cf79f 833 return NULL_TREE;
5d75ad95 834 return maybe_push_res_to_seq (&res_op, seq);
3d2cf79f
RB
835}
836
37d486ab
RB
837/* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
838 VALUEIZED to true if valueization changed OP. */
839
840static inline tree
841do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
842{
843 if (valueize && TREE_CODE (op) == SSA_NAME)
844 {
845 tree tem = valueize (op);
846 if (tem && tem != op)
847 {
848 op = tem;
849 valueized = true;
850 }
851 }
852 return op;
853}
3d2cf79f 854
6a86928d
RS
855/* If RES_OP is a call to a conditional internal function, try simplifying
856 the associated unconditional operation and using the result to build
857 a new conditional operation. For example, if RES_OP is:
858
859 IFN_COND_ADD (COND, A, B, ELSE)
860
861 try simplifying (plus A B) and using the result to build a replacement
862 for the whole IFN_COND_ADD.
863
864 Return true if this approach led to a simplification, otherwise leave
865 RES_OP unchanged (and so suitable for other simplifications). When
866 returning true, add any new statements to SEQ and use VALUEIZE as the
867 valueization function.
868
869 RES_OP is known to be a call to IFN. */
870
871static bool
872try_conditional_simplification (internal_fn ifn, gimple_match_op *res_op,
873 gimple_seq *seq, tree (*valueize) (tree))
874{
b41d1f6e 875 code_helper op;
6a86928d 876 tree_code code = conditional_internal_fn_code (ifn);
b41d1f6e
RS
877 if (code != ERROR_MARK)
878 op = code;
879 else
880 {
881 ifn = get_unconditional_internal_fn (ifn);
882 if (ifn == IFN_LAST)
883 return false;
884 op = as_combined_fn (ifn);
885 }
6a86928d
RS
886
887 unsigned int num_ops = res_op->num_ops;
888 gimple_match_op cond_op (gimple_match_cond (res_op->ops[0],
889 res_op->ops[num_ops - 1]),
b41d1f6e 890 op, res_op->type, num_ops - 2);
49fb45c8
MS
891
892 memcpy (cond_op.ops, res_op->ops + 1, (num_ops - 1) * sizeof *cond_op.ops);
6a86928d
RS
893 switch (num_ops - 2)
894 {
20dcda98 895 case 1:
896 if (!gimple_resimplify1 (seq, &cond_op, valueize))
897 return false;
898 break;
6a86928d
RS
899 case 2:
900 if (!gimple_resimplify2 (seq, &cond_op, valueize))
901 return false;
902 break;
b41d1f6e
RS
903 case 3:
904 if (!gimple_resimplify3 (seq, &cond_op, valueize))
905 return false;
906 break;
6a86928d
RS
907 default:
908 gcc_unreachable ();
909 }
910 *res_op = cond_op;
911 maybe_resimplify_conditional_op (seq, res_op, valueize);
912 return true;
913}
914
33973fa7
RS
915/* Common subroutine of gimple_extract_op and gimple_simplify. Try to
916 describe STMT in RES_OP, returning true on success. Before recording
917 an operand, call:
3d2cf79f 918
33973fa7
RS
919 - VALUEIZE_CONDITION for a COND_EXPR condition
920 - VALUEIZE_OP for every other top-level operand
921
922 Both routines take a tree argument and returns a tree. */
923
924template<typename ValueizeOp, typename ValueizeCondition>
925inline bool
926gimple_extract (gimple *stmt, gimple_match_op *res_op,
927 ValueizeOp valueize_op,
928 ValueizeCondition valueize_condition)
3d2cf79f
RB
929{
930 switch (gimple_code (stmt))
931 {
932 case GIMPLE_ASSIGN:
933 {
934 enum tree_code code = gimple_assign_rhs_code (stmt);
935 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
936 switch (gimple_assign_rhs_class (stmt))
937 {
938 case GIMPLE_SINGLE_RHS:
939 if (code == REALPART_EXPR
940 || code == IMAGPART_EXPR
941 || code == VIEW_CONVERT_EXPR)
942 {
943 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
33973fa7
RS
944 res_op->set_op (code, type, valueize_op (op0));
945 return true;
3d2cf79f
RB
946 }
947 else if (code == BIT_FIELD_REF)
948 {
949 tree rhs1 = gimple_assign_rhs1 (stmt);
33973fa7 950 tree op0 = valueize_op (TREE_OPERAND (rhs1, 0));
5d75ad95
RS
951 res_op->set_op (code, type, op0,
952 TREE_OPERAND (rhs1, 1),
de310193
EB
953 TREE_OPERAND (rhs1, 2),
954 REF_REVERSE_STORAGE_ORDER (rhs1));
33973fa7 955 return true;
3d2cf79f 956 }
33973fa7 957 else if (code == SSA_NAME)
3d2cf79f
RB
958 {
959 tree op0 = gimple_assign_rhs1 (stmt);
33973fa7 960 res_op->set_op (TREE_CODE (op0), type, valueize_op (op0));
3d2cf79f
RB
961 return true;
962 }
963 break;
964 case GIMPLE_UNARY_RHS:
965 {
966 tree rhs1 = gimple_assign_rhs1 (stmt);
33973fa7
RS
967 res_op->set_op (code, type, valueize_op (rhs1));
968 return true;
3d2cf79f
RB
969 }
970 case GIMPLE_BINARY_RHS:
971 {
33973fa7
RS
972 tree rhs1 = valueize_op (gimple_assign_rhs1 (stmt));
973 tree rhs2 = valueize_op (gimple_assign_rhs2 (stmt));
5d75ad95 974 res_op->set_op (code, type, rhs1, rhs2);
33973fa7 975 return true;
3d2cf79f
RB
976 }
977 case GIMPLE_TERNARY_RHS:
978 {
979 tree rhs1 = gimple_assign_rhs1 (stmt);
33973fa7
RS
980 if (code == COND_EXPR && COMPARISON_CLASS_P (rhs1))
981 rhs1 = valueize_condition (rhs1);
982 else
983 rhs1 = valueize_op (rhs1);
984 tree rhs2 = valueize_op (gimple_assign_rhs2 (stmt));
985 tree rhs3 = valueize_op (gimple_assign_rhs3 (stmt));
5d75ad95 986 res_op->set_op (code, type, rhs1, rhs2, rhs3);
33973fa7 987 return true;
3d2cf79f
RB
988 }
989 default:
990 gcc_unreachable ();
991 }
992 break;
993 }
994
995 case GIMPLE_CALL:
996 /* ??? This way we can't simplify calls with side-effects. */
37d486ab
RB
997 if (gimple_call_lhs (stmt) != NULL_TREE
998 && gimple_call_num_args (stmt) >= 1
b41d1f6e 999 && gimple_call_num_args (stmt) <= 5)
3d2cf79f 1000 {
5d75ad95 1001 combined_fn cfn;
c9e926ce 1002 if (gimple_call_internal_p (stmt))
5d75ad95 1003 cfn = as_combined_fn (gimple_call_internal_fn (stmt));
c9e926ce
RS
1004 else
1005 {
1006 tree fn = gimple_call_fn (stmt);
1007 if (!fn)
1008 return false;
3d2cf79f 1009
33973fa7 1010 fn = valueize_op (fn);
c9e926ce
RS
1011 if (TREE_CODE (fn) != ADDR_EXPR
1012 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
1013 return false;
1014
1015 tree decl = TREE_OPERAND (fn, 0);
1016 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
1017 || !gimple_builtin_call_types_compatible_p (stmt, decl))
1018 return false;
1019
5d75ad95 1020 cfn = as_combined_fn (DECL_FUNCTION_CODE (decl));
c9e926ce 1021 }
37d486ab 1022
5d75ad95
RS
1023 unsigned int num_args = gimple_call_num_args (stmt);
1024 res_op->set_op (cfn, TREE_TYPE (gimple_call_lhs (stmt)), num_args);
1025 for (unsigned i = 0; i < num_args; ++i)
33973fa7
RS
1026 res_op->ops[i] = valueize_op (gimple_call_arg (stmt, i));
1027 return true;
3d2cf79f
RB
1028 }
1029 break;
1030
1031 case GIMPLE_COND:
1032 {
33973fa7
RS
1033 tree lhs = valueize_op (gimple_cond_lhs (stmt));
1034 tree rhs = valueize_op (gimple_cond_rhs (stmt));
5d75ad95 1035 res_op->set_op (gimple_cond_code (stmt), boolean_type_node, lhs, rhs);
33973fa7 1036 return true;
3d2cf79f
RB
1037 }
1038
1039 default:
1040 break;
1041 }
1042
1043 return false;
1044}
1045
33973fa7
RS
1046/* Try to describe STMT in RES_OP, returning true on success.
1047 For GIMPLE_CONDs, describe the condition that is being tested.
1048 For GIMPLE_ASSIGNs, describe the rhs of the assignment.
1049 For GIMPLE_CALLs, describe the call. */
1050
1051bool
1052gimple_extract_op (gimple *stmt, gimple_match_op *res_op)
1053{
1054 auto nop = [](tree op) { return op; };
1055 return gimple_extract (stmt, res_op, nop, nop);
1056}
1057
1058/* The main STMT based simplification entry. It is used by the fold_stmt
1059 and the fold_stmt_to_constant APIs. */
1060
1061bool
1062gimple_simplify (gimple *stmt, gimple_match_op *res_op, gimple_seq *seq,
1063 tree (*valueize)(tree), tree (*top_valueize)(tree))
1064{
1065 bool valueized = false;
1066 auto valueize_op = [&](tree op)
1067 {
1068 return do_valueize (op, top_valueize, valueized);
1069 };
1070 auto valueize_condition = [&](tree op) -> tree
1071 {
1072 bool cond_valueized = false;
1073 tree lhs = do_valueize (TREE_OPERAND (op, 0), top_valueize,
1074 cond_valueized);
1075 tree rhs = do_valueize (TREE_OPERAND (op, 1), top_valueize,
1076 cond_valueized);
1077 gimple_match_op res_op2 (res_op->cond, TREE_CODE (op),
1078 TREE_TYPE (op), lhs, rhs);
1079 if ((gimple_resimplify2 (seq, &res_op2, valueize)
1080 || cond_valueized)
1081 && res_op2.code.is_tree_code ())
1082 {
0c1fb64d
RS
1083 auto code = tree_code (res_op2.code);
1084 if (TREE_CODE_CLASS (code) == tcc_comparison)
33973fa7
RS
1085 {
1086 valueized = true;
0c1fb64d 1087 return build2 (code, TREE_TYPE (op),
33973fa7
RS
1088 res_op2.ops[0], res_op2.ops[1]);
1089 }
0c1fb64d
RS
1090 else if (code == SSA_NAME
1091 || code == INTEGER_CST
1092 || code == VECTOR_CST)
33973fa7
RS
1093 {
1094 valueized = true;
1095 return res_op2.ops[0];
1096 }
1097 }
1098 return valueize_op (op);
1099 };
1100
1101 if (!gimple_extract (stmt, res_op, valueize_op, valueize_condition))
1102 return false;
1103
1104 if (res_op->code.is_internal_fn ())
1105 {
1106 internal_fn ifn = internal_fn (res_op->code);
1107 if (try_conditional_simplification (ifn, res_op, seq, valueize))
1108 return true;
1109 }
1110
1111 if (!res_op->reverse
1112 && res_op->num_ops
1113 && res_op->resimplify (seq, valueize))
1114 return true;
1115
1116 return valueized;
1117}
3d2cf79f
RB
1118
1119/* Helper for the autogenerated code, valueize OP. */
1120
1121inline tree
1122do_valueize (tree (*valueize)(tree), tree op)
1123{
1124 if (valueize && TREE_CODE (op) == SSA_NAME)
4f450a2b
RB
1125 {
1126 tree tem = valueize (op);
1127 if (tem)
1128 return tem;
1129 }
3d2cf79f
RB
1130 return op;
1131}
1132
4f450a2b
RB
1133/* Helper for the autogenerated code, get at the definition of NAME when
1134 VALUEIZE allows that. */
1135
1136inline gimple *
1137get_def (tree (*valueize)(tree), tree name)
1138{
1139 if (valueize && ! valueize (name))
1140 return NULL;
1141 return SSA_NAME_DEF_STMT (name);
1142}
1143
48451e8f 1144/* Routine to determine if the types T1 and T2 are effectively
aea417d7
MG
1145 the same for GIMPLE. If T1 or T2 is not a type, the test
1146 applies to their TREE_TYPE. */
48451e8f
JL
1147
1148static inline bool
1149types_match (tree t1, tree t2)
1150{
aea417d7
MG
1151 if (!TYPE_P (t1))
1152 t1 = TREE_TYPE (t1);
1153 if (!TYPE_P (t2))
1154 t2 = TREE_TYPE (t2);
1155
48451e8f
JL
1156 return types_compatible_p (t1, t2);
1157}
1158
1159/* Return if T has a single use. For GIMPLE, we also allow any
1160 non-SSA_NAME (ie constants) and zero uses to cope with uses
1161 that aren't linked up yet. */
1162
6aef670e
RS
1163static bool
1164single_use (const_tree) ATTRIBUTE_PURE;
1165
1166static bool
1167single_use (const_tree t)
48451e8f 1168{
6aef670e
RS
1169 if (TREE_CODE (t) != SSA_NAME)
1170 return true;
1171
1172 /* Inline return has_zero_uses (t) || has_single_use (t); */
1173 const ssa_use_operand_t *const head = &(SSA_NAME_IMM_USE_NODE (t));
1174 const ssa_use_operand_t *ptr;
1175 bool single = false;
1176
1177 for (ptr = head->next; ptr != head; ptr = ptr->next)
1178 if (USE_STMT(ptr) && !is_gimple_debug (USE_STMT (ptr)))
1179 {
1180 if (single)
1181 return false;
1182 single = true;
1183 }
1184 return true;
48451e8f 1185}
53f3cd25
RS
1186
1187/* Return true if math operations should be canonicalized,
1188 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
1189
1190static inline bool
1191canonicalize_math_p ()
1192{
1193 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
1194}
848bb6fc
JJ
1195
1196/* Return true if math operations that are beneficial only after
1197 vectorization should be canonicalized. */
1198
1199static inline bool
1200canonicalize_math_after_vectorization_p ()
1201{
1202 return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
1203}
30a2c10e 1204
a1ee6d50
MG
1205/* Return true if we can still perform transformations that may introduce
1206 vector operations that are not supported by the target. Vector lowering
1207 normally handles those, but after that pass, it becomes unsafe. */
1208
1209static inline bool
1210optimize_vectors_before_lowering_p ()
1211{
1212 return !cfun || (cfun->curr_properties & PROP_gimple_lvec) == 0;
1213}
1214
30a2c10e
JJ
1215/* Return true if pow(cst, x) should be optimized into exp(log(cst) * x).
1216 As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0
1217 is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...>
1218 where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1)
1219 will likely be exact, while exp (log (arg0) * arg1) might be not.
1220 Also don't do it if arg1 is phi_res above and cst2 is an exact integer. */
1221
1222static bool
1223optimize_pow_to_exp (tree arg0, tree arg1)
1224{
1225 gcc_assert (TREE_CODE (arg0) == REAL_CST);
1226 if (!real_isinteger (TREE_REAL_CST_PTR (arg0), TYPE_MODE (TREE_TYPE (arg0))))
1227 return true;
1228
1229 if (TREE_CODE (arg1) != SSA_NAME)
1230 return true;
1231
1232 gimple *def = SSA_NAME_DEF_STMT (arg1);
1233 gphi *phi = dyn_cast <gphi *> (def);
1234 tree cst1 = NULL_TREE;
1235 enum tree_code code = ERROR_MARK;
1236 if (!phi)
1237 {
1238 if (!is_gimple_assign (def))
1239 return true;
1240 code = gimple_assign_rhs_code (def);
1241 switch (code)
1242 {
1243 case PLUS_EXPR:
1244 case MINUS_EXPR:
1245 break;
1246 default:
1247 return true;
1248 }
1249 if (TREE_CODE (gimple_assign_rhs1 (def)) != SSA_NAME
1250 || TREE_CODE (gimple_assign_rhs2 (def)) != REAL_CST)
1251 return true;
1252
1253 cst1 = gimple_assign_rhs2 (def);
1254
1255 phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def)));
1256 if (!phi)
1257 return true;
1258 }
1259
1260 tree cst2 = NULL_TREE;
1261 int n = gimple_phi_num_args (phi);
1262 for (int i = 0; i < n; i++)
1263 {
1264 tree arg = PHI_ARG_DEF (phi, i);
1265 if (TREE_CODE (arg) != REAL_CST)
1266 continue;
1267 else if (cst2 == NULL_TREE)
1268 cst2 = arg;
1269 else if (!operand_equal_p (cst2, arg, 0))
1270 return true;
1271 }
1272
1273 if (cst1 && cst2)
1274 cst2 = const_binop (code, TREE_TYPE (cst2), cst2, cst1);
1275 if (cst2
1276 && TREE_CODE (cst2) == REAL_CST
1277 && real_isinteger (TREE_REAL_CST_PTR (cst2),
1278 TYPE_MODE (TREE_TYPE (cst2))))
1279 return false;
1280 return true;
1281}
98610dc5
JJ
1282
1283/* Return true if a division INNER_DIV / DIVISOR where INNER_DIV
1284 is another division can be optimized. Don't optimize if INNER_DIV
1285 is used in a TRUNC_MOD_EXPR with DIVISOR as second operand. */
1286
1287static bool
1288optimize_successive_divisions_p (tree divisor, tree inner_div)
1289{
1290 if (!gimple_in_ssa_p (cfun))
1291 return false;
1292
1293 imm_use_iterator imm_iter;
1294 use_operand_p use_p;
1295 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, inner_div)
1296 {
1297 gimple *use_stmt = USE_STMT (use_p);
1298 if (!is_gimple_assign (use_stmt)
1299 || gimple_assign_rhs_code (use_stmt) != TRUNC_MOD_EXPR
1300 || !operand_equal_p (gimple_assign_rhs2 (use_stmt), divisor, 0))
1301 continue;
1302 return false;
1303 }
1304 return true;
1305}
30213ae9
RS
1306
1307/* Return a canonical form for CODE when operating on TYPE. The idea
1308 is to remove redundant ways of representing the same operation so
1309 that code_helpers can be hashed and compared for equality.
1310
1311 The only current canonicalization is to replace built-in functions
1312 with internal functions, in cases where internal-fn.def defines
1313 such an internal function.
1314
1315 Note that the new code_helper cannot necessarily be used in place of
1316 the original code_helper. For example, the new code_helper might be
1317 an internal function that the target does not support. */
1318
1319code_helper
1320canonicalize_code (code_helper code, tree type)
1321{
1322 if (code.is_fn_code ())
1323 return associated_internal_fn (combined_fn (code), type);
1324 return code;
1325}
1326
1327/* Return true if CODE is a binary operation and if CODE is commutative when
1328 operating on type TYPE. */
1329
1330bool
1331commutative_binary_op_p (code_helper code, tree type)
1332{
1333 if (code.is_tree_code ())
1334 return commutative_tree_code (tree_code (code));
1335 auto cfn = combined_fn (code);
1336 return commutative_binary_fn_p (associated_internal_fn (cfn, type));
1337}
1338
1339/* Return true if CODE represents a ternary operation and if the first two
1340 operands are commutative when CODE is operating on TYPE. */
1341
1342bool
1343commutative_ternary_op_p (code_helper code, tree type)
1344{
1345 if (code.is_tree_code ())
1346 return commutative_ternary_tree_code (tree_code (code));
1347 auto cfn = combined_fn (code);
1348 return commutative_ternary_fn_p (associated_internal_fn (cfn, type));
1349}
1350
1351/* If CODE is commutative in two consecutive operands, return the
1352 index of the first, otherwise return -1. */
1353
1354int
1355first_commutative_argument (code_helper code, tree type)
1356{
1357 if (code.is_tree_code ())
1358 {
1359 auto tcode = tree_code (code);
1360 if (commutative_tree_code (tcode)
1361 || commutative_ternary_tree_code (tcode))
1362 return 0;
1363 return -1;
1364 }
1365 auto cfn = combined_fn (code);
1366 return first_commutative_argument (associated_internal_fn (cfn, type));
1367}
1368
1369/* Return true if CODE is a binary operation that is associative when
1370 operating on type TYPE. */
1371
1372bool
1373associative_binary_op_p (code_helper code, tree type)
1374{
1375 if (code.is_tree_code ())
1376 return associative_tree_code (tree_code (code));
1377 auto cfn = combined_fn (code);
1378 return associative_binary_fn_p (associated_internal_fn (cfn, type));
1379}
1380
1381/* Return true if the target directly supports operation CODE on type TYPE.
1382 QUERY_TYPE acts as for optab_for_tree_code. */
1383
1384bool
1385directly_supported_p (code_helper code, tree type, optab_subtype query_type)
1386{
1387 if (code.is_tree_code ())
1388 {
1389 direct_optab optab = optab_for_tree_code (tree_code (code), type,
1390 query_type);
1391 return (optab != unknown_optab
1392 && optab_handler (optab, TYPE_MODE (type)) != CODE_FOR_nothing);
1393 }
1394 gcc_assert (query_type == optab_default
1395 || (query_type == optab_vector && VECTOR_TYPE_P (type))
1396 || (query_type == optab_scalar && !VECTOR_TYPE_P (type)));
1397 internal_fn ifn = associated_internal_fn (combined_fn (code), type);
1398 return (direct_internal_fn_p (ifn)
1399 && direct_internal_fn_supported_p (ifn, type, OPTIMIZE_FOR_SPEED));
1400}
1401
e53b6e56 1402/* A wrapper around the internal-fn.cc versions of get_conditional_internal_fn
30213ae9
RS
1403 for a code_helper CODE operating on type TYPE. */
1404
1405internal_fn
1406get_conditional_internal_fn (code_helper code, tree type)
1407{
1408 if (code.is_tree_code ())
1409 return get_conditional_internal_fn (tree_code (code));
1410 auto cfn = combined_fn (code);
1411 return get_conditional_internal_fn (associated_internal_fn (cfn, type));
1412}
This page took 3.399382 seconds and 5 git commands to generate.