analyzer: fix feasibility false +ve on jumps through function ptrs [PR107582]
[platform/upstream/gcc.git] / gcc / gimple-match.h
1 /* Gimple simplify definitions.
2
3    Copyright (C) 2011-2022 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   gimple_match_cond (uncond) : cond (NULL_TREE), else_value (NULL_TREE) {}
36   gimple_match_cond (tree, tree);
37
38   gimple_match_cond any_else () const;
39
40   /* The condition under which the operation occurs, or NULL_TREE
41      if the operation is unconditional.  */
42   tree cond;
43
44   /* The value to use when the condition is false.  This is NULL_TREE if
45      the operation is unconditional or if the value doesn't matter.  */
46   tree else_value;
47 };
48
49 inline
50 gimple_match_cond::gimple_match_cond (tree cond_in, tree else_value_in)
51   : cond (cond_in), else_value (else_value_in)
52 {
53 }
54
55 /* Return a gimple_match_cond with the same condition but with an
56    arbitrary ELSE_VALUE.  */
57
58 inline gimple_match_cond
59 gimple_match_cond::any_else () const
60 {
61   return gimple_match_cond (cond, NULL_TREE);
62 }
63
64 /* Represents an operation to be simplified, or the result of the
65    simplification.  */
66 class gimple_match_op
67 {
68 public:
69   gimple_match_op ();
70   gimple_match_op (const gimple_match_cond &, code_helper, tree, unsigned int);
71   gimple_match_op (const gimple_match_cond &,
72                    code_helper, tree, tree);
73   gimple_match_op (const gimple_match_cond &,
74                    code_helper, tree, tree, tree);
75   gimple_match_op (const gimple_match_cond &,
76                    code_helper, tree, tree, tree, tree);
77   gimple_match_op (const gimple_match_cond &,
78                    code_helper, tree, tree, tree, tree, tree);
79   gimple_match_op (const gimple_match_cond &,
80                    code_helper, tree, tree, tree, tree, tree, tree);
81
82   void set_op (code_helper, tree, unsigned int);
83   void set_op (code_helper, tree, tree);
84   void set_op (code_helper, tree, tree, tree);
85   void set_op (code_helper, tree, tree, tree, tree);
86   void set_op (code_helper, tree, tree, tree, tree, bool);
87   void set_op (code_helper, tree, tree, tree, tree, tree);
88   void set_op (code_helper, tree, tree, tree, tree, tree, tree);
89   void set_value (tree);
90
91   tree op_or_null (unsigned int) const;
92
93   bool resimplify (gimple_seq *, tree (*)(tree));
94
95   /* The maximum value of NUM_OPS.  */
96   static const unsigned int MAX_NUM_OPS = 5;
97
98   /* The conditions under which the operation is performed, and the value to
99      use as a fallback.  */
100   gimple_match_cond cond;
101
102   /* The operation being performed.  */
103   code_helper code;
104
105   /* The type of the result.  */
106   tree type;
107
108   /* For a BIT_FIELD_REF, whether the group of bits is stored in reverse order
109      from the target order.  */
110   bool reverse;
111
112   /* The number of operands to CODE.  */
113   unsigned int num_ops;
114
115   /* The operands to CODE.  Only the first NUM_OPS entries are meaningful.  */
116   tree ops[MAX_NUM_OPS];
117 };
118
119 inline
120 gimple_match_op::gimple_match_op ()
121   : cond (gimple_match_cond::UNCOND), type (NULL_TREE), reverse (false),
122     num_ops (0)
123 {
124 }
125
126 /* Constructor that takes the condition, code, type and number of
127    operands, but leaves the caller to fill in the operands.  */
128
129 inline
130 gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
131                                   code_helper code_in, tree type_in,
132                                   unsigned int num_ops_in)
133   : cond (cond_in), code (code_in), type (type_in), reverse (false),
134     num_ops (num_ops_in)
135 {
136 }
137
138 /* Constructors for various numbers of operands.  */
139
140 inline
141 gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
142                                   code_helper code_in, tree type_in,
143                                   tree op0)
144   : cond (cond_in), code (code_in), type (type_in), reverse (false),
145     num_ops (1)
146 {
147   ops[0] = op0;
148 }
149
150 inline
151 gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
152                                   code_helper code_in, tree type_in,
153                                   tree op0, tree op1)
154   : cond (cond_in), code (code_in), type (type_in), reverse (false), 
155     num_ops (2)
156 {
157   ops[0] = op0;
158   ops[1] = op1;
159 }
160
161 inline
162 gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
163                                   code_helper code_in, tree type_in,
164                                   tree op0, tree op1, tree op2)
165   : cond (cond_in), code (code_in), type (type_in), reverse (false),
166     num_ops (3)
167 {
168   ops[0] = op0;
169   ops[1] = op1;
170   ops[2] = op2;
171 }
172
173 inline
174 gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
175                                   code_helper code_in, tree type_in,
176                                   tree op0, tree op1, tree op2, tree op3)
177   : cond (cond_in), code (code_in), type (type_in), reverse (false),
178     num_ops (4)
179 {
180   ops[0] = op0;
181   ops[1] = op1;
182   ops[2] = op2;
183   ops[3] = op3;
184 }
185
186 inline
187 gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
188                                   code_helper code_in, tree type_in,
189                                   tree op0, tree op1, tree op2, tree op3,
190                                   tree op4)
191   : cond (cond_in), code (code_in), type (type_in), reverse (false),
192     num_ops (5)
193 {
194   ops[0] = op0;
195   ops[1] = op1;
196   ops[2] = op2;
197   ops[3] = op3;
198   ops[4] = op4;
199 }
200
201 /* Change the operation performed to CODE_IN, the type of the result to
202    TYPE_IN, and the number of operands to NUM_OPS_IN.  The caller needs
203    to set the operands itself.  */
204
205 inline void
206 gimple_match_op::set_op (code_helper code_in, tree type_in,
207                          unsigned int num_ops_in)
208 {
209   code = code_in;
210   type = type_in;
211   num_ops = num_ops_in;
212 }
213
214 /* Functions for changing the operation performed, for various numbers
215    of operands.  */
216
217 inline void
218 gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0)
219 {
220   code = code_in;
221   type = type_in;
222   num_ops = 1;
223   ops[0] = op0;
224 }
225
226 inline void
227 gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0, tree op1)
228 {
229   code = code_in;
230   type = type_in;
231   num_ops = 2;
232   ops[0] = op0;
233   ops[1] = op1;
234 }
235
236 inline void
237 gimple_match_op::set_op (code_helper code_in, tree type_in,
238                          tree op0, tree op1, tree op2)
239 {
240   code = code_in;
241   type = type_in;
242   num_ops = 3;
243   ops[0] = op0;
244   ops[1] = op1;
245   ops[2] = op2;
246 }
247
248 inline void
249 gimple_match_op::set_op (code_helper code_in, tree type_in,
250                          tree op0, tree op1, tree op2, bool reverse_in)
251 {
252   code = code_in;
253   type = type_in;
254   reverse = reverse_in;
255   num_ops = 3;
256   ops[0] = op0;
257   ops[1] = op1;
258   ops[2] = op2;
259 }
260
261 inline void
262 gimple_match_op::set_op (code_helper code_in, tree type_in,
263                          tree op0, tree op1, tree op2, tree op3)
264 {
265   code = code_in;
266   type = type_in;
267   num_ops = 4;
268   ops[0] = op0;
269   ops[1] = op1;
270   ops[2] = op2;
271   ops[3] = op3;
272 }
273
274 inline void
275 gimple_match_op::set_op (code_helper code_in, tree type_in,
276                          tree op0, tree op1, tree op2, tree op3, tree op4)
277 {
278   code = code_in;
279   type = type_in;
280   num_ops = 5;
281   ops[0] = op0;
282   ops[1] = op1;
283   ops[2] = op2;
284   ops[3] = op3;
285   ops[4] = op4;
286 }
287
288 /* Set the "operation" to be the single value VALUE, such as a constant
289    or SSA_NAME.  */
290
291 inline void
292 gimple_match_op::set_value (tree value)
293 {
294   set_op (TREE_CODE (value), TREE_TYPE (value), value);
295 }
296
297 /* Return the value of operand I, or null if there aren't that many
298    operands.  */
299
300 inline tree
301 gimple_match_op::op_or_null (unsigned int i) const
302 {
303   return i < num_ops ? ops[i] : NULL_TREE;
304 }
305
306 /* Return whether OP is a non-expression result and a gimple value.  */
307
308 inline bool
309 gimple_simplified_result_is_gimple_val (const gimple_match_op *op)
310 {
311   return (op->code.is_tree_code ()
312           && (TREE_CODE_LENGTH ((tree_code) op->code) == 0
313               || ((tree_code) op->code) == ADDR_EXPR)
314           && is_gimple_val (op->ops[0]));
315 }
316
317 extern tree (*mprts_hook) (gimple_match_op *);
318
319 bool gimple_extract_op (gimple *, gimple_match_op *);
320 bool gimple_simplify (gimple *, gimple_match_op *, gimple_seq *,
321                       tree (*)(tree), tree (*)(tree));
322 tree maybe_push_res_to_seq (gimple_match_op *, gimple_seq *,
323                             tree res = NULL_TREE);
324 void maybe_build_generic_op (gimple_match_op *);
325
326 bool commutative_binary_op_p (code_helper, tree);
327 bool commutative_ternary_op_p (code_helper, tree);
328 int first_commutative_argument (code_helper, tree);
329 bool associative_binary_op_p (code_helper, tree);
330 code_helper canonicalize_code (code_helper, tree);
331
332 #ifdef GCC_OPTABS_TREE_H
333 bool directly_supported_p (code_helper, tree, optab_subtype = optab_default);
334 #endif
335
336 internal_fn get_conditional_internal_fn (code_helper, tree);
337
338 #endif  /* GCC_GIMPLE_MATCH_H */