annotate gcc/gimple-match-head.c @ 158:494b0b89df80 default tip

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