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