]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gimple-match-head.c
re PR c++/67845 (ICE on invalid use of const qualifier on x86_64-linux-gnu in merge_t...
[thirdparty/gcc.git] / gcc / gimple-match-head.c
CommitLineData
3d2cf79f 1/* Preamble and helpers for the autogenerated gimple-match.c file.
5624e564 2 Copyright (C) 2014-2015 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
AM
23#include "backend.h"
24#include "tree.h"
25#include "gimple.h"
26#include "rtl.h"
27#include "ssa.h"
40e23961 28#include "alias.h"
40e23961 29#include "options.h"
40e23961 30#include "fold-const.h"
3d2cf79f
RB
31#include "stor-layout.h"
32#include "flags.h"
3d2cf79f 33#include "internal-fn.h"
3d2cf79f
RB
34#include "gimple-fold.h"
35#include "gimple-iterator.h"
36566b39
PK
36#include "insn-config.h"
37#include "expmed.h"
38#include "dojump.h"
39#include "explow.h"
40#include "calls.h"
41#include "emit-rtl.h"
42#include "varasm.h"
43#include "stmt.h"
3d2cf79f
RB
44#include "expr.h"
45#include "tree-dfa.h"
46#include "builtins.h"
3d2cf79f 47#include "dumpfile.h"
79d4f7c6 48#include "target.h"
d057c866 49#include "cgraph.h"
3d2cf79f 50#include "gimple-match.h"
53f3cd25 51#include "tree-pass.h"
3d2cf79f
RB
52
53
54/* Forward declarations of the private auto-generated matchers.
55 They expect valueized operands in canonical order and do not
56 perform simplification of all-constant operands. */
57static bool gimple_simplify (code_helper *, tree *,
58 gimple_seq *, tree (*)(tree),
59 code_helper, tree, tree);
60static bool gimple_simplify (code_helper *, tree *,
61 gimple_seq *, tree (*)(tree),
62 code_helper, tree, tree, tree);
63static bool gimple_simplify (code_helper *, tree *,
64 gimple_seq *, tree (*)(tree),
65 code_helper, tree, tree, tree, tree);
66
67
68/* Return whether T is a constant that we'll dispatch to fold to
69 evaluate fully constant expressions. */
70
71static inline bool
72constant_for_folding (tree t)
73{
74 return (CONSTANT_CLASS_P (t)
75 /* The following is only interesting to string builtins. */
76 || (TREE_CODE (t) == ADDR_EXPR
77 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
78}
79
80
81/* Helper that matches and simplifies the toplevel result from
82 a gimple_simplify run (where we don't want to build
83 a stmt in case it's used in in-place folding). Replaces
84 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
85 result and returns whether any change was made. */
86
c0f62740 87bool
3d2cf79f
RB
88gimple_resimplify1 (gimple_seq *seq,
89 code_helper *res_code, tree type, tree *res_ops,
90 tree (*valueize)(tree))
91{
92 if (constant_for_folding (res_ops[0]))
93 {
94 tree tem = NULL_TREE;
95 if (res_code->is_tree_code ())
8006f46b 96 tem = const_unop (*res_code, type, res_ops[0]);
3d2cf79f
RB
97 else
98 {
99 tree decl = builtin_decl_implicit (*res_code);
100 if (decl)
101 {
102 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 1, false);
103 if (tem)
104 {
105 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
106 STRIP_NOPS (tem);
107 tem = fold_convert (type, tem);
108 }
109 }
110 }
111 if (tem != NULL_TREE
112 && CONSTANT_CLASS_P (tem))
113 {
114 res_ops[0] = tem;
115 res_ops[1] = NULL_TREE;
116 res_ops[2] = NULL_TREE;
117 *res_code = TREE_CODE (res_ops[0]);
118 return true;
119 }
120 }
121
122 code_helper res_code2;
123 tree res_ops2[3] = {};
124 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
125 *res_code, type, res_ops[0]))
126 {
127 *res_code = res_code2;
128 res_ops[0] = res_ops2[0];
129 res_ops[1] = res_ops2[1];
130 res_ops[2] = res_ops2[2];
131 return true;
132 }
133
134 return false;
135}
136
137/* Helper that matches and simplifies the toplevel result from
138 a gimple_simplify run (where we don't want to build
139 a stmt in case it's used in in-place folding). Replaces
140 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
141 result and returns whether any change was made. */
142
c0f62740 143bool
3d2cf79f
RB
144gimple_resimplify2 (gimple_seq *seq,
145 code_helper *res_code, tree type, tree *res_ops,
146 tree (*valueize)(tree))
147{
148 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1]))
149 {
150 tree tem = NULL_TREE;
151 if (res_code->is_tree_code ())
8006f46b 152 tem = const_binop (*res_code, type, res_ops[0], res_ops[1]);
3d2cf79f
RB
153 else
154 {
155 tree decl = builtin_decl_implicit (*res_code);
156 if (decl)
157 {
158 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 2, false);
159 if (tem)
160 {
161 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
162 STRIP_NOPS (tem);
163 tem = fold_convert (type, tem);
164 }
165 }
166 }
167 if (tem != NULL_TREE
168 && CONSTANT_CLASS_P (tem))
169 {
170 res_ops[0] = tem;
171 res_ops[1] = NULL_TREE;
172 res_ops[2] = NULL_TREE;
173 *res_code = TREE_CODE (res_ops[0]);
174 return true;
175 }
176 }
177
178 /* Canonicalize operand order. */
179 bool canonicalized = false;
180 if (res_code->is_tree_code ()
181 && (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison
182 || commutative_tree_code (*res_code))
183 && tree_swap_operands_p (res_ops[0], res_ops[1], false))
184 {
6b4db501 185 std::swap (res_ops[0], res_ops[1]);
3d2cf79f
RB
186 if (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison)
187 *res_code = swap_tree_comparison (*res_code);
188 canonicalized = true;
189 }
190
191 code_helper res_code2;
192 tree res_ops2[3] = {};
193 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
194 *res_code, type, res_ops[0], res_ops[1]))
195 {
196 *res_code = res_code2;
197 res_ops[0] = res_ops2[0];
198 res_ops[1] = res_ops2[1];
199 res_ops[2] = res_ops2[2];
200 return true;
201 }
202
203 return canonicalized;
204}
205
206/* Helper that matches and simplifies the toplevel result from
207 a gimple_simplify run (where we don't want to build
208 a stmt in case it's used in in-place folding). Replaces
209 *RES_CODE and *RES_OPS with a simplified and/or canonicalized
210 result and returns whether any change was made. */
211
c0f62740 212bool
3d2cf79f
RB
213gimple_resimplify3 (gimple_seq *seq,
214 code_helper *res_code, tree type, tree *res_ops,
215 tree (*valueize)(tree))
216{
217 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1])
218 && constant_for_folding (res_ops[2]))
219 {
220 tree tem = NULL_TREE;
221 if (res_code->is_tree_code ())
222 tem = fold_ternary/*_to_constant*/ (*res_code, type, res_ops[0],
223 res_ops[1], res_ops[2]);
224 else
225 {
226 tree decl = builtin_decl_implicit (*res_code);
227 if (decl)
228 {
229 tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 3, false);
230 if (tem)
231 {
232 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
233 STRIP_NOPS (tem);
234 tem = fold_convert (type, tem);
235 }
236 }
237 }
238 if (tem != NULL_TREE
239 && CONSTANT_CLASS_P (tem))
240 {
241 res_ops[0] = tem;
242 res_ops[1] = NULL_TREE;
243 res_ops[2] = NULL_TREE;
244 *res_code = TREE_CODE (res_ops[0]);
245 return true;
246 }
247 }
248
249 /* Canonicalize operand order. */
250 bool canonicalized = false;
251 if (res_code->is_tree_code ()
252 && commutative_ternary_tree_code (*res_code)
253 && tree_swap_operands_p (res_ops[0], res_ops[1], false))
254 {
6b4db501 255 std::swap (res_ops[0], res_ops[1]);
3d2cf79f
RB
256 canonicalized = true;
257 }
258
259 code_helper res_code2;
260 tree res_ops2[3] = {};
261 if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
262 *res_code, type,
263 res_ops[0], res_ops[1], res_ops[2]))
264 {
265 *res_code = res_code2;
266 res_ops[0] = res_ops2[0];
267 res_ops[1] = res_ops2[1];
268 res_ops[2] = res_ops2[2];
269 return true;
270 }
271
272 return canonicalized;
273}
274
275
276/* If in GIMPLE expressions with CODE go as single-rhs build
277 a GENERIC tree for that expression into *OP0. */
278
279void
280maybe_build_generic_op (enum tree_code code, tree type,
281 tree *op0, tree op1, tree op2)
282{
283 switch (code)
284 {
285 case REALPART_EXPR:
286 case IMAGPART_EXPR:
287 case VIEW_CONVERT_EXPR:
288 *op0 = build1 (code, type, *op0);
289 break;
290 case BIT_FIELD_REF:
291 *op0 = build3 (code, type, *op0, op1, op2);
292 break;
293 default:;
294 }
295}
296
34050b6b
RB
297tree (*mprts_hook) (code_helper, tree, tree *);
298
3d2cf79f
RB
299/* Push the exploded expression described by RCODE, TYPE and OPS
300 as a statement to SEQ if necessary and return a gimple value
301 denoting the value of the expression. If RES is not NULL
302 then the result will be always RES and even gimple values are
303 pushed to SEQ. */
304
305tree
306maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
307 gimple_seq *seq, tree res)
308{
309 if (rcode.is_tree_code ())
310 {
311 if (!res
c0f62740 312 && gimple_simplified_result_is_gimple_val (rcode, ops))
3d2cf79f 313 return ops[0];
34050b6b
RB
314 if (mprts_hook)
315 {
316 tree tem = mprts_hook (rcode, type, ops);
317 if (tem)
318 return tem;
319 }
3d2cf79f
RB
320 if (!seq)
321 return NULL_TREE;
322 /* Play safe and do not allow abnormals to be mentioned in
323 newly created statements. */
324 if ((TREE_CODE (ops[0]) == SSA_NAME
325 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
326 || (ops[1]
327 && TREE_CODE (ops[1]) == SSA_NAME
328 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
329 || (ops[2]
330 && TREE_CODE (ops[2]) == SSA_NAME
331 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
332 return NULL_TREE;
333 if (!res)
4aecfe19
RS
334 {
335 if (gimple_in_ssa_p (cfun))
336 res = make_ssa_name (type);
337 else
338 res = create_tmp_reg (type);
339 }
3d2cf79f 340 maybe_build_generic_op (rcode, type, &ops[0], ops[1], ops[2]);
355fe088 341 gimple *new_stmt = gimple_build_assign (res, rcode,
0d0e4a03 342 ops[0], ops[1], ops[2]);
3d2cf79f
RB
343 gimple_seq_add_stmt_without_update (seq, new_stmt);
344 return res;
345 }
346 else
347 {
348 if (!seq)
349 return NULL_TREE;
350 tree decl = builtin_decl_implicit (rcode);
351 if (!decl)
352 return NULL_TREE;
4d20d00a
RB
353 /* We can't and should not emit calls to non-const functions. */
354 if (!(flags_from_decl_or_type (decl) & ECF_CONST))
355 return NULL_TREE;
3d2cf79f
RB
356 /* Play safe and do not allow abnormals to be mentioned in
357 newly created statements. */
37d486ab
RB
358 unsigned nargs;
359 for (nargs = 0; nargs < 3; ++nargs)
360 {
361 if (!ops[nargs])
362 break;
363 if (TREE_CODE (ops[nargs]) == SSA_NAME
364 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[nargs]))
365 return NULL_TREE;
366 }
367 gcc_assert (nargs != 0);
3d2cf79f 368 if (!res)
4aecfe19
RS
369 {
370 if (gimple_in_ssa_p (cfun))
371 res = make_ssa_name (type);
372 else
373 res = create_tmp_reg (type);
374 }
355fe088 375 gimple *new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]);
3d2cf79f
RB
376 gimple_call_set_lhs (new_stmt, res);
377 gimple_seq_add_stmt_without_update (seq, new_stmt);
378 return res;
379 }
380}
381
382
383/* Public API overloads follow for operation being tree_code or
384 built_in_function and for one to three operands or arguments.
385 They return NULL_TREE if nothing could be simplified or
386 the resulting simplified value with parts pushed to SEQ.
387 If SEQ is NULL then if the simplification needs to create
388 new stmts it will fail. If VALUEIZE is non-NULL then all
389 SSA names will be valueized using that hook prior to
390 applying simplifications. */
391
392/* Unary ops. */
393
394tree
395gimple_simplify (enum tree_code code, tree type,
396 tree op0,
397 gimple_seq *seq, tree (*valueize)(tree))
398{
399 if (constant_for_folding (op0))
400 {
8006f46b 401 tree res = const_unop (code, type, op0);
3d2cf79f
RB
402 if (res != NULL_TREE
403 && CONSTANT_CLASS_P (res))
404 return res;
405 }
406
407 code_helper rcode;
408 tree ops[3] = {};
409 if (!gimple_simplify (&rcode, ops, seq, valueize,
410 code, type, op0))
411 return NULL_TREE;
412 return maybe_push_res_to_seq (rcode, type, ops, seq);
413}
414
415/* Binary ops. */
416
417tree
418gimple_simplify (enum tree_code code, tree type,
419 tree op0, tree op1,
420 gimple_seq *seq, tree (*valueize)(tree))
421{
422 if (constant_for_folding (op0) && constant_for_folding (op1))
423 {
8006f46b 424 tree res = const_binop (code, type, op0, op1);
3d2cf79f
RB
425 if (res != NULL_TREE
426 && CONSTANT_CLASS_P (res))
427 return res;
428 }
429
430 /* Canonicalize operand order both for matching and fallback stmt
431 generation. */
432 if ((commutative_tree_code (code)
433 || TREE_CODE_CLASS (code) == tcc_comparison)
434 && tree_swap_operands_p (op0, op1, false))
435 {
6b4db501 436 std::swap (op0, op1);
3d2cf79f
RB
437 if (TREE_CODE_CLASS (code) == tcc_comparison)
438 code = swap_tree_comparison (code);
439 }
440
441 code_helper rcode;
442 tree ops[3] = {};
443 if (!gimple_simplify (&rcode, ops, seq, valueize,
444 code, type, op0, op1))
445 return NULL_TREE;
446 return maybe_push_res_to_seq (rcode, type, ops, seq);
447}
448
449/* Ternary ops. */
450
451tree
452gimple_simplify (enum tree_code code, tree type,
453 tree op0, tree op1, tree op2,
454 gimple_seq *seq, tree (*valueize)(tree))
455{
456 if (constant_for_folding (op0) && constant_for_folding (op1)
457 && constant_for_folding (op2))
458 {
459 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
460 if (res != NULL_TREE
461 && CONSTANT_CLASS_P (res))
462 return res;
463 }
464
465 /* Canonicalize operand order both for matching and fallback stmt
466 generation. */
467 if (commutative_ternary_tree_code (code)
468 && tree_swap_operands_p (op0, op1, false))
6b4db501 469 std::swap (op0, op1);
3d2cf79f
RB
470
471 code_helper rcode;
472 tree ops[3] = {};
473 if (!gimple_simplify (&rcode, ops, seq, valueize,
474 code, type, op0, op1, op2))
475 return NULL_TREE;
476 return maybe_push_res_to_seq (rcode, type, ops, seq);
477}
478
479/* Builtin function with one argument. */
480
481tree
482gimple_simplify (enum built_in_function fn, tree type,
483 tree arg0,
484 gimple_seq *seq, tree (*valueize)(tree))
485{
486 if (constant_for_folding (arg0))
487 {
488 tree decl = builtin_decl_implicit (fn);
489 if (decl)
490 {
491 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, &arg0, 1, false);
492 if (res)
493 {
494 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
495 STRIP_NOPS (res);
496 res = fold_convert (type, res);
497 if (CONSTANT_CLASS_P (res))
498 return res;
499 }
500 }
501 }
502
503 code_helper rcode;
504 tree ops[3] = {};
505 if (!gimple_simplify (&rcode, ops, seq, valueize,
506 fn, type, arg0))
507 return NULL_TREE;
508 return maybe_push_res_to_seq (rcode, type, ops, seq);
509}
510
511/* Builtin function with two arguments. */
512
513tree
514gimple_simplify (enum built_in_function fn, tree type,
515 tree arg0, tree arg1,
516 gimple_seq *seq, tree (*valueize)(tree))
517{
518 if (constant_for_folding (arg0)
519 && constant_for_folding (arg1))
520 {
521 tree decl = builtin_decl_implicit (fn);
522 if (decl)
523 {
524 tree args[2];
525 args[0] = arg0;
526 args[1] = arg1;
527 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, args, 2, false);
528 if (res)
529 {
530 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
531 STRIP_NOPS (res);
532 res = fold_convert (type, res);
533 if (CONSTANT_CLASS_P (res))
534 return res;
535 }
536 }
537 }
538
539 code_helper rcode;
540 tree ops[3] = {};
541 if (!gimple_simplify (&rcode, ops, seq, valueize,
542 fn, type, arg0, arg1))
543 return NULL_TREE;
544 return maybe_push_res_to_seq (rcode, type, ops, seq);
545}
546
547/* Builtin function with three arguments. */
548
549tree
550gimple_simplify (enum built_in_function fn, tree type,
551 tree arg0, tree arg1, tree arg2,
552 gimple_seq *seq, tree (*valueize)(tree))
553{
554 if (constant_for_folding (arg0)
555 && constant_for_folding (arg1)
556 && constant_for_folding (arg2))
557 {
558 tree decl = builtin_decl_implicit (fn);
559 if (decl)
560 {
561 tree args[3];
562 args[0] = arg0;
563 args[1] = arg1;
564 args[2] = arg2;
565 tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, args, 3, false);
566 if (res)
567 {
568 /* fold_builtin_n wraps the result inside a NOP_EXPR. */
569 STRIP_NOPS (res);
570 res = fold_convert (type, res);
571 if (CONSTANT_CLASS_P (res))
572 return res;
573 }
574 }
575 }
576
577 code_helper rcode;
578 tree ops[3] = {};
579 if (!gimple_simplify (&rcode, ops, seq, valueize,
580 fn, type, arg0, arg1, arg2))
581 return NULL_TREE;
582 return maybe_push_res_to_seq (rcode, type, ops, seq);
583}
584
37d486ab
RB
585/* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
586 VALUEIZED to true if valueization changed OP. */
587
588static inline tree
589do_valueize (tree op, tree (*valueize)(tree), bool &valueized)
590{
591 if (valueize && TREE_CODE (op) == SSA_NAME)
592 {
593 tree tem = valueize (op);
594 if (tem && tem != op)
595 {
596 op = tem;
597 valueized = true;
598 }
599 }
600 return op;
601}
3d2cf79f
RB
602
603/* The main STMT based simplification entry. It is used by the fold_stmt
604 and the fold_stmt_to_constant APIs. */
605
606bool
355fe088 607gimple_simplify (gimple *stmt,
3d2cf79f 608 code_helper *rcode, tree *ops,
0ff093d8
RB
609 gimple_seq *seq,
610 tree (*valueize)(tree), tree (*top_valueize)(tree))
3d2cf79f
RB
611{
612 switch (gimple_code (stmt))
613 {
614 case GIMPLE_ASSIGN:
615 {
616 enum tree_code code = gimple_assign_rhs_code (stmt);
617 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
618 switch (gimple_assign_rhs_class (stmt))
619 {
620 case GIMPLE_SINGLE_RHS:
621 if (code == REALPART_EXPR
622 || code == IMAGPART_EXPR
623 || code == VIEW_CONVERT_EXPR)
624 {
625 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
37d486ab
RB
626 bool valueized = false;
627 op0 = do_valueize (op0, top_valueize, valueized);
3d2cf79f
RB
628 *rcode = code;
629 ops[0] = op0;
37d486ab
RB
630 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
631 || valueized);
3d2cf79f
RB
632 }
633 else if (code == BIT_FIELD_REF)
634 {
635 tree rhs1 = gimple_assign_rhs1 (stmt);
636 tree op0 = TREE_OPERAND (rhs1, 0);
37d486ab
RB
637 bool valueized = false;
638 op0 = do_valueize (op0, top_valueize, valueized);
3d2cf79f
RB
639 *rcode = code;
640 ops[0] = op0;
641 ops[1] = TREE_OPERAND (rhs1, 1);
642 ops[2] = TREE_OPERAND (rhs1, 2);
37d486ab
RB
643 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
644 || valueized);
3d2cf79f
RB
645 }
646 else if (code == SSA_NAME
0ff093d8 647 && top_valueize)
3d2cf79f
RB
648 {
649 tree op0 = gimple_assign_rhs1 (stmt);
0ff093d8 650 tree valueized = top_valueize (op0);
3d2cf79f
RB
651 if (!valueized || op0 == valueized)
652 return false;
653 ops[0] = valueized;
654 *rcode = TREE_CODE (op0);
655 return true;
656 }
657 break;
658 case GIMPLE_UNARY_RHS:
659 {
660 tree rhs1 = gimple_assign_rhs1 (stmt);
37d486ab
RB
661 bool valueized = false;
662 rhs1 = do_valueize (rhs1, top_valueize, valueized);
3d2cf79f
RB
663 *rcode = code;
664 ops[0] = rhs1;
37d486ab
RB
665 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
666 || valueized);
3d2cf79f
RB
667 }
668 case GIMPLE_BINARY_RHS:
669 {
670 tree rhs1 = gimple_assign_rhs1 (stmt);
3d2cf79f 671 tree rhs2 = gimple_assign_rhs2 (stmt);
37d486ab
RB
672 bool valueized = false;
673 rhs1 = do_valueize (rhs1, top_valueize, valueized);
674 rhs2 = do_valueize (rhs2, top_valueize, valueized);
3d2cf79f
RB
675 *rcode = code;
676 ops[0] = rhs1;
677 ops[1] = rhs2;
37d486ab
RB
678 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
679 || valueized);
3d2cf79f
RB
680 }
681 case GIMPLE_TERNARY_RHS:
682 {
a0c012fd 683 bool valueized = false;
3d2cf79f 684 tree rhs1 = gimple_assign_rhs1 (stmt);
a0c012fd
RB
685 /* If this is a [VEC_]COND_EXPR first try to simplify an
686 embedded GENERIC condition. */
687 if (code == COND_EXPR
688 || code == VEC_COND_EXPR)
689 {
690 if (COMPARISON_CLASS_P (rhs1))
691 {
692 tree lhs = TREE_OPERAND (rhs1, 0);
693 tree rhs = TREE_OPERAND (rhs1, 1);
694 lhs = do_valueize (lhs, top_valueize, valueized);
695 rhs = do_valueize (rhs, top_valueize, valueized);
696 code_helper rcode2 = TREE_CODE (rhs1);
697 tree ops2[3] = {};
698 ops2[0] = lhs;
699 ops2[1] = rhs;
700 if ((gimple_resimplify2 (seq, &rcode2, TREE_TYPE (rhs1),
701 ops2, valueize)
702 || valueized)
703 && rcode2.is_tree_code ())
704 {
705 valueized = true;
706 if (TREE_CODE_CLASS ((enum tree_code)rcode2)
707 == tcc_comparison)
708 rhs1 = build2 (rcode2, TREE_TYPE (rhs1),
709 ops2[0], ops2[1]);
710 else if (rcode2 == SSA_NAME
fe4ed7b1
RB
711 || rcode2 == INTEGER_CST
712 || rcode2 == VECTOR_CST)
a0c012fd
RB
713 rhs1 = ops2[0];
714 else
715 valueized = false;
716 }
717 }
718 }
3d2cf79f 719 tree rhs2 = gimple_assign_rhs2 (stmt);
3d2cf79f 720 tree rhs3 = gimple_assign_rhs3 (stmt);
37d486ab
RB
721 rhs1 = do_valueize (rhs1, top_valueize, valueized);
722 rhs2 = do_valueize (rhs2, top_valueize, valueized);
723 rhs3 = do_valueize (rhs3, top_valueize, valueized);
3d2cf79f
RB
724 *rcode = code;
725 ops[0] = rhs1;
726 ops[1] = rhs2;
727 ops[2] = rhs3;
37d486ab
RB
728 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
729 || valueized);
3d2cf79f
RB
730 }
731 default:
732 gcc_unreachable ();
733 }
734 break;
735 }
736
737 case GIMPLE_CALL:
738 /* ??? This way we can't simplify calls with side-effects. */
37d486ab
RB
739 if (gimple_call_lhs (stmt) != NULL_TREE
740 && gimple_call_num_args (stmt) >= 1
741 && gimple_call_num_args (stmt) <= 3)
3d2cf79f
RB
742 {
743 tree fn = gimple_call_fn (stmt);
744 /* ??? Internal function support missing. */
745 if (!fn)
746 return false;
37d486ab
RB
747 bool valueized = false;
748 fn = do_valueize (fn, top_valueize, valueized);
749 if (TREE_CODE (fn) != ADDR_EXPR
750 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL)
3d2cf79f
RB
751 return false;
752
753 tree decl = TREE_OPERAND (fn, 0);
37d486ab 754 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL
37d486ab
RB
755 || !gimple_builtin_call_types_compatible_p (stmt, decl))
756 return false;
757
3d2cf79f 758 tree type = TREE_TYPE (gimple_call_lhs (stmt));
37d486ab
RB
759 *rcode = DECL_FUNCTION_CODE (decl);
760 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i)
761 {
762 tree arg = gimple_call_arg (stmt, i);
763 ops[i] = do_valueize (arg, top_valueize, valueized);
764 }
3d2cf79f
RB
765 switch (gimple_call_num_args (stmt))
766 {
767 case 1:
37d486ab
RB
768 return (gimple_resimplify1 (seq, rcode, type, ops, valueize)
769 || valueized);
3d2cf79f 770 case 2:
37d486ab
RB
771 return (gimple_resimplify2 (seq, rcode, type, ops, valueize)
772 || valueized);
3d2cf79f 773 case 3:
37d486ab
RB
774 return (gimple_resimplify3 (seq, rcode, type, ops, valueize)
775 || valueized);
3d2cf79f 776 default:
37d486ab 777 gcc_unreachable ();
3d2cf79f
RB
778 }
779 }
780 break;
781
782 case GIMPLE_COND:
783 {
784 tree lhs = gimple_cond_lhs (stmt);
3d2cf79f 785 tree rhs = gimple_cond_rhs (stmt);
37d486ab
RB
786 bool valueized = false;
787 lhs = do_valueize (lhs, top_valueize, valueized);
788 rhs = do_valueize (rhs, top_valueize, valueized);
3d2cf79f
RB
789 *rcode = gimple_cond_code (stmt);
790 ops[0] = lhs;
791 ops[1] = rhs;
37d486ab
RB
792 return (gimple_resimplify2 (seq, rcode,
793 boolean_type_node, ops, valueize)
794 || valueized);
3d2cf79f
RB
795 }
796
797 default:
798 break;
799 }
800
801 return false;
802}
803
804
805/* Helper for the autogenerated code, valueize OP. */
806
807inline tree
808do_valueize (tree (*valueize)(tree), tree op)
809{
810 if (valueize && TREE_CODE (op) == SSA_NAME)
811 return valueize (op);
812 return op;
813}
814
48451e8f 815/* Routine to determine if the types T1 and T2 are effectively
aea417d7
MG
816 the same for GIMPLE. If T1 or T2 is not a type, the test
817 applies to their TREE_TYPE. */
48451e8f
JL
818
819static inline bool
820types_match (tree t1, tree t2)
821{
aea417d7
MG
822 if (!TYPE_P (t1))
823 t1 = TREE_TYPE (t1);
824 if (!TYPE_P (t2))
825 t2 = TREE_TYPE (t2);
826
48451e8f
JL
827 return types_compatible_p (t1, t2);
828}
829
830/* Return if T has a single use. For GIMPLE, we also allow any
831 non-SSA_NAME (ie constants) and zero uses to cope with uses
832 that aren't linked up yet. */
833
834static inline bool
835single_use (tree t)
836{
837 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t);
838}
53f3cd25
RS
839
840/* Return true if math operations should be canonicalized,
841 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
842
843static inline bool
844canonicalize_math_p ()
845{
846 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
847}