Branch data Line data Source code
1 : : /* Gimple folding definitions.
2 : :
3 : : Copyright (C) 2011-2025 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 : 541186 : 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 : 541186 : gimple_stmt_iterator gsi = gsi_last (*seq);
91 : 541186 : return gimple_build (&gsi, false, GSI_CONTINUE_LINKING,
92 : 541186 : loc, code, type, ops...);
93 : : }
94 : : template<class ...Args>
95 : : inline tree
96 : 359337 : 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 : 359337 : gimple_stmt_iterator gsi = gsi_last (*seq);
101 : 359337 : return gimple_build (&gsi, false, GSI_CONTINUE_LINKING,
102 : 359337 : 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 : 377 : 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 : 377 : gimple_stmt_iterator gsi = gsi_last (*seq);
125 : 377 : return gimple_build (&gsi, false, GSI_CONTINUE_LINKING,
126 : 377 : loc, fn, type, args...);
127 : : }
128 : : template<class ...Args>
129 : : inline tree
130 : 23853 : 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 : 23853 : gimple_stmt_iterator gsi = gsi_last (*seq);
135 : 23853 : return gimple_build (&gsi, false, GSI_CONTINUE_LINKING,
136 : 23853 : 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 : 24415 : 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 : 24415 : gimple_stmt_iterator gsi = gsi_last (*seq);
168 : 24415 : return gimple_build (&gsi, false, GSI_CONTINUE_LINKING,
169 : 24415 : 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 : 30320 : gimple_convert (gimple_seq *seq, location_t loc, tree type, tree op)
177 : : {
178 : 30320 : gimple_stmt_iterator gsi = gsi_last (*seq);
179 : 30320 : return gimple_convert (&gsi, false, GSI_CONTINUE_LINKING, loc, type, op);
180 : : }
181 : : inline tree
182 : 1859685 : gimple_convert (gimple_seq *seq, tree type, tree op)
183 : : {
184 : 1859685 : gimple_stmt_iterator gsi = gsi_last (*seq);
185 : 1859685 : return gimple_convert (&gsi, false, GSI_CONTINUE_LINKING,
186 : 1859685 : 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 : 150 : gimple_build_vector_from_val (gimple_seq *seq, location_t loc,
212 : : tree type, tree op)
213 : : {
214 : 150 : gimple_stmt_iterator gsi = gsi_last (*seq);
215 : 150 : return gimple_build_vector_from_val (&gsi, false, GSI_CONTINUE_LINKING,
216 : 150 : loc, type, op);
217 : : }
218 : : inline tree
219 : 324223 : gimple_build_vector_from_val (gimple_seq *seq, tree type, tree op)
220 : : {
221 : 324223 : gimple_stmt_iterator gsi = gsi_last (*seq);
222 : 324223 : return gimple_build_vector_from_val (&gsi, false, GSI_CONTINUE_LINKING,
223 : 324223 : 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 : 374099 : gimple_build_vector (gimple_seq *seq, tree_vector_builder *builder)
240 : : {
241 : 374099 : gimple_stmt_iterator gsi = gsi_last (*seq);
242 : 374099 : return gimple_build_vector (&gsi, false, GSI_CONTINUE_LINKING,
243 : 374099 : 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 : 492881 : fold_before_rtl_expansion_p ()
288 : : {
289 : 492747 : if (!cfun)
290 : : return false;
291 : 492881 : return (cfun->curr_properties & PROP_last_full_fold) != 0;
292 : : }
293 : :
294 : : #endif /* GCC_GIMPLE_FOLD_H */
|