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