Branch data Line data Source code
1 : : /* Gimple simplify definitions.
2 : :
3 : : Copyright (C) 2011-2024 Free Software Foundation, Inc.
4 : : Contributed by Richard Guenther <rguenther@suse.de>
5 : :
6 : : This file is part of GCC.
7 : :
8 : : GCC is free software; you can redistribute it and/or modify it under
9 : : the terms of the GNU General Public License as published by the Free
10 : : Software Foundation; either version 3, or (at your option) any later
11 : : version.
12 : :
13 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 : : for more details.
17 : :
18 : : You should have received a copy of the GNU General Public License
19 : : along with GCC; see the file COPYING3. If not see
20 : : <http://www.gnu.org/licenses/>. */
21 : :
22 : : #ifndef GCC_GIMPLE_MATCH_H
23 : : #define GCC_GIMPLE_MATCH_H
24 : :
25 : :
26 : : /* Represents the condition under which an operation should happen,
27 : : and the value to use otherwise. The condition applies elementwise
28 : : (as for VEC_COND_EXPR) if the values are vectors. */
29 : : class gimple_match_cond
30 : : {
31 : : public:
32 : : enum uncond { UNCOND };
33 : :
34 : : /* Build an unconditional op. */
35 : 1179816085 : gimple_match_cond (uncond) : cond (NULL_TREE), else_value (NULL_TREE), len
36 : 1162843362 : (NULL_TREE), bias (NULL_TREE) {}
37 : : gimple_match_cond (tree, tree);
38 : : gimple_match_cond (tree, tree, tree, tree);
39 : :
40 : : gimple_match_cond any_else () const;
41 : :
42 : : /* The condition under which the operation occurs, or NULL_TREE
43 : : if the operation is unconditional. */
44 : : tree cond;
45 : :
46 : : /* The value to use when the condition is false. This is NULL_TREE if
47 : : the operation is unconditional or if the value doesn't matter. */
48 : : tree else_value;
49 : :
50 : : /* The length and bias parameters to be applied to a vector operation,
51 : : so that the condition is forced to false when the element index is
52 : : >= LEN + BIAS. These are NULL_TREE if the operation isn't applied
53 : : to vectors, or if no such length limit is in use. */
54 : : tree len;
55 : : tree bias;
56 : : };
57 : :
58 : : inline
59 : 9182303 : gimple_match_cond::gimple_match_cond (tree cond_in, tree else_value_in)
60 : 0 : : cond (cond_in), else_value (else_value_in), len (NULL_TREE),
61 : 0 : bias (NULL_TREE)
62 : : {
63 : : }
64 : :
65 : : inline
66 : 10349 : gimple_match_cond::gimple_match_cond (tree cond_in, tree else_value_in,
67 : : tree len_in, tree bias_in)
68 : : : cond (cond_in), else_value (else_value_in), len (len_in), bias (bias_in)
69 : : {}
70 : :
71 : : /* Return a gimple_match_cond with the same condition but with an
72 : : arbitrary ELSE_VALUE. */
73 : :
74 : : inline gimple_match_cond
75 : 9182303 : gimple_match_cond::any_else () const
76 : : {
77 : 9182303 : return gimple_match_cond (cond, NULL_TREE);
78 : : }
79 : :
80 : : /* Represents an operation to be simplified, or the result of the
81 : : simplification. */
82 : : class gimple_match_op
83 : : {
84 : : public:
85 : : gimple_match_op ();
86 : : gimple_match_op (const gimple_match_cond &, code_helper, tree, unsigned int);
87 : : gimple_match_op (const gimple_match_cond &,
88 : : code_helper, tree, tree);
89 : : gimple_match_op (const gimple_match_cond &,
90 : : code_helper, tree, tree, tree);
91 : : gimple_match_op (const gimple_match_cond &,
92 : : code_helper, tree, tree, tree, tree);
93 : : gimple_match_op (const gimple_match_cond &,
94 : : code_helper, tree, tree, tree, tree, tree);
95 : : gimple_match_op (const gimple_match_cond &,
96 : : code_helper, tree, tree, tree, tree, tree, tree);
97 : : gimple_match_op (const gimple_match_cond &,
98 : : code_helper, tree, tree, tree, tree, tree, tree, tree);
99 : : gimple_match_op (const gimple_match_cond &,
100 : : code_helper, tree, tree, tree, tree, tree, tree, tree, tree);
101 : :
102 : : void set_op (code_helper, tree, unsigned int);
103 : : void set_op (code_helper, tree, tree);
104 : : void set_op (code_helper, tree, tree, tree);
105 : : void set_op (code_helper, tree, tree, tree, tree);
106 : : void set_op (code_helper, tree, tree, tree, tree, bool);
107 : : void set_op (code_helper, tree, tree, tree, tree, tree);
108 : : void set_op (code_helper, tree, tree, tree, tree, tree, tree);
109 : : void set_op (code_helper, tree, tree, tree, tree, tree, tree, tree);
110 : : void set_op (code_helper, tree, tree, tree, tree, tree, tree, tree, tree);
111 : : void set_value (tree);
112 : :
113 : : tree op_or_null (unsigned int) const;
114 : :
115 : : bool resimplify (gimple_seq *, tree (*)(tree));
116 : :
117 : : /* The maximum value of NUM_OPS. */
118 : : static const unsigned int MAX_NUM_OPS = 7;
119 : :
120 : : /* The conditions under which the operation is performed, and the value to
121 : : use as a fallback. */
122 : : gimple_match_cond cond;
123 : :
124 : : /* The operation being performed. */
125 : : code_helper code;
126 : :
127 : : /* The type of the result. */
128 : : tree type;
129 : :
130 : : /* For a BIT_FIELD_REF, whether the group of bits is stored in reverse order
131 : : from the target order. */
132 : : bool reverse;
133 : :
134 : : /* The number of operands to CODE. */
135 : : unsigned int num_ops;
136 : :
137 : : /* The operands to CODE. Only the first NUM_OPS entries are meaningful. */
138 : : tree ops[MAX_NUM_OPS];
139 : : };
140 : :
141 : : inline
142 : 1162843362 : gimple_match_op::gimple_match_op ()
143 : 1162843362 : : cond (gimple_match_cond::UNCOND), type (NULL_TREE), reverse (false),
144 : 1162722630 : num_ops (0)
145 : : {
146 : 120732 : }
147 : :
148 : : /* Constructor that takes the condition, code, type and number of
149 : : operands, but leaves the caller to fill in the operands. */
150 : :
151 : : inline
152 : 5981647 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
153 : : code_helper code_in, tree type_in,
154 : 5981647 : unsigned int num_ops_in)
155 : 5981647 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
156 : 5981647 : num_ops (num_ops_in)
157 : : {
158 : : }
159 : :
160 : : /* Constructors for various numbers of operands. */
161 : :
162 : : inline
163 : 12498260 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
164 : : code_helper code_in, tree type_in,
165 : 12498260 : tree op0)
166 : 12498260 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
167 : 12498260 : num_ops (1)
168 : : {
169 : 12498260 : ops[0] = op0;
170 : 0 : }
171 : :
172 : : inline
173 : 6763303 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
174 : : code_helper code_in, tree type_in,
175 : 6763303 : tree op0, tree op1)
176 : 6763303 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
177 : 6763303 : num_ops (2)
178 : : {
179 : 6763303 : ops[0] = op0;
180 : 6763303 : ops[1] = op1;
181 : : }
182 : :
183 : : inline
184 : 920981 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
185 : : code_helper code_in, tree type_in,
186 : 920981 : tree op0, tree op1, tree op2)
187 : 920981 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
188 : 920981 : num_ops (3)
189 : : {
190 : 920981 : ops[0] = op0;
191 : 920981 : ops[1] = op1;
192 : 920981 : ops[2] = op2;
193 : : }
194 : :
195 : : inline
196 : 800 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
197 : : code_helper code_in, tree type_in,
198 : 800 : tree op0, tree op1, tree op2, tree op3)
199 : 800 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
200 : 800 : num_ops (4)
201 : : {
202 : 800 : ops[0] = op0;
203 : 800 : ops[1] = op1;
204 : 800 : ops[2] = op2;
205 : 800 : ops[3] = op3;
206 : : }
207 : :
208 : : inline
209 : 384 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
210 : : code_helper code_in, tree type_in,
211 : : tree op0, tree op1, tree op2, tree op3,
212 : 384 : tree op4)
213 : 384 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
214 : 384 : num_ops (5)
215 : : {
216 : 384 : ops[0] = op0;
217 : 384 : ops[1] = op1;
218 : 384 : ops[2] = op2;
219 : 384 : ops[3] = op3;
220 : 384 : ops[4] = op4;
221 : : }
222 : :
223 : : inline
224 : 0 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
225 : : code_helper code_in, tree type_in,
226 : : tree op0, tree op1, tree op2, tree op3,
227 : 0 : tree op4, tree op5)
228 : 0 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
229 : 0 : num_ops (6)
230 : : {
231 : 0 : ops[0] = op0;
232 : 0 : ops[1] = op1;
233 : 0 : ops[2] = op2;
234 : 0 : ops[3] = op3;
235 : 0 : ops[4] = op4;
236 : 0 : ops[5] = op5;
237 : : }
238 : :
239 : : inline
240 : 0 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
241 : : code_helper code_in, tree type_in,
242 : : tree op0, tree op1, tree op2, tree op3,
243 : 0 : tree op4, tree op5, tree op6)
244 : 0 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
245 : 0 : num_ops (7)
246 : : {
247 : 0 : ops[0] = op0;
248 : 0 : ops[1] = op1;
249 : 0 : ops[2] = op2;
250 : 0 : ops[3] = op3;
251 : 0 : ops[4] = op4;
252 : 0 : ops[5] = op5;
253 : 0 : ops[6] = op6;
254 : : }
255 : :
256 : : /* Change the operation performed to CODE_IN, the type of the result to
257 : : TYPE_IN, and the number of operands to NUM_OPS_IN. The caller needs
258 : : to set the operands itself. */
259 : :
260 : : inline void
261 : 26239726 : gimple_match_op::set_op (code_helper code_in, tree type_in,
262 : : unsigned int num_ops_in)
263 : : {
264 : 26239726 : code = code_in;
265 : 26239726 : type = type_in;
266 : 26239726 : num_ops = num_ops_in;
267 : 0 : }
268 : :
269 : : /* Functions for changing the operation performed, for various numbers
270 : : of operands. */
271 : :
272 : : inline void
273 : 182074953 : gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0)
274 : : {
275 : 182074953 : code = code_in;
276 : 182074953 : type = type_in;
277 : 182074953 : num_ops = 1;
278 : 153066984 : ops[0] = op0;
279 : : }
280 : :
281 : : inline void
282 : 424417313 : gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0, tree op1)
283 : : {
284 : 424417313 : code = code_in;
285 : 424417313 : type = type_in;
286 : 424417313 : num_ops = 2;
287 : 424417313 : ops[0] = op0;
288 : 424417313 : ops[1] = op1;
289 : : }
290 : :
291 : : inline void
292 : 976536 : gimple_match_op::set_op (code_helper code_in, tree type_in,
293 : : tree op0, tree op1, tree op2)
294 : : {
295 : 976536 : code = code_in;
296 : 976536 : type = type_in;
297 : 976536 : num_ops = 3;
298 : 976536 : ops[0] = op0;
299 : 976536 : ops[1] = op1;
300 : 976536 : ops[2] = op2;
301 : : }
302 : :
303 : : inline void
304 : 1452008 : gimple_match_op::set_op (code_helper code_in, tree type_in,
305 : : tree op0, tree op1, tree op2, bool reverse_in)
306 : : {
307 : 1452008 : code = code_in;
308 : 1452008 : type = type_in;
309 : 1452008 : reverse = reverse_in;
310 : 1452008 : num_ops = 3;
311 : 1452008 : ops[0] = op0;
312 : 1452008 : ops[1] = op1;
313 : 1452008 : ops[2] = op2;
314 : : }
315 : :
316 : : inline void
317 : : gimple_match_op::set_op (code_helper code_in, tree type_in,
318 : : tree op0, tree op1, tree op2, tree op3)
319 : : {
320 : : code = code_in;
321 : : type = type_in;
322 : : num_ops = 4;
323 : : ops[0] = op0;
324 : : ops[1] = op1;
325 : : ops[2] = op2;
326 : : ops[3] = op3;
327 : : }
328 : :
329 : : inline void
330 : 0 : gimple_match_op::set_op (code_helper code_in, tree type_in,
331 : : tree op0, tree op1, tree op2, tree op3, tree op4)
332 : : {
333 : 0 : code = code_in;
334 : 0 : type = type_in;
335 : 0 : num_ops = 5;
336 : 0 : ops[0] = op0;
337 : 0 : ops[1] = op1;
338 : 0 : ops[2] = op2;
339 : 0 : ops[3] = op3;
340 : 0 : ops[4] = op4;
341 : : }
342 : :
343 : : inline void
344 : : gimple_match_op::set_op (code_helper code_in, tree type_in,
345 : : tree op0, tree op1, tree op2, tree op3, tree op4,
346 : : tree op5)
347 : : {
348 : : code = code_in;
349 : : type = type_in;
350 : : num_ops = 6;
351 : : ops[0] = op0;
352 : : ops[1] = op1;
353 : : ops[2] = op2;
354 : : ops[3] = op3;
355 : : ops[4] = op4;
356 : : ops[5] = op5;
357 : : }
358 : :
359 : : inline void
360 : : gimple_match_op::set_op (code_helper code_in, tree type_in,
361 : : tree op0, tree op1, tree op2, tree op3, tree op4,
362 : : tree op5, tree op6)
363 : : {
364 : : code = code_in;
365 : : type = type_in;
366 : : num_ops = 7;
367 : : ops[0] = op0;
368 : : ops[1] = op1;
369 : : ops[2] = op2;
370 : : ops[3] = op3;
371 : : ops[4] = op4;
372 : : ops[5] = op5;
373 : : ops[6] = op6;
374 : : }
375 : :
376 : : /* Set the "operation" to be the single value VALUE, such as a constant
377 : : or SSA_NAME. */
378 : :
379 : : inline void
380 : 59092359 : gimple_match_op::set_value (tree value)
381 : : {
382 : 59092359 : set_op (TREE_CODE (value), TREE_TYPE (value), value);
383 : 59092359 : }
384 : :
385 : : /* Return the value of operand I, or null if there aren't that many
386 : : operands. */
387 : :
388 : : inline tree
389 : 7691827 : gimple_match_op::op_or_null (unsigned int i) const
390 : : {
391 : 2551085 : return i < num_ops ? ops[i] : NULL_TREE;
392 : : }
393 : :
394 : : /* Return whether OP is a non-expression result and a gimple value. */
395 : :
396 : : inline bool
397 : 66326088 : gimple_simplified_result_is_gimple_val (const gimple_match_op *op)
398 : : {
399 : 66326088 : return (op->code.is_tree_code ()
400 : 65799284 : && (TREE_CODE_LENGTH ((tree_code) op->code) == 0
401 : 26449892 : || ((tree_code) op->code) == ADDR_EXPR)
402 : 106617010 : && is_gimple_val (op->ops[0]));
403 : : }
404 : :
405 : : extern tree (*mprts_hook) (gimple_match_op *);
406 : :
407 : : bool gimple_extract_op (gimple *, gimple_match_op *);
408 : : bool gimple_simplify (gimple *, gimple_match_op *, gimple_seq *,
409 : : tree (*)(tree), tree (*)(tree));
410 : : tree maybe_push_res_to_seq (gimple_match_op *, gimple_seq *,
411 : : tree res = NULL_TREE);
412 : : void maybe_build_generic_op (gimple_match_op *);
413 : :
414 : : bool commutative_binary_op_p (code_helper, tree);
415 : : bool commutative_ternary_op_p (code_helper, tree);
416 : : int first_commutative_argument (code_helper, tree);
417 : : bool associative_binary_op_p (code_helper, tree);
418 : : code_helper canonicalize_code (code_helper, tree);
419 : :
420 : : #ifdef GCC_OPTABS_TREE_H
421 : : bool directly_supported_p (code_helper, tree, optab_subtype = optab_default);
422 : : #endif
423 : :
424 : : internal_fn get_conditional_internal_fn (code_helper, tree);
425 : :
426 : : #endif /* GCC_GIMPLE_MATCH_H */
|