Branch data Line data Source code
1 : : /* Header file for gimple iterators.
2 : : Copyright (C) 2013-2024 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 : 30 : 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 : 336163 : gphi *operator * () const { return as_a <gphi *> (ptr); }
44 : :
45 : 4220656593 : gphi *phi () const
46 : : {
47 : 4180042000 : 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 : 332420572 : gsi_start (gimple_seq &seq)
107 : : {
108 : 332420572 : gimple_stmt_iterator i;
109 : :
110 : 321307052 : i.ptr = gimple_seq_first (seq);
111 : 332420572 : i.seq = &seq;
112 : 200557176 : i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
113 : :
114 : 300572171 : return i;
115 : : }
116 : :
117 : : inline gimple_stmt_iterator
118 : 2292652 : gsi_none (void)
119 : : {
120 : 2292652 : gimple_stmt_iterator i;
121 : 2292652 : i.ptr = NULL;
122 : 2292652 : i.seq = NULL;
123 : 2292652 : i.bb = NULL;
124 : 2292652 : 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 : 12389368915 : gsi_start_bb (basic_block bb)
131 : : {
132 : 12389368915 : gimple_stmt_iterator i;
133 : 8365351334 : gimple_seq *seq;
134 : :
135 : 12268261190 : seq = bb_seq_addr (bb);
136 : 12385658201 : i.ptr = gimple_seq_first (*seq);
137 : 12385658201 : i.seq = seq;
138 : 12385658201 : i.bb = bb;
139 : :
140 : 12159861726 : 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 : 1143788857 : gsi_last (gimple_seq &seq)
149 : : {
150 : 1143788857 : gimple_stmt_iterator i;
151 : :
152 : 1143785811 : i.ptr = gimple_seq_last (seq);
153 : 1143788857 : i.seq = &seq;
154 : 1140267877 : i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
155 : :
156 : 1143788857 : 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 : 4966486573 : gsi_last_bb (basic_block bb)
163 : : {
164 : 4966486573 : gimple_stmt_iterator i;
165 : 4966486573 : gimple_seq *seq;
166 : :
167 : 2902059030 : seq = bb_seq_addr (bb);
168 : 5946534343 : i.ptr = gimple_seq_last (*seq);
169 : 4586296513 : i.seq = seq;
170 : 4586296513 : i.bb = bb;
171 : :
172 : 2297051010 : 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 : 5313 : gsi_end_bb (basic_block bb)
198 : : {
199 : 5313 : gimple_stmt_iterator i;
200 : 5313 : gimple_seq *seq;
201 : :
202 : 5315 : seq = bb_seq_addr (bb);
203 : 5313 : i.ptr = NULL;
204 : 5313 : i.seq = seq;
205 : 5313 : i.bb = bb;
206 : :
207 : 5313 : return i;
208 : : }
209 : :
210 : : /* Return true if I is at the end of its sequence. */
211 : :
212 : : inline bool
213 : 12845368584 : gsi_end_p (gimple_stmt_iterator i)
214 : : {
215 : 11863500606 : 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 : 547680432 : gsi_one_before_end_p (gimple_stmt_iterator i)
222 : : {
223 : 547680243 : return i.ptr != NULL && i.ptr->next == NULL;
224 : : }
225 : :
226 : : /* Advance the iterator to the next gimple statement. */
227 : :
228 : : inline void
229 : 78944905451 : gsi_next (gimple_stmt_iterator *i)
230 : : {
231 : 23272492074 : i->ptr = i->ptr->next;
232 : 76369011530 : }
233 : :
234 : : /* Advance the iterator to the previous gimple statement. */
235 : :
236 : : inline void
237 : 3279368379 : gsi_prev (gimple_stmt_iterator *i)
238 : : {
239 : 3279368379 : gimple *prev = i->ptr->prev;
240 : 2673882077 : if (prev->next)
241 : 1322546176 : i->ptr = prev;
242 : : else
243 : 369421437 : i->ptr = NULL;
244 : : }
245 : :
246 : : /* Return the current stmt. */
247 : :
248 : : inline gimple *
249 : 8157676411 : gsi_stmt (gimple_stmt_iterator i)
250 : : {
251 : 7713920507 : 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 : 248664866 : gsi_after_labels (basic_block bb)
259 : : {
260 : 248664866 : gimple_stmt_iterator gsi = gsi_start_bb (bb);
261 : :
262 : 263292340 : for (; !gsi_end_p (gsi); )
263 : : {
264 : 216531731 : if (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL)
265 : 14627474 : gsi_next (&gsi);
266 : : else
267 : : break;
268 : : }
269 : :
270 : 248664866 : 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 : 813746861 : gsi_next_nondebug (gimple_stmt_iterator *i)
296 : : {
297 : 1573328991 : do
298 : : {
299 : 1573328991 : gsi_next (i);
300 : : }
301 : 2387075852 : while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
302 : 813746861 : }
303 : :
304 : : /* Advance the iterator to the previous non-debug gimple statement. */
305 : :
306 : : inline void
307 : 189944760 : gsi_prev_nondebug (gimple_stmt_iterator *i)
308 : : {
309 : 657589633 : do
310 : : {
311 : 657589633 : gsi_prev (i);
312 : : }
313 : 847534393 : while (!gsi_end_p (*i) && is_gimple_debug (gsi_stmt (*i)));
314 : 189944760 : }
315 : :
316 : : /* Return a new iterator pointing to the first non-debug statement in
317 : : SEQ. */
318 : :
319 : : inline gimple_stmt_iterator
320 : : gsi_start_nondebug (gimple_seq seq)
321 : : {
322 : : gimple_stmt_iterator gsi = gsi_start (seq);
323 : : if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
324 : : gsi_next_nondebug (&gsi);
325 : :
326 : : 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 : 135245418 : gsi_start_nondebug_bb (basic_block bb)
334 : : {
335 : 135245418 : gimple_stmt_iterator i = gsi_start_bb (bb);
336 : :
337 : 135245418 : if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
338 : 28740175 : gsi_next_nondebug (&i);
339 : :
340 : 135245418 : 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 : 53093878 : gsi_start_nondebug_after_labels_bb (basic_block bb)
348 : : {
349 : 53093878 : gimple_stmt_iterator i = gsi_after_labels (bb);
350 : :
351 : 53093878 : if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
352 : 12063521 : gsi_next_nondebug (&i);
353 : :
354 : 53093878 : 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 : 2509894349 : gsi_last_nondebug_bb (basic_block bb)
362 : : {
363 : 2509894349 : gimple_stmt_iterator i = gsi_last_bb (bb);
364 : :
365 : 2509894349 : if (!gsi_end_p (i) && is_gimple_debug (gsi_stmt (i)))
366 : 144714714 : gsi_prev_nondebug (&i);
367 : :
368 : 2509894349 : return i;
369 : : }
370 : :
371 : : /* Return true if I is followed only by debug statements in its
372 : : sequence. */
373 : :
374 : : inline bool
375 : 499918 : gsi_one_nondebug_before_end_p (gimple_stmt_iterator i)
376 : : {
377 : 499918 : if (gsi_one_before_end_p (i))
378 : 473126 : return true;
379 : 26792 : if (gsi_end_p (i))
380 : : return false;
381 : 26603 : gsi_next_nondebug (&i);
382 : 26603 : 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 : 2277355 : gsi_next_nonvirtual_phi (gphi_iterator *i)
390 : : {
391 : 2597850 : do
392 : : {
393 : 2597850 : gsi_next (i);
394 : : }
395 : 4129574 : while (!gsi_end_p (*i) && virtual_operand_p (gimple_phi_result (i->phi ())));
396 : 2277355 : }
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 : 7691149 : gsi_start_nonvirtual_phis (basic_block bb)
403 : : {
404 : 7691149 : gphi_iterator i = gsi_start_phis (bb);
405 : :
406 : 12250143 : if (!gsi_end_p (i) && virtual_operand_p (gimple_phi_result (i.phi ())))
407 : 1277322 : gsi_next_nonvirtual_phi (&i);
408 : :
409 : 7691149 : return i;
410 : : }
411 : :
412 : : /* Return the basic block associated with this iterator. */
413 : :
414 : : inline basic_block
415 : 391148759 : gsi_bb (gimple_stmt_iterator i)
416 : : {
417 : 391146219 : return i.bb;
418 : : }
419 : :
420 : : /* Return the sequence associated with this iterator. */
421 : :
422 : : inline gimple_seq
423 : 801588 : gsi_seq (gimple_stmt_iterator i)
424 : : {
425 : 801588 : return *i.seq;
426 : : }
427 : :
428 : : /* Determine whether SEQ is a nondebug singleton. */
429 : :
430 : : inline bool
431 : 699 : gimple_seq_nondebug_singleton_p (gimple_seq seq)
432 : : {
433 : 699 : gimple_stmt_iterator gsi;
434 : :
435 : : /* Find a nondebug gimple. */
436 : 699 : gsi.ptr = gimple_seq_first (seq);
437 : 699 : gsi.seq = &seq;
438 : 699 : gsi.bb = NULL;
439 : 699 : while (!gsi_end_p (gsi)
440 : 699 : && is_gimple_debug (gsi_stmt (gsi)))
441 : 0 : gsi_next (&gsi);
442 : :
443 : : /* No nondebug gimple found, not a singleton. */
444 : 699 : if (gsi_end_p (gsi))
445 : : return false;
446 : :
447 : : /* Find a next nondebug gimple. */
448 : 699 : gsi_next (&gsi);
449 : 699 : while (!gsi_end_p (gsi)
450 : 699 : && is_gimple_debug (gsi_stmt (gsi)))
451 : 0 : gsi_next (&gsi);
452 : :
453 : : /* Only a singleton if there's no next nondebug gimple. */
454 : 699 : return gsi_end_p (gsi);
455 : : }
456 : :
457 : : #endif /* GCC_GIMPLE_ITERATOR_H */
|