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