Skip gcc.dg/guality/example.c on hppa-linux.
[official-gcc.git] / gcc / gimple-match.h
blobb7b6d2cea42f18ada654f4d3aac3fd1a94755b84
1 /* Gimple simplify definitions.
3 Copyright (C) 2011-2021 Free Software Foundation, Inc.
4 Contributed by Richard Guenther <rguenther@suse.de>
6 This file is part of GCC.
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.
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.
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/>. */
22 #ifndef GCC_GIMPLE_MATCH_H
23 #define GCC_GIMPLE_MATCH_H
26 /* Helper to transparently allow tree codes and builtin function codes
27 exist in one storage entity. */
28 class code_helper
30 public:
31 code_helper () {}
32 code_helper (tree_code code) : rep ((int) code) {}
33 code_helper (combined_fn fn) : rep (-(int) fn) {}
34 code_helper (internal_fn fn) : rep (-(int) as_combined_fn (fn)) {}
35 explicit operator tree_code () const { return (tree_code) rep; }
36 explicit operator combined_fn () const { return (combined_fn) -rep; }
37 explicit operator internal_fn () const;
38 explicit operator built_in_function () const;
39 bool is_tree_code () const { return rep > 0; }
40 bool is_fn_code () const { return rep < 0; }
41 bool is_internal_fn () const;
42 bool is_builtin_fn () const;
43 int get_rep () const { return rep; }
44 bool operator== (const code_helper &other) { return rep == other.rep; }
45 bool operator!= (const code_helper &other) { return rep != other.rep; }
46 bool operator== (tree_code c) { return rep == code_helper (c).rep; }
47 bool operator!= (tree_code c) { return rep != code_helper (c).rep; }
49 private:
50 int rep;
53 inline code_helper::operator internal_fn () const
55 return as_internal_fn (combined_fn (*this));
58 inline code_helper::operator built_in_function () const
60 return as_builtin_fn (combined_fn (*this));
63 inline bool
64 code_helper::is_internal_fn () const
66 return is_fn_code () && internal_fn_p (combined_fn (*this));
69 inline bool
70 code_helper::is_builtin_fn () const
72 return is_fn_code () && builtin_fn_p (combined_fn (*this));
75 /* Represents the condition under which an operation should happen,
76 and the value to use otherwise. The condition applies elementwise
77 (as for VEC_COND_EXPR) if the values are vectors. */
78 class gimple_match_cond
80 public:
81 enum uncond { UNCOND };
83 /* Build an unconditional op. */
84 gimple_match_cond (uncond) : cond (NULL_TREE), else_value (NULL_TREE) {}
85 gimple_match_cond (tree, tree);
87 gimple_match_cond any_else () const;
89 /* The condition under which the operation occurs, or NULL_TREE
90 if the operation is unconditional. */
91 tree cond;
93 /* The value to use when the condition is false. This is NULL_TREE if
94 the operation is unconditional or if the value doesn't matter. */
95 tree else_value;
98 inline
99 gimple_match_cond::gimple_match_cond (tree cond_in, tree else_value_in)
100 : cond (cond_in), else_value (else_value_in)
104 /* Return a gimple_match_cond with the same condition but with an
105 arbitrary ELSE_VALUE. */
107 inline gimple_match_cond
108 gimple_match_cond::any_else () const
110 return gimple_match_cond (cond, NULL_TREE);
113 /* Represents an operation to be simplified, or the result of the
114 simplification. */
115 class gimple_match_op
117 public:
118 gimple_match_op ();
119 gimple_match_op (const gimple_match_cond &, code_helper, tree, unsigned int);
120 gimple_match_op (const gimple_match_cond &,
121 code_helper, tree, tree);
122 gimple_match_op (const gimple_match_cond &,
123 code_helper, tree, tree, tree);
124 gimple_match_op (const gimple_match_cond &,
125 code_helper, tree, tree, tree, tree);
126 gimple_match_op (const gimple_match_cond &,
127 code_helper, tree, tree, tree, tree, tree);
128 gimple_match_op (const gimple_match_cond &,
129 code_helper, tree, tree, tree, tree, tree, tree);
131 void set_op (code_helper, tree, unsigned int);
132 void set_op (code_helper, tree, tree);
133 void set_op (code_helper, tree, tree, tree);
134 void set_op (code_helper, tree, tree, tree, tree);
135 void set_op (code_helper, tree, tree, tree, tree, bool);
136 void set_op (code_helper, tree, tree, tree, tree, tree);
137 void set_op (code_helper, tree, tree, tree, tree, tree, tree);
138 void set_value (tree);
140 tree op_or_null (unsigned int) const;
142 bool resimplify (gimple_seq *, tree (*)(tree));
144 /* The maximum value of NUM_OPS. */
145 static const unsigned int MAX_NUM_OPS = 5;
147 /* The conditions under which the operation is performed, and the value to
148 use as a fallback. */
149 gimple_match_cond cond;
151 /* The operation being performed. */
152 code_helper code;
154 /* The type of the result. */
155 tree type;
157 /* For a BIT_FIELD_REF, whether the group of bits is stored in reverse order
158 from the target order. */
159 bool reverse;
161 /* The number of operands to CODE. */
162 unsigned int num_ops;
164 /* The operands to CODE. Only the first NUM_OPS entries are meaningful. */
165 tree ops[MAX_NUM_OPS];
168 inline
169 gimple_match_op::gimple_match_op ()
170 : cond (gimple_match_cond::UNCOND), type (NULL_TREE), reverse (false),
171 num_ops (0)
175 /* Constructor that takes the condition, code, type and number of
176 operands, but leaves the caller to fill in the operands. */
178 inline
179 gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
180 code_helper code_in, tree type_in,
181 unsigned int num_ops_in)
182 : cond (cond_in), code (code_in), type (type_in), reverse (false),
183 num_ops (num_ops_in)
187 /* Constructors for various numbers of operands. */
189 inline
190 gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
191 code_helper code_in, tree type_in,
192 tree op0)
193 : cond (cond_in), code (code_in), type (type_in), reverse (false),
194 num_ops (1)
196 ops[0] = op0;
199 inline
200 gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
201 code_helper code_in, tree type_in,
202 tree op0, tree op1)
203 : cond (cond_in), code (code_in), type (type_in), reverse (false),
204 num_ops (2)
206 ops[0] = op0;
207 ops[1] = op1;
210 inline
211 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)
214 : cond (cond_in), code (code_in), type (type_in), reverse (false),
215 num_ops (3)
217 ops[0] = op0;
218 ops[1] = op1;
219 ops[2] = op2;
222 inline
223 gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
224 code_helper code_in, tree type_in,
225 tree op0, tree op1, tree op2, tree op3)
226 : cond (cond_in), code (code_in), type (type_in), reverse (false),
227 num_ops (4)
229 ops[0] = op0;
230 ops[1] = op1;
231 ops[2] = op2;
232 ops[3] = op3;
235 inline
236 gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
237 code_helper code_in, tree type_in,
238 tree op0, tree op1, tree op2, tree op3,
239 tree op4)
240 : cond (cond_in), code (code_in), type (type_in), reverse (false),
241 num_ops (5)
243 ops[0] = op0;
244 ops[1] = op1;
245 ops[2] = op2;
246 ops[3] = op3;
247 ops[4] = op4;
250 /* Change the operation performed to CODE_IN, the type of the result to
251 TYPE_IN, and the number of operands to NUM_OPS_IN. The caller needs
252 to set the operands itself. */
254 inline void
255 gimple_match_op::set_op (code_helper code_in, tree type_in,
256 unsigned int num_ops_in)
258 code = code_in;
259 type = type_in;
260 num_ops = num_ops_in;
263 /* Functions for changing the operation performed, for various numbers
264 of operands. */
266 inline void
267 gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0)
269 code = code_in;
270 type = type_in;
271 num_ops = 1;
272 ops[0] = op0;
275 inline void
276 gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0, tree op1)
278 code = code_in;
279 type = type_in;
280 num_ops = 2;
281 ops[0] = op0;
282 ops[1] = op1;
285 inline void
286 gimple_match_op::set_op (code_helper code_in, tree type_in,
287 tree op0, tree op1, tree op2)
289 code = code_in;
290 type = type_in;
291 num_ops = 3;
292 ops[0] = op0;
293 ops[1] = op1;
294 ops[2] = op2;
297 inline void
298 gimple_match_op::set_op (code_helper code_in, tree type_in,
299 tree op0, tree op1, tree op2, bool reverse_in)
301 code = code_in;
302 type = type_in;
303 reverse = reverse_in;
304 num_ops = 3;
305 ops[0] = op0;
306 ops[1] = op1;
307 ops[2] = op2;
310 inline void
311 gimple_match_op::set_op (code_helper code_in, tree type_in,
312 tree op0, tree op1, tree op2, tree op3)
314 code = code_in;
315 type = type_in;
316 num_ops = 4;
317 ops[0] = op0;
318 ops[1] = op1;
319 ops[2] = op2;
320 ops[3] = op3;
323 inline void
324 gimple_match_op::set_op (code_helper code_in, tree type_in,
325 tree op0, tree op1, tree op2, tree op3, tree op4)
327 code = code_in;
328 type = type_in;
329 num_ops = 5;
330 ops[0] = op0;
331 ops[1] = op1;
332 ops[2] = op2;
333 ops[3] = op3;
334 ops[4] = op4;
337 /* Set the "operation" to be the single value VALUE, such as a constant
338 or SSA_NAME. */
340 inline void
341 gimple_match_op::set_value (tree value)
343 set_op (TREE_CODE (value), TREE_TYPE (value), value);
346 /* Return the value of operand I, or null if there aren't that many
347 operands. */
349 inline tree
350 gimple_match_op::op_or_null (unsigned int i) const
352 return i < num_ops ? ops[i] : NULL_TREE;
355 /* Return whether OP is a non-expression result and a gimple value. */
357 inline bool
358 gimple_simplified_result_is_gimple_val (const gimple_match_op *op)
360 return (op->code.is_tree_code ()
361 && (TREE_CODE_LENGTH ((tree_code) op->code) == 0
362 || ((tree_code) op->code) == ADDR_EXPR)
363 && is_gimple_val (op->ops[0]));
366 extern tree (*mprts_hook) (gimple_match_op *);
368 bool gimple_extract_op (gimple *, gimple_match_op *);
369 bool gimple_simplify (gimple *, gimple_match_op *, gimple_seq *,
370 tree (*)(tree), tree (*)(tree));
371 tree maybe_push_res_to_seq (gimple_match_op *, gimple_seq *,
372 tree res = NULL_TREE);
373 void maybe_build_generic_op (gimple_match_op *);
375 bool commutative_binary_op_p (code_helper, tree);
376 bool commutative_ternary_op_p (code_helper, tree);
377 int first_commutative_argument (code_helper, tree);
378 bool associative_binary_op_p (code_helper, tree);
379 code_helper canonicalize_code (code_helper, tree);
381 #ifdef GCC_OPTABS_TREE_H
382 bool directly_supported_p (code_helper, tree, optab_subtype = optab_default);
383 #endif
385 internal_fn get_conditional_internal_fn (code_helper, tree);
387 extern tree gimple_build (gimple_seq *, location_t,
388 code_helper, tree, tree);
389 inline tree
390 gimple_build (gimple_seq *seq, code_helper code, tree type, tree op0)
392 return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0);
395 extern tree gimple_build (gimple_seq *, location_t,
396 code_helper, tree, tree, tree);
397 inline tree
398 gimple_build (gimple_seq *seq, code_helper code, tree type, tree op0,
399 tree op1)
401 return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0, op1);
404 extern tree gimple_build (gimple_seq *, location_t,
405 code_helper, tree, tree, tree, tree);
406 inline tree
407 gimple_build (gimple_seq *seq, code_helper code, tree type, tree op0,
408 tree op1, tree op2)
410 return gimple_build (seq, UNKNOWN_LOCATION, code, type, op0, op1, op2);
413 #endif /* GCC_GIMPLE_MATCH_H */