Branch data Line data Source code
1 : : /* Header file for gimple iterators.
2 : : Copyright (C) 2013-2025 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 : 38 : 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 : 57598340 : gphi *operator * () const { return as_a <gphi *> (ptr); }
44 : :
45 : 4427950162 : gphi *phi () const
46 : : {
47 : 4384930046 : 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 : 336225105 : gsi_start (gimple_seq &seq)
107 : : {
108 : 336225105 : gimple_stmt_iterator i;
109 : :
110 : 322685248 : i.ptr = gimple_seq_first (seq);
111 : 336225105 : i.seq = &seq;
112 : 194355310 : i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
113 : :
114 : 303596806 : return i;
115 : : }
116 : :
117 : : inline gimple_stmt_iterator
118 : 2330949 : gsi_none (void)
119 : : {
120 : 2330949 : gimple_stmt_iterator i;
121 : 2330949 : i.ptr = NULL;
122 : 2330949 : i.seq = NULL;
123 : 2330949 : i.bb = NULL;
124 : 2330949 : 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 : 12975927995 : gsi_start_bb (basic_block bb)
131 : : {
132 : 12975927995 : gimple_stmt_iterator i;
133 : 8795618272 : gimple_seq *seq;
134 : :
135 : 12823167534 : seq = bb_seq_addr (bb);
136 : 12972147753 : i.ptr = gimple_seq_first (*seq);
137 : 12972147753 : i.seq = seq;
138 : 12972147753 : i.bb = bb;
139 : :
140 : 12710924073 : 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 : 1185898657 : gsi_last (gimple_seq &seq)
149 : : {
150 : 1185898657 : gimple_stmt_iterator i;
151 : :
152 : 1185895421 : i.ptr = gimple_seq_last (seq);
153 : 1185898657 : i.seq = &seq;
154 : 1182049012 : i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
155 : :
156 : 1185898657 : 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 : 5154114403 : gsi_last_bb (basic_block bb)
163 : : {
164 : 5154114403 : gimple_stmt_iterator i;
165 : 5154114403 : gimple_seq *seq;
166 : :
167 : 3017626905 : seq = bb_seq_addr (bb);
168 : 6192469486 : i.ptr = gimple_seq_last (*seq);
169 : 4758930830 : i.seq = seq;
170 : 4758930830 : i.bb = bb;
171 : :
172 : 2377467407 : 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 : 5322 : gsi_end_bb (basic_block bb)
198 : : {
199 : 5322 : gimple_stmt_iterator i;
200 : 5322 : gimple_seq *seq;
201 : :
202 : 5324 : seq = bb_seq_addr (bb);
203 : 5322 : i.ptr = NULL;
204 : 5322 : i.seq = seq;
205 : 5322 : i.bb = bb;
206 : :
207 : 5322 : return i;
208 : : }
209 : :
210 : : /* Return true if I is at the end of its sequence. */
211 : :
212 : : inline bool
213 : 13835815740 : gsi_end_p (gimple_stmt_iterator i)
214 : : {
215 : 12813852319 : 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 : 561310302 : gsi_one_before_end_p (gimple_stmt_iterator i)
222 : : {
223 : 561310032 : return i.ptr != NULL && i.ptr->next == NULL;
224 : : }
225 : :
226 : : /* Advance the iterator to the next gimple statement. */
227 : :
228 : : inline void
229 : 82268120046 : gsi_next (gimple_stmt_iterator *i)
230 : : {
231 : 24621136768 : i->ptr = i->ptr->next;
232 : 79457678796 : }
233 : :
234 : : /* Advance the iterator to the previous gimple statement. */
235 : :
236 : : inline void
237 : 3405957822 : gsi_prev (gimple_stmt_iterator *i)
238 : : {
239 : 3405957822 : gimple *prev = i->ptr->prev;
240 : 2773344036 : if (prev->next)
241 : 1371190734 : i->ptr = prev;
242 : : else
243 : 383249777 : i->ptr = NULL;
244 : : }
245 : :
246 : : /* Return the current stmt. */
247 : :
248 : : inline gimple *
249 : 8625687188 : gsi_stmt (gimple_stmt_iterator i)
250 : : {
251 : 8251430015 : 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 : 257076416 : gsi_after_labels (basic_block bb)
259 : : {
260 : 257076416 : gimple_stmt_iterator gsi = gsi_start_bb (bb);
261 : :
262 : 271557415 : for (; !gsi_end_p (gsi); )
263 : : {
264 : 222690168 : if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
265 : 14480999 : gsi_next (&gsi);
266 : : else
267 : : break;
268 : : }
269 : :
270 : 257076416 : 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 : 999846683 : gsi_next_nondebug (gimple_stmt_iterator *i)
296 : : {
297 : 1859045283 : do
298 : : {
299 : 1859045283 : gsi_next (i);
300 : : }
301 : 2858891966 : while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
302 : 999846683 : }
303 : :
304 : : /* Advance the iterator to the previous non-debug gimple statement. */
305 : :
306 : : inline void
307 : 197702105 : gsi_prev_nondebug (gimple_stmt_iterator *i)
308 : : {
309 : 687205505 : do
310 : : {
311 : 687205505 : gsi_prev (i);
312 : : }
313 : 884907610 : while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
314 : 197702105 : }
315 : :
316 : : /* Return a new iterator pointing to the first non-debug statement in
317 : : SEQ. */
318 : :
319 : : inline gimple_stmt_iterator
320 : 706 : gsi_start_nondebug (gimple_seq seq)
321 : : {
322 : 706 : gimple_stmt_iterator gsi = gsi_start (seq);
323 : 706 : if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
324 : 0 : gsi_next_nondebug (&gsi);
325 : :
326 : 706 : 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 : 168294034 : gsi_start_nondebug_bb (basic_block bb)
334 : : {
335 : 168294034 : gimple_stmt_iterator i = gsi_start_bb (bb);
336 : :
337 : 168294034 : if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
338 : 34128617 : gsi_next_nondebug (&i);
339 : :
340 : 168294034 : 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 : 54908420 : gsi_start_nondebug_after_labels_bb (basic_block bb)
348 : : {
349 : 54908420 : gimple_stmt_iterator i = gsi_after_labels (bb);
350 : :
351 : 54908420 : if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
352 : 12269976 : gsi_next_nondebug (&i);
353 : :
354 : 54908420 : 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 : 2612147253 : gsi_last_nondebug_bb (basic_block bb)
362 : : {
363 : 2612147253 : gimple_stmt_iterator i = gsi_last_bb (bb);
364 : :
365 : 2612147253 : if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
366 : 150538067 : gsi_prev_nondebug (&i);
367 : :
368 : 2612147253 : return i;
369 : : }
370 : :
371 : : /* Return true if I is followed only by debug statements in its
372 : : sequence. */
373 : :
374 : : inline bool
375 : 505231 : gsi_one_nondebug_before_end_p (gimple_stmt_iterator i)
376 : : {
377 : 505231 : if (gsi_one_before_end_p (i))
378 : 475791 : return true;
379 : 29440 : if (gsi_end_p (i))
380 : : return false;
381 : 29171 : gsi_next_nondebug (&i);
382 : 29171 : 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 : 2362343 : gsi_next_nonvirtual_phi (gphi_iterator *i)
390 : : {
391 : 2699993 : do
392 : : {
393 : 2699993 : gsi_next (i);
394 : : }
395 : 4308249 : while (!gsi_end_p (*i) && virtual_operand_p (gimple_phi_result (i->phi ())));
396 : 2362343 : }
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 : 8015830 : gsi_start_nonvirtual_phis (basic_block bb)
403 : : {
404 : 8015830 : gphi_iterator i = gsi_start_phis (bb);
405 : :
406 : 12714576 : if (!gsi_end_p (i) && virtual_operand_p (gimple_phi_result (i.phi ())))
407 : 1293670 : gsi_next_nonvirtual_phi (&i);
408 : :
409 : 8015830 : return i;
410 : : }
411 : :
412 : : /* Return the basic block associated with this iterator. */
413 : :
414 : : inline basic_block
415 : 409042986 : gsi_bb (gimple_stmt_iterator i)
416 : : {
417 : 409040405 : return i.bb;
418 : : }
419 : :
420 : : /* Return the sequence associated with this iterator. */
421 : :
422 : : inline gimple_seq
423 : 834070 : gsi_seq (gimple_stmt_iterator i)
424 : : {
425 : 834070 : return *i.seq;
426 : : }
427 : :
428 : : /* Determine whether SEQ is a nondebug singleton. */
429 : :
430 : : inline bool
431 : 706 : gimple_seq_nondebug_singleton_p (gimple_seq seq)
432 : : {
433 : 706 : gimple_stmt_iterator gsi = gsi_start_nondebug (seq);
434 : :
435 : 706 : return gsi_one_nondebug_before_end_p (gsi);
436 : : }
437 : :
438 : : #endif /* GCC_GIMPLE_ITERATOR_H */
|