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