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 : 1233222010 : gimple_match_cond (uncond) : cond (NULL_TREE), else_value (NULL_TREE), len
36 : 1214941371 : (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 : 9908198 : gimple_match_cond::gimple_match_cond (tree cond_in, tree else_value_in)
60 : : : cond (cond_in), else_value (else_value_in), len (NULL_TREE),
61 : : bias (NULL_TREE)
62 : : {
63 : : }
64 : :
65 : : inline
66 : 8924 : 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 : 9908198 : gimple_match_cond::any_else () const
76 : : {
77 : 9908198 : 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 : : bool operands_occurs_in_abnormal_phi() const;
141 : : };
142 : :
143 : : inline
144 : 1214941371 : gimple_match_op::gimple_match_op ()
145 : 1214941371 : : cond (gimple_match_cond::UNCOND), type (NULL_TREE), reverse (false),
146 : 1214941371 : num_ops (0)
147 : : {
148 : : }
149 : :
150 : : /* Constructor that takes the condition, code, type and number of
151 : : operands, but leaves the caller to fill in the operands. */
152 : :
153 : : inline
154 : 6197706 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
155 : : code_helper code_in, tree type_in,
156 : 6197706 : unsigned int num_ops_in)
157 : 6197706 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
158 : 6197706 : num_ops (num_ops_in)
159 : : {
160 : : }
161 : :
162 : : /* Constructors for various numbers of operands. */
163 : :
164 : : inline
165 : 13667245 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
166 : : code_helper code_in, tree type_in,
167 : 13667245 : tree op0)
168 : 13667245 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
169 : 13667245 : num_ops (1)
170 : : {
171 : 13667245 : ops[0] = op0;
172 : : }
173 : :
174 : : inline
175 : 7360243 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
176 : : code_helper code_in, tree type_in,
177 : 7360243 : tree op0, tree op1)
178 : 7360243 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
179 : 7360243 : num_ops (2)
180 : : {
181 : 7360243 : ops[0] = op0;
182 : 7360243 : ops[1] = op1;
183 : : }
184 : :
185 : : inline
186 : 970862 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
187 : : code_helper code_in, tree type_in,
188 : 970862 : tree op0, tree op1, tree op2)
189 : 970862 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
190 : 970862 : num_ops (3)
191 : : {
192 : 970862 : ops[0] = op0;
193 : 970862 : ops[1] = op1;
194 : 970862 : ops[2] = op2;
195 : : }
196 : :
197 : : inline
198 : 1189 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
199 : : code_helper code_in, tree type_in,
200 : 1189 : tree op0, tree op1, tree op2, tree op3)
201 : 1189 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
202 : 1189 : num_ops (4)
203 : : {
204 : 1189 : ops[0] = op0;
205 : 1189 : ops[1] = op1;
206 : 1189 : ops[2] = op2;
207 : 1189 : ops[3] = op3;
208 : : }
209 : :
210 : : inline
211 : 516 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
212 : : code_helper code_in, tree type_in,
213 : : tree op0, tree op1, tree op2, tree op3,
214 : 516 : tree op4)
215 : 516 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
216 : 516 : num_ops (5)
217 : : {
218 : 516 : ops[0] = op0;
219 : 516 : ops[1] = op1;
220 : 516 : ops[2] = op2;
221 : 516 : ops[3] = op3;
222 : 516 : ops[4] = op4;
223 : : }
224 : :
225 : : inline
226 : 0 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
227 : : code_helper code_in, tree type_in,
228 : : tree op0, tree op1, tree op2, tree op3,
229 : 0 : tree op4, tree op5)
230 : 0 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
231 : 0 : num_ops (6)
232 : : {
233 : 0 : ops[0] = op0;
234 : 0 : ops[1] = op1;
235 : 0 : ops[2] = op2;
236 : 0 : ops[3] = op3;
237 : 0 : ops[4] = op4;
238 : 0 : ops[5] = op5;
239 : : }
240 : :
241 : : inline
242 : 0 : gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
243 : : code_helper code_in, tree type_in,
244 : : tree op0, tree op1, tree op2, tree op3,
245 : 0 : tree op4, tree op5, tree op6)
246 : 0 : : cond (cond_in), code (code_in), type (type_in), reverse (false),
247 : 0 : num_ops (7)
248 : : {
249 : 0 : ops[0] = op0;
250 : 0 : ops[1] = op1;
251 : 0 : ops[2] = op2;
252 : 0 : ops[3] = op3;
253 : 0 : ops[4] = op4;
254 : 0 : ops[5] = op5;
255 : 0 : ops[6] = op6;
256 : : }
257 : :
258 : : /* Change the operation performed to CODE_IN, the type of the result to
259 : : TYPE_IN, and the number of operands to NUM_OPS_IN. The caller needs
260 : : to set the operands itself. */
261 : :
262 : : inline void
263 : 27468954 : gimple_match_op::set_op (code_helper code_in, tree type_in,
264 : : unsigned int num_ops_in)
265 : : {
266 : 27468954 : code = code_in;
267 : 27468954 : type = type_in;
268 : 27468954 : num_ops = num_ops_in;
269 : : }
270 : :
271 : : /* Functions for changing the operation performed, for various numbers
272 : : of operands. */
273 : :
274 : : inline void
275 : 187305101 : gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0)
276 : : {
277 : 187305101 : code = code_in;
278 : 187305101 : type = type_in;
279 : 187305101 : num_ops = 1;
280 : 156168957 : ops[0] = op0;
281 : : }
282 : :
283 : : inline void
284 : 449147650 : gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0, tree op1)
285 : : {
286 : 449147650 : code = code_in;
287 : 449147650 : type = type_in;
288 : 449147650 : num_ops = 2;
289 : 449147650 : ops[0] = op0;
290 : 449147650 : ops[1] = op1;
291 : : }
292 : :
293 : : inline void
294 : 1162440 : gimple_match_op::set_op (code_helper code_in, tree type_in,
295 : : tree op0, tree op1, tree op2)
296 : : {
297 : 1162440 : code = code_in;
298 : 1162440 : type = type_in;
299 : 1162440 : num_ops = 3;
300 : 1162440 : ops[0] = op0;
301 : 1162440 : ops[1] = op1;
302 : 1162440 : ops[2] = op2;
303 : : }
304 : :
305 : : inline void
306 : 866131 : gimple_match_op::set_op (code_helper code_in, tree type_in,
307 : : tree op0, tree op1, tree op2, bool reverse_in)
308 : : {
309 : 866131 : code = code_in;
310 : 866131 : type = type_in;
311 : 866131 : reverse = reverse_in;
312 : 866131 : num_ops = 3;
313 : 866131 : ops[0] = op0;
314 : 866131 : ops[1] = op1;
315 : 866131 : ops[2] = op2;
316 : : }
317 : :
318 : : inline void
319 : : gimple_match_op::set_op (code_helper code_in, tree type_in,
320 : : tree op0, tree op1, tree op2, tree op3)
321 : : {
322 : : code = code_in;
323 : : type = type_in;
324 : : num_ops = 4;
325 : : ops[0] = op0;
326 : : ops[1] = op1;
327 : : ops[2] = op2;
328 : : ops[3] = op3;
329 : : }
330 : :
331 : : inline void
332 : 0 : gimple_match_op::set_op (code_helper code_in, tree type_in,
333 : : tree op0, tree op1, tree op2, tree op3, tree op4)
334 : : {
335 : 0 : code = code_in;
336 : 0 : type = type_in;
337 : 0 : num_ops = 5;
338 : 0 : ops[0] = op0;
339 : 0 : ops[1] = op1;
340 : 0 : ops[2] = op2;
341 : 0 : ops[3] = op3;
342 : 0 : ops[4] = op4;
343 : : }
344 : :
345 : : inline void
346 : : gimple_match_op::set_op (code_helper code_in, tree type_in,
347 : : tree op0, tree op1, tree op2, tree op3, tree op4,
348 : : tree op5)
349 : : {
350 : : code = code_in;
351 : : type = type_in;
352 : : num_ops = 6;
353 : : ops[0] = op0;
354 : : ops[1] = op1;
355 : : ops[2] = op2;
356 : : ops[3] = op3;
357 : : ops[4] = op4;
358 : : ops[5] = op5;
359 : : }
360 : :
361 : : inline void
362 : : gimple_match_op::set_op (code_helper code_in, tree type_in,
363 : : tree op0, tree op1, tree op2, tree op3, tree op4,
364 : : tree op5, tree op6)
365 : : {
366 : : code = code_in;
367 : : type = type_in;
368 : : num_ops = 7;
369 : : ops[0] = op0;
370 : : ops[1] = op1;
371 : : ops[2] = op2;
372 : : ops[3] = op3;
373 : : ops[4] = op4;
374 : : ops[5] = op5;
375 : : ops[6] = op6;
376 : : }
377 : :
378 : : /* Set the "operation" to be the single value VALUE, such as a constant
379 : : or SSA_NAME. */
380 : :
381 : : inline void
382 : 62610951 : gimple_match_op::set_value (tree value)
383 : : {
384 : 62610951 : set_op (TREE_CODE (value), TREE_TYPE (value), value);
385 : 62610951 : }
386 : :
387 : : /* Return the value of operand I, or null if there aren't that many
388 : : operands. */
389 : :
390 : : inline tree
391 : 8144998 : gimple_match_op::op_or_null (unsigned int i) const
392 : : {
393 : 2700772 : return i < num_ops ? ops[i] : NULL_TREE;
394 : : }
395 : :
396 : : /* Return whether OP is a non-expression result and a gimple value. */
397 : :
398 : : inline bool
399 : 70637670 : gimple_simplified_result_is_gimple_val (const gimple_match_op *op)
400 : : {
401 : 70637670 : return (op->code.is_tree_code ()
402 : 70095367 : && (TREE_CODE_LENGTH ((tree_code) op->code) == 0
403 : 28177172 : || ((tree_code) op->code) == ADDR_EXPR)
404 : 113538295 : && is_gimple_val (op->ops[0]));
405 : : }
406 : :
407 : : extern tree (*mprts_hook) (gimple_match_op *);
408 : :
409 : : bool gimple_extract_op (gimple *, gimple_match_op *);
410 : : bool gimple_simplify (gimple *, gimple_match_op *, gimple_seq *,
411 : : tree (*)(tree), tree (*)(tree));
412 : : tree maybe_push_res_to_seq (gimple_match_op *, gimple_seq *,
413 : : tree res = NULL_TREE);
414 : : void maybe_build_generic_op (gimple_match_op *);
415 : :
416 : : bool commutative_binary_op_p (code_helper, tree);
417 : : bool commutative_ternary_op_p (code_helper, tree);
418 : : int first_commutative_argument (code_helper, tree);
419 : : bool associative_binary_op_p (code_helper, tree);
420 : : code_helper canonicalize_code (code_helper, tree);
421 : :
422 : : #ifdef GCC_OPTABS_TREE_H
423 : : bool directly_supported_p (code_helper, tree, optab_subtype = optab_default);
424 : : bool directly_supported_p (code_helper, tree, tree,
425 : : optab_subtype = optab_default);
426 : : #endif
427 : :
428 : : internal_fn get_conditional_internal_fn (code_helper, tree);
429 : :
430 : : #endif /* GCC_GIMPLE_MATCH_H */
|