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