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