Line data Source code
1 : /* Header file for gimple iterators.
2 : Copyright (C) 2013-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #ifndef GCC_GIMPLE_ITERATOR_H
21 : #define GCC_GIMPLE_ITERATOR_H
22 :
23 : /* Iterator object for GIMPLE statement sequences. */
24 :
25 : struct gimple_stmt_iterator
26 : {
27 9730797 : gimple *operator * () const { return ptr; }
28 :
29 : /* Sequence node holding the current statement. */
30 : gimple_seq_node ptr;
31 :
32 : /* Sequence and basic block holding the statement. These fields
33 : are necessary to handle edge cases such as when statement is
34 : added to an empty basic block or when the last statement of a
35 : block/sequence is removed. */
36 : gimple_seq *seq;
37 : basic_block bb;
38 : };
39 :
40 : /* Iterator over GIMPLE_PHI statements. */
41 : struct gphi_iterator : public gimple_stmt_iterator
42 : {
43 63493915 : gphi *operator * () const { return as_a <gphi *> (ptr); }
44 :
45 4733487821 : gphi *phi () const
46 : {
47 4682201281 : return as_a <gphi *> (ptr);
48 : }
49 : };
50 :
51 : enum gsi_iterator_update
52 : {
53 : GSI_NEW_STMT = 2, /* Move the iterator to the first statement added. */
54 : GSI_LAST_NEW_STMT, /* Move the iterator to the last statement added. */
55 : GSI_SAME_STMT, /* Leave the iterator at the same statement. */
56 : GSI_CONTINUE_LINKING /* Move iterator to whatever position is suitable
57 : for linking other statements in the same
58 : direction. */
59 : };
60 :
61 : extern void gsi_insert_seq_before_without_update (gimple_stmt_iterator *,
62 : gimple_seq,
63 : enum gsi_iterator_update);
64 : extern void gsi_insert_seq_before (gimple_stmt_iterator *, gimple_seq,
65 : enum gsi_iterator_update);
66 : extern void gsi_insert_seq_after_without_update (gimple_stmt_iterator *,
67 : gimple_seq,
68 : enum gsi_iterator_update);
69 : extern void gsi_insert_seq_after (gimple_stmt_iterator *, gimple_seq,
70 : enum gsi_iterator_update);
71 : extern gimple_seq gsi_split_seq_after (gimple_stmt_iterator);
72 : extern void gsi_set_stmt (gimple_stmt_iterator *, gimple *);
73 : extern void gsi_split_seq_before (gimple_stmt_iterator *, gimple_seq *);
74 : extern bool gsi_replace (gimple_stmt_iterator *, gimple *, bool);
75 : extern void gsi_replace_with_seq (gimple_stmt_iterator *, gimple_seq, bool);
76 : extern void gsi_insert_before_without_update (gimple_stmt_iterator *, gimple *,
77 : enum gsi_iterator_update);
78 : extern void gsi_insert_before (gimple_stmt_iterator *, gimple *,
79 : enum gsi_iterator_update);
80 : extern void gsi_insert_after_without_update (gimple_stmt_iterator *, gimple *,
81 : enum gsi_iterator_update);
82 : extern void gsi_insert_after (gimple_stmt_iterator *, gimple *,
83 : enum gsi_iterator_update);
84 : extern bool gsi_remove (gimple_stmt_iterator *, bool);
85 : extern gimple_stmt_iterator gsi_for_stmt (gimple *);
86 : extern gimple_stmt_iterator gsi_for_stmt (gimple *, gimple_seq *);
87 : extern gphi_iterator gsi_for_phi (gphi *);
88 : extern void gsi_move_after (gimple_stmt_iterator *, gimple_stmt_iterator *);
89 : extern void gsi_move_before (gimple_stmt_iterator *, gimple_stmt_iterator *,
90 : gsi_iterator_update = GSI_SAME_STMT);
91 : extern void gsi_move_to_bb_end (gimple_stmt_iterator *, basic_block);
92 : extern void gsi_insert_on_edge (edge, gimple *);
93 : extern void gsi_insert_seq_on_edge (edge, gimple_seq);
94 : extern basic_block gsi_insert_on_edge_immediate (edge, gimple *);
95 : extern basic_block gsi_insert_seq_on_edge_immediate (edge, gimple_seq);
96 : extern void gsi_safe_insert_before (gimple_stmt_iterator *, gimple *);
97 : extern void gsi_safe_insert_seq_before (gimple_stmt_iterator *, gimple_seq);
98 : extern void gsi_commit_edge_inserts (void);
99 : extern void gsi_commit_one_edge_insert (edge, basic_block *);
100 : extern gphi_iterator gsi_start_phis (basic_block);
101 : extern void update_modified_stmts (gimple_seq);
102 :
103 : /* Return a new iterator pointing to GIMPLE_SEQ's first statement. */
104 :
105 : inline gimple_stmt_iterator
106 359273299 : gsi_start (gimple_seq &seq)
107 : {
108 359273299 : gimple_stmt_iterator i;
109 :
110 349161248 : i.ptr = gimple_seq_first (seq);
111 359273299 : i.seq = &seq;
112 225955653 : i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
113 :
114 325494490 : return i;
115 : }
116 :
117 : inline gimple_stmt_iterator
118 2530463 : gsi_none (void)
119 : {
120 2530463 : gimple_stmt_iterator i;
121 2530463 : i.ptr = NULL;
122 2530463 : i.seq = NULL;
123 2530463 : i.bb = NULL;
124 2530463 : return i;
125 : }
126 :
127 : /* Return a new iterator pointing to the first statement in basic block BB. */
128 :
129 : inline gimple_stmt_iterator
130 13839040753 : gsi_start_bb (basic_block bb)
131 : {
132 13839040753 : gimple_stmt_iterator i;
133 9362916905 : gimple_seq *seq;
134 :
135 13676213565 : seq = bb_seq_addr (bb);
136 13834724047 : i.ptr = gimple_seq_first (*seq);
137 13834724047 : i.seq = seq;
138 13834724047 : i.bb = bb;
139 :
140 13547083860 : return i;
141 : }
142 :
143 : gimple_stmt_iterator gsi_start_edge (edge e);
144 :
145 : /* Return a new iterator initially pointing to GIMPLE_SEQ's last statement. */
146 :
147 : inline gimple_stmt_iterator
148 1243804355 : gsi_last (gimple_seq &seq)
149 : {
150 1243804355 : gimple_stmt_iterator i;
151 :
152 1243801119 : i.ptr = gimple_seq_last (seq);
153 1243804355 : i.seq = &seq;
154 1239581529 : i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
155 :
156 1243804355 : return i;
157 : }
158 :
159 : /* Return a new iterator pointing to the last statement in basic block BB. */
160 :
161 : inline gimple_stmt_iterator
162 5526182694 : gsi_last_bb (basic_block bb)
163 : {
164 5526182694 : gimple_stmt_iterator i;
165 5526182694 : gimple_seq *seq;
166 :
167 3324992069 : seq = bb_seq_addr (bb);
168 6429509831 : i.ptr = gimple_seq_last (*seq);
169 5257206407 : i.seq = seq;
170 5257206407 : i.bb = bb;
171 :
172 2757262321 : return i;
173 : }
174 :
175 : /* Return a new iterator pointing to before the first statement or after
176 : last statement (depending on whether adding statements after it or before it)
177 : in a GIMPLE_SEQ. */
178 :
179 : inline gimple_stmt_iterator
180 : gsi_end (gimple_seq &seq)
181 : {
182 : gimple_stmt_iterator i;
183 : gimple *g = gimple_seq_last (seq);
184 :
185 : i.ptr = NULL;
186 : i.seq = &seq;
187 : i.bb = g ? gimple_bb (g) : NULL;
188 :
189 : return i;
190 : }
191 :
192 : /* Return a new iterator pointing to before the first statement or after
193 : last statement (depending on whether adding statements after it or before it)
194 : in basic block BB. */
195 :
196 : inline gimple_stmt_iterator
197 5435 : gsi_end_bb (basic_block bb)
198 : {
199 5435 : gimple_stmt_iterator i;
200 5435 : gimple_seq *seq;
201 :
202 5437 : seq = bb_seq_addr (bb);
203 5435 : i.ptr = NULL;
204 5435 : i.seq = seq;
205 5435 : i.bb = bb;
206 :
207 5435 : return i;
208 : }
209 :
210 : /* Return true if I is at the end of its sequence. */
211 :
212 : inline bool
213 15825303023 : gsi_end_p (gimple_stmt_iterator i)
214 : {
215 14574043648 : return i.ptr == NULL;
216 : }
217 :
218 : /* Return true if I is one statement before the end of its sequence. */
219 :
220 : inline bool
221 608435627 : gsi_one_before_end_p (gimple_stmt_iterator i)
222 : {
223 608435626 : return i.ptr != NULL && i.ptr->next == NULL;
224 : }
225 :
226 : /* Advance the iterator to the next gimple statement. */
227 :
228 : inline void
229 92437543434 : gsi_next (gimple_stmt_iterator *i)
230 : {
231 29015206418 : i->ptr = i->ptr->next;
232 88903087773 : }
233 :
234 : /* Advance the iterator to the previous gimple statement. */
235 :
236 : inline void
237 3972288704 : gsi_prev (gimple_stmt_iterator *i)
238 : {
239 3972288704 : gimple *prev = i->ptr->prev;
240 3204412126 : if (prev->next)
241 1748531080 : i->ptr = prev;
242 : else
243 407440545 : i->ptr = NULL;
244 : }
245 :
246 : /* Return the current stmt. */
247 :
248 : inline gimple *
249 9687124016 : gsi_stmt (gimple_stmt_iterator i)
250 : {
251 9261869348 : return i.ptr;
252 : }
253 :
254 : /* Return a block statement iterator that points to the first
255 : non-label statement in block BB. */
256 :
257 : inline gimple_stmt_iterator
258 295061875 : gsi_after_labels (basic_block bb)
259 : {
260 295061875 : gimple_stmt_iterator gsi = gsi_start_bb (bb);
261 :
262 311084991 : for (; !gsi_end_p (gsi); )
263 : {
264 259199656 : if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
265 16023116 : gsi_next (&gsi);
266 : else
267 : break;
268 : }
269 :
270 295061875 : return gsi;
271 : }
272 :
273 : /* Return a statement iterator that points to the first
274 : non-label statement in sequence SEQ. */
275 :
276 : inline gimple_stmt_iterator
277 : gsi_after_labels (gimple_seq &seq)
278 : {
279 : gimple_stmt_iterator gsi = gsi_start (seq);
280 :
281 : for (; !gsi_end_p (gsi); )
282 : {
283 : if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
284 : gsi_next (&gsi);
285 : else
286 : break;
287 : }
288 :
289 : return gsi;
290 : }
291 :
292 : /* Advance the iterator to the next non-debug gimple statement. */
293 :
294 : inline void
295 1090861139 : gsi_next_nondebug (gimple_stmt_iterator *i)
296 : {
297 2236495528 : do
298 : {
299 2236495528 : gsi_next (i);
300 : }
301 3327356667 : while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
302 1090861139 : }
303 :
304 : /* Advance the iterator to the previous non-debug gimple statement. */
305 :
306 : inline void
307 212034822 : gsi_prev_nondebug (gimple_stmt_iterator *i)
308 : {
309 828280350 : do
310 : {
311 828280350 : gsi_prev (i);
312 : }
313 1040315172 : while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
314 212034822 : }
315 :
316 : /* Return a new iterator pointing to the first non-debug statement in
317 : SEQ. */
318 :
319 : inline gimple_stmt_iterator
320 696 : gsi_start_nondebug (gimple_seq seq)
321 : {
322 696 : gimple_stmt_iterator gsi = gsi_start (seq);
323 696 : if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
324 0 : gsi_next_nondebug (&gsi);
325 :
326 696 : return gsi;
327 : }
328 :
329 : /* Return a new iterator pointing to the first non-debug statement in
330 : basic block BB. */
331 :
332 : inline gimple_stmt_iterator
333 177236403 : gsi_start_nondebug_bb (basic_block bb)
334 : {
335 177236403 : gimple_stmt_iterator i = gsi_start_bb (bb);
336 :
337 177236403 : if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
338 37230686 : gsi_next_nondebug (&i);
339 :
340 177236403 : return i;
341 : }
342 :
343 : /* Return a new iterator pointing to the first non-debug non-label statement in
344 : basic block BB. */
345 :
346 : inline gimple_stmt_iterator
347 69360981 : gsi_start_nondebug_after_labels_bb (basic_block bb)
348 : {
349 69360981 : gimple_stmt_iterator i = gsi_after_labels (bb);
350 :
351 69360981 : if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
352 16549213 : gsi_next_nondebug (&i);
353 :
354 69360981 : return i;
355 : }
356 :
357 : /* Return a new iterator pointing to the last non-debug statement in
358 : basic block BB. */
359 :
360 : inline gimple_stmt_iterator
361 2772448253 : gsi_last_nondebug_bb (basic_block bb)
362 : {
363 2772448253 : gimple_stmt_iterator i = gsi_last_bb (bb);
364 :
365 2772448253 : if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
366 161735710 : gsi_prev_nondebug (&i);
367 :
368 2772448253 : return i;
369 : }
370 :
371 : /* Return true if I is followed only by debug statements in its
372 : sequence. */
373 :
374 : inline bool
375 535951 : gsi_one_nondebug_before_end_p (gimple_stmt_iterator i)
376 : {
377 535951 : if (gsi_one_before_end_p (i))
378 : return true;
379 4 : if (gsi_end_p (i))
380 : return false;
381 4 : gsi_next_nondebug (&i);
382 4 : return gsi_end_p (i);
383 : }
384 :
385 : /* Advance I statement iterator to the next non-virtual GIMPLE_PHI
386 : statement. */
387 :
388 : inline void
389 15575278 : gsi_next_nonvirtual_phi (gphi_iterator *i)
390 : {
391 17887709 : do
392 : {
393 17887709 : gsi_next (i);
394 : }
395 31199693 : while (!gsi_end_p (*i) && virtual_operand_p (gimple_phi_result (i->phi ())));
396 15575278 : }
397 :
398 : /* Return a new iterator pointing to the first non-virtual phi statement in
399 : basic block BB. */
400 :
401 : inline gphi_iterator
402 41937417 : gsi_start_nonvirtual_phis (basic_block bb)
403 : {
404 41937417 : gphi_iterator i = gsi_start_phis (bb);
405 :
406 65986701 : if (!gsi_end_p (i) && virtual_operand_p (gimple_phi_result (i.phi ())))
407 6501471 : gsi_next_nonvirtual_phi (&i);
408 :
409 41937417 : return i;
410 : }
411 :
412 : /* Return the basic block associated with this iterator. */
413 :
414 : inline basic_block
415 462890248 : gsi_bb (gimple_stmt_iterator i)
416 : {
417 462887573 : return i.bb;
418 : }
419 :
420 : /* Return the sequence associated with this iterator. */
421 :
422 : inline gimple_seq
423 838626 : gsi_seq (gimple_stmt_iterator i)
424 : {
425 838626 : return *i.seq;
426 : }
427 :
428 : /* Determine whether SEQ is a nondebug singleton. */
429 :
430 : inline bool
431 696 : gimple_seq_nondebug_singleton_p (gimple_seq seq)
432 : {
433 696 : gimple_stmt_iterator gsi = gsi_start_nondebug (seq);
434 :
435 696 : return gsi_one_nondebug_before_end_p (gsi);
436 : }
437 :
438 : #endif /* GCC_GIMPLE_ITERATOR_H */
|