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