1 /* Gimple simplify definitions.
3 Copyright (C) 2011-2022 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
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
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. */
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
; }
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));
64 code_helper::is_internal_fn () const
66 return is_fn_code () && internal_fn_p (combined_fn (*this));
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
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. */
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. */
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
115 class 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. */
154 /* The type of the result. */
157 /* For a BIT_FIELD_REF, whether the group of bits is stored in reverse order
158 from the target order. */
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
];
169 gimple_match_op::gimple_match_op ()
170 : cond (gimple_match_cond::UNCOND
), type (NULL_TREE
), reverse (false),
175 /* Constructor that takes the condition, code, type and number of
176 operands, but leaves the caller to fill in the operands. */
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),
187 /* Constructors for various numbers of operands. */
190 gimple_match_op::gimple_match_op (const gimple_match_cond
&cond_in
,
191 code_helper code_in
, tree type_in
,
193 : cond (cond_in
), code (code_in
), type (type_in
), reverse (false),
200 gimple_match_op::gimple_match_op (const gimple_match_cond
&cond_in
,
201 code_helper code_in
, tree type_in
,
203 : cond (cond_in
), code (code_in
), type (type_in
), reverse (false),
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),
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),
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
,
240 : cond (cond_in
), code (code_in
), type (type_in
), reverse (false),
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. */
255 gimple_match_op::set_op (code_helper code_in
, tree type_in
,
256 unsigned int num_ops_in
)
260 num_ops
= num_ops_in
;
263 /* Functions for changing the operation performed, for various numbers
267 gimple_match_op::set_op (code_helper code_in
, tree type_in
, tree op0
)
276 gimple_match_op::set_op (code_helper code_in
, tree type_in
, tree op0
, tree op1
)
286 gimple_match_op::set_op (code_helper code_in
, tree type_in
,
287 tree op0
, tree op1
, tree op2
)
298 gimple_match_op::set_op (code_helper code_in
, tree type_in
,
299 tree op0
, tree op1
, tree op2
, bool reverse_in
)
303 reverse
= reverse_in
;
311 gimple_match_op::set_op (code_helper code_in
, tree type_in
,
312 tree op0
, tree op1
, tree op2
, tree op3
)
324 gimple_match_op::set_op (code_helper code_in
, tree type_in
,
325 tree op0
, tree op1
, tree op2
, tree op3
, tree op4
)
337 /* Set the "operation" to be the single value VALUE, such as a constant
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
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. */
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
);
385 internal_fn
get_conditional_internal_fn (code_helper
, tree
);
387 extern tree
gimple_build (gimple_seq
*, location_t
,
388 code_helper
, tree
, 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
);
398 gimple_build (gimple_seq
*seq
, code_helper code
, tree type
, tree op0
,
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
);
407 gimple_build (gimple_seq
*seq
, code_helper code
, tree type
, tree op0
,
410 return gimple_build (seq
, UNKNOWN_LOCATION
, code
, type
, op0
, op1
, op2
);
413 #endif /* GCC_GIMPLE_MATCH_H */