Line data Source code
1 : /* Gimple folding definitions.
2 :
3 : Copyright (C) 2011-2026 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_FOLD_H
23 : #define GCC_GIMPLE_FOLD_H
24 :
25 : #include "tree-pass.h"
26 :
27 : extern tree canonicalize_constructor_val (tree, tree);
28 : extern tree get_symbol_constant_value (tree);
29 : struct c_strlen_data;
30 : extern bool get_range_strlen (tree, c_strlen_data *, unsigned eltsize);
31 : extern void gimplify_and_update_call_from_tree (gimple_stmt_iterator *, tree);
32 : extern bool update_gimple_call (gimple_stmt_iterator *, tree, int, ...);
33 : extern tree no_follow_ssa_edges (tree);
34 : extern tree follow_single_use_edges (tree);
35 : extern tree follow_all_ssa_edges (tree);
36 : extern bool fold_stmt (gimple_stmt_iterator *, bitmap = nullptr);
37 : extern bool fold_stmt (gimple_stmt_iterator *, tree (*) (tree), bitmap = nullptr);
38 : extern bool fold_stmt_inplace (gimple_stmt_iterator *, tree (*) (tree) = no_follow_ssa_edges);
39 : extern tree maybe_fold_and_comparisons (tree, enum tree_code, tree, tree,
40 : enum tree_code, tree, tree,
41 : basic_block = nullptr);
42 : extern tree maybe_fold_or_comparisons (tree, enum tree_code, tree, tree,
43 : enum tree_code, tree, tree,
44 : basic_block = nullptr);
45 : extern bool optimize_atomic_compare_exchange_p (gimple *);
46 : extern void fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *);
47 : extern tree gimple_fold_stmt_to_constant_1 (gimple *, tree (*) (tree),
48 : tree (*) (tree) = no_follow_ssa_edges);
49 : extern tree gimple_fold_stmt_to_constant (gimple *, tree (*) (tree));
50 : extern tree fold_ctor_reference (tree, tree, const poly_uint64&,
51 : const poly_uint64&, tree,
52 : unsigned HOST_WIDE_INT * = NULL);
53 : extern tree fold_const_aggregate_ref_1 (tree, tree (*) (tree));
54 : extern tree fold_const_aggregate_ref (tree);
55 : extern tree gimple_get_virt_method_for_binfo (HOST_WIDE_INT, tree,
56 : bool *can_refer = NULL);
57 : extern tree gimple_get_virt_method_for_vtable (HOST_WIDE_INT, tree,
58 : unsigned HOST_WIDE_INT,
59 : bool *can_refer = NULL);
60 : extern tree gimple_fold_indirect_ref (tree);
61 : extern bool gimple_fold_builtin_sprintf (gimple_stmt_iterator *);
62 : extern bool gimple_fold_builtin_snprintf (gimple_stmt_iterator *);
63 : extern bool arith_code_with_undefined_signed_overflow (tree_code);
64 : extern bool gimple_needing_rewrite_undefined (gimple *);
65 : extern void rewrite_to_defined_unconditional (gimple_stmt_iterator *);
66 : extern gimple_seq rewrite_to_defined_unconditional (gimple *);
67 : extern void replace_call_with_value (gimple_stmt_iterator *, tree);
68 : extern tree tree_vec_extract (gimple_stmt_iterator *, tree, tree, tree, tree);
69 : extern void gsi_replace_with_seq_vops (gimple_stmt_iterator *, gimple_seq);
70 :
71 : /* gimple_build, functionally matching fold_buildN, outputs stmts
72 : int the provided sequence, matching and simplifying them on-the-fly.
73 : Supposed to replace force_gimple_operand (fold_buildN (...), ...). */
74 : extern tree gimple_build (gimple_stmt_iterator *, bool,
75 : enum gsi_iterator_update,
76 : location_t, enum tree_code, tree, tree);
77 : extern tree gimple_build (gimple_stmt_iterator *, bool,
78 : enum gsi_iterator_update,
79 : location_t, enum tree_code, tree, tree, tree);
80 : extern tree gimple_build (gimple_stmt_iterator *, bool,
81 : enum gsi_iterator_update,
82 : location_t, enum tree_code, tree, tree, tree, tree);
83 : template<class ...Args>
84 : inline tree
85 524884 : gimple_build (gimple_seq *seq, location_t loc,
86 : enum tree_code code, tree type, Args ...ops)
87 : {
88 : static_assert (sizeof...(ops) > 0 && sizeof...(ops) <= 3,
89 : "Number of operands must be from one to three");
90 524884 : gimple_stmt_iterator gsi = gsi_last (*seq);
91 524884 : return gimple_build (&gsi, false, GSI_CONTINUE_LINKING,
92 524884 : loc, code, type, ops...);
93 : }
94 : template<class ...Args>
95 : inline tree
96 358821 : gimple_build (gimple_seq *seq, enum tree_code code, tree type, Args ...ops)
97 : {
98 : static_assert (sizeof...(ops) > 0 && sizeof...(ops) <= 3,
99 : "Number of operands must be from one to three");
100 358821 : gimple_stmt_iterator gsi = gsi_last (*seq);
101 358821 : return gimple_build (&gsi, false, GSI_CONTINUE_LINKING,
102 358821 : UNKNOWN_LOCATION, code, type, ops...);
103 : }
104 :
105 : extern tree gimple_build (gimple_stmt_iterator *, bool,
106 : enum gsi_iterator_update,
107 : location_t, combined_fn, tree);
108 : extern tree gimple_build (gimple_stmt_iterator *, bool,
109 : enum gsi_iterator_update,
110 : location_t, combined_fn, tree, tree);
111 : extern tree gimple_build (gimple_stmt_iterator *, bool,
112 : enum gsi_iterator_update,
113 : location_t, combined_fn, tree, tree, tree);
114 : extern tree gimple_build (gimple_stmt_iterator *, bool,
115 : enum gsi_iterator_update,
116 : location_t, combined_fn, tree, tree, tree, tree);
117 : template<class ...Args>
118 : inline tree
119 381 : gimple_build (gimple_seq *seq, location_t loc,
120 : combined_fn fn, tree type, Args ...args)
121 : {
122 : static_assert (sizeof...(args) < 4,
123 : "Number of arguments must be less than four");
124 381 : gimple_stmt_iterator gsi = gsi_last (*seq);
125 381 : return gimple_build (&gsi, false, GSI_CONTINUE_LINKING,
126 381 : loc, fn, type, args...);
127 : }
128 : template<class ...Args>
129 : inline tree
130 24595 : gimple_build (gimple_seq *seq, combined_fn fn, tree type, Args ...args)
131 : {
132 : static_assert (sizeof...(args) < 4,
133 : "Number of arguments must be less than four");
134 24595 : gimple_stmt_iterator gsi = gsi_last (*seq);
135 24595 : return gimple_build (&gsi, false, GSI_CONTINUE_LINKING,
136 24595 : UNKNOWN_LOCATION, fn, type, args...);
137 : }
138 :
139 : extern tree gimple_build (gimple_stmt_iterator *, bool,
140 : enum gsi_iterator_update,
141 : location_t, code_helper, tree, tree);
142 : extern tree gimple_build (gimple_stmt_iterator *, bool,
143 : enum gsi_iterator_update,
144 : location_t, code_helper, tree, tree, tree);
145 : extern tree gimple_build (gimple_stmt_iterator *, bool,
146 : enum gsi_iterator_update,
147 : location_t, code_helper, tree, tree, tree, tree);
148 :
149 : template<class ...Args>
150 : inline tree
151 : gimple_build (gimple_seq *seq, location_t loc,
152 : code_helper code, tree type, Args ...ops)
153 : {
154 : static_assert (sizeof...(ops) < 4,
155 : "Number of operands must be less than four");
156 : gimple_stmt_iterator gsi = gsi_last (*seq);
157 : return gimple_build (&gsi, false, GSI_CONTINUE_LINKING,
158 : loc, code, type, ops...);
159 : }
160 : template<class ...Args>
161 : inline tree
162 24078 : gimple_build (gimple_seq *seq,
163 : code_helper code, tree type, Args ...ops)
164 : {
165 : static_assert (sizeof...(ops) < 4,
166 : "Number of operands must be less than four");
167 24078 : gimple_stmt_iterator gsi = gsi_last (*seq);
168 24078 : return gimple_build (&gsi, false, GSI_CONTINUE_LINKING,
169 24078 : UNKNOWN_LOCATION, code, type, ops...);
170 : }
171 :
172 : extern tree gimple_convert (gimple_stmt_iterator *, bool,
173 : enum gsi_iterator_update,
174 : location_t, tree, tree);
175 : inline tree
176 19649 : gimple_convert (gimple_seq *seq, location_t loc, tree type, tree op)
177 : {
178 19649 : gimple_stmt_iterator gsi = gsi_last (*seq);
179 19649 : return gimple_convert (&gsi, false, GSI_CONTINUE_LINKING, loc, type, op);
180 : }
181 : inline tree
182 1875294 : gimple_convert (gimple_seq *seq, tree type, tree op)
183 : {
184 1875294 : gimple_stmt_iterator gsi = gsi_last (*seq);
185 1875294 : return gimple_convert (&gsi, false, GSI_CONTINUE_LINKING,
186 1875294 : UNKNOWN_LOCATION, type, op);
187 : }
188 :
189 : extern tree gimple_convert_to_ptrofftype (gimple_stmt_iterator *, bool,
190 : enum gsi_iterator_update,
191 : location_t, tree);
192 : inline tree
193 203 : gimple_convert_to_ptrofftype (gimple_seq *seq, location_t loc, tree op)
194 : {
195 203 : gimple_stmt_iterator gsi = gsi_last (*seq);
196 203 : return gimple_convert_to_ptrofftype (&gsi, false, GSI_CONTINUE_LINKING,
197 203 : loc, op);
198 : }
199 : inline tree
200 : gimple_convert_to_ptrofftype (gimple_seq *seq, tree op)
201 : {
202 : gimple_stmt_iterator gsi = gsi_last (*seq);
203 : return gimple_convert_to_ptrofftype (&gsi, false, GSI_CONTINUE_LINKING,
204 : UNKNOWN_LOCATION, op);
205 : }
206 :
207 : extern tree gimple_build_vector_from_val (gimple_stmt_iterator *, bool,
208 : enum gsi_iterator_update,
209 : location_t, tree, tree);
210 : inline tree
211 155 : gimple_build_vector_from_val (gimple_seq *seq, location_t loc,
212 : tree type, tree op)
213 : {
214 155 : gimple_stmt_iterator gsi = gsi_last (*seq);
215 155 : return gimple_build_vector_from_val (&gsi, false, GSI_CONTINUE_LINKING,
216 155 : loc, type, op);
217 : }
218 : inline tree
219 324400 : gimple_build_vector_from_val (gimple_seq *seq, tree type, tree op)
220 : {
221 324400 : gimple_stmt_iterator gsi = gsi_last (*seq);
222 324400 : return gimple_build_vector_from_val (&gsi, false, GSI_CONTINUE_LINKING,
223 324400 : UNKNOWN_LOCATION, type, op);
224 : }
225 :
226 : class tree_vector_builder;
227 : extern tree gimple_build_vector (gimple_stmt_iterator *, bool,
228 : enum gsi_iterator_update,
229 : location_t, tree_vector_builder *);
230 : inline tree
231 : gimple_build_vector (gimple_seq *seq, location_t loc,
232 : tree_vector_builder *builder)
233 : {
234 : gimple_stmt_iterator gsi = gsi_last (*seq);
235 : return gimple_build_vector (&gsi, false, GSI_CONTINUE_LINKING,
236 : loc, builder);
237 : }
238 : inline tree
239 366094 : gimple_build_vector (gimple_seq *seq, tree_vector_builder *builder)
240 : {
241 366094 : gimple_stmt_iterator gsi = gsi_last (*seq);
242 366094 : return gimple_build_vector (&gsi, false, GSI_CONTINUE_LINKING,
243 366094 : UNKNOWN_LOCATION, builder);
244 : }
245 :
246 : extern tree gimple_build_round_up (gimple_stmt_iterator *, bool,
247 : enum gsi_iterator_update,
248 : location_t, tree, tree,
249 : unsigned HOST_WIDE_INT);
250 : inline tree
251 0 : gimple_build_round_up (gimple_seq *seq, location_t loc,
252 : tree type, tree old_size, unsigned HOST_WIDE_INT align)
253 : {
254 0 : gimple_stmt_iterator gsi = gsi_last (*seq);
255 0 : return gimple_build_round_up (&gsi, false, GSI_CONTINUE_LINKING,
256 0 : loc, type, old_size, align);
257 : }
258 : inline tree
259 : gimple_build_round_up (gimple_seq *seq, tree type, tree old_size,
260 : unsigned HOST_WIDE_INT align)
261 : {
262 : gimple_stmt_iterator gsi = gsi_last (*seq);
263 : return gimple_build_round_up (&gsi, false, GSI_CONTINUE_LINKING,
264 : UNKNOWN_LOCATION, type, old_size, align);
265 : }
266 :
267 : extern bool gimple_stmt_nonnegative_warnv_p (gimple *, bool *, int = 0);
268 : extern bool gimple_stmt_integer_valued_real_p (gimple *, int = 0);
269 : extern void mark_lhs_in_seq_for_dce (bitmap, gimple_seq);
270 :
271 : /* In gimple-match.cc. */
272 : extern tree gimple_simplify (enum tree_code, tree, tree,
273 : gimple_seq *, tree (*)(tree));
274 : extern tree gimple_simplify (enum tree_code, tree, tree, tree,
275 : gimple_seq *, tree (*)(tree));
276 : extern tree gimple_simplify (enum tree_code, tree, tree, tree, tree,
277 : gimple_seq *, tree (*)(tree));
278 : extern tree gimple_simplify (combined_fn, tree, tree,
279 : gimple_seq *, tree (*)(tree));
280 : extern tree gimple_simplify (combined_fn, tree, tree, tree,
281 : gimple_seq *, tree (*)(tree));
282 : extern tree gimple_simplify (combined_fn, tree, tree, tree, tree,
283 : gimple_seq *, tree (*)(tree));
284 :
285 : /* Returns true if we are doing the fold before expansion to rtl. */
286 : inline bool
287 520708 : fold_before_rtl_expansion_p ()
288 : {
289 520574 : if (!cfun)
290 : return false;
291 519562 : return (cfun->curr_properties & PROP_last_full_fold) != 0;
292 : }
293 :
294 : #endif /* GCC_GIMPLE_FOLD_H */
|