]>
Commit | Line | Data |
---|---|---|
c63539ff ML |
1 | .. |
2 | Copyright 1988-2022 Free Software Foundation, Inc. | |
3 | This is part of the GCC manual. | |
4 | For copying conditions, see the copyright.rst file. | |
5 | ||
6 | .. index:: Sequence iterators | |
7 | ||
8 | .. _sequence-iterators: | |
9 | ||
10 | Sequence iterators | |
11 | ****************** | |
12 | ||
13 | Sequence iterators are convenience constructs for iterating | |
14 | through statements in a sequence. Given a sequence ``SEQ``, here is | |
15 | a typical use of gimple sequence iterators: | |
16 | ||
17 | .. code-block:: c++ | |
18 | ||
19 | gimple_stmt_iterator gsi; | |
20 | ||
21 | for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi)) | |
22 | { | |
23 | gimple g = gsi_stmt (gsi); | |
24 | /* Do something with gimple statement G. */ | |
25 | } | |
26 | ||
27 | Backward iterations are possible: | |
28 | ||
29 | .. code-block:: c++ | |
30 | ||
31 | for (gsi = gsi_last (seq); !gsi_end_p (gsi); gsi_prev (&gsi)) | |
32 | ||
33 | Forward and backward iterations on basic blocks are possible with | |
34 | ``gsi_start_bb`` and ``gsi_last_bb``. | |
35 | ||
36 | In the documentation below we sometimes refer to enum | |
37 | ``gsi_iterator_update``. The valid options for this enumeration are: | |
38 | ||
39 | * ``GSI_NEW_STMT`` | |
40 | Only valid when a single statement is added. Move the iterator to it. | |
41 | ||
42 | * ``GSI_SAME_STMT`` | |
43 | Leave the iterator at the same statement. | |
44 | ||
45 | * ``GSI_CONTINUE_LINKING`` | |
46 | Move iterator to whatever position is suitable for linking other | |
47 | statements in the same direction. | |
48 | ||
49 | Below is a list of the functions used to manipulate and use | |
50 | statement iterators. | |
51 | ||
52 | .. function:: gimple_stmt_iterator gsi_start (gimple_seq seq) | |
53 | ||
54 | Return a new iterator pointing to the sequence ``SEQ`` 's first | |
55 | statement. If ``SEQ`` is empty, the iterator's basic block is ``NULL``. | |
56 | Use ``gsi_start_bb`` instead when the iterator needs to always have | |
57 | the correct basic block set. | |
58 | ||
59 | .. function:: gimple_stmt_iterator gsi_start_bb (basic_block bb) | |
60 | ||
61 | Return a new iterator pointing to the first statement in basic | |
62 | block ``BB``. | |
63 | ||
64 | .. function:: gimple_stmt_iterator gsi_last (gimple_seq seq) | |
65 | ||
66 | Return a new iterator initially pointing to the last statement of | |
67 | sequence ``SEQ``. If ``SEQ`` is empty, the iterator's basic block is | |
68 | ``NULL``. Use ``gsi_last_bb`` instead when the iterator needs to always | |
69 | have the correct basic block set. | |
70 | ||
71 | .. function:: gimple_stmt_iterator gsi_last_bb (basic_block bb) | |
72 | ||
73 | Return a new iterator pointing to the last statement in basic | |
74 | block ``BB``. | |
75 | ||
76 | .. function:: bool gsi_end_p (gimple_stmt_iterator i) | |
77 | ||
78 | Return ``TRUE`` if at the end of ``I``. | |
79 | ||
80 | .. function:: bool gsi_one_before_end_p (gimple_stmt_iterator i) | |
81 | ||
82 | Return ``TRUE`` if we're one statement before the end of ``I``. | |
83 | ||
84 | .. function:: void gsi_next (gimple_stmt_iterator *i) | |
85 | ||
86 | Advance the iterator to the next gimple statement. | |
87 | ||
88 | .. function:: void gsi_prev (gimple_stmt_iterator *i) | |
89 | ||
90 | Advance the iterator to the previous gimple statement. | |
91 | ||
92 | .. function:: gimple gsi_stmt (gimple_stmt_iterator i) | |
93 | ||
94 | Return the current stmt. | |
95 | ||
96 | .. function:: gimple_stmt_iterator gsi_after_labels (basic_block bb) | |
97 | ||
98 | Return a block statement iterator that points to the first | |
99 | non-label statement in block ``BB``. | |
100 | ||
101 | .. function:: gimple * gsi_stmt_ptr (gimple_stmt_iterator *i) | |
102 | ||
103 | Return a pointer to the current stmt. | |
104 | ||
105 | .. function:: basic_block gsi_bb (gimple_stmt_iterator i) | |
106 | ||
107 | Return the basic block associated with this iterator. | |
108 | ||
109 | .. function:: gimple_seq gsi_seq (gimple_stmt_iterator i) | |
110 | ||
111 | Return the sequence associated with this iterator. | |
112 | ||
113 | .. function:: void gsi_remove (gimple_stmt_iterator *i, bool remove_eh_info) | |
114 | ||
115 | Remove the current stmt from the sequence. The iterator is | |
116 | updated to point to the next statement. When ``REMOVE_EH_INFO`` is | |
117 | true we remove the statement pointed to by iterator ``I`` from the ``EH`` | |
118 | tables. Otherwise we do not modify the ``EH`` tables. Generally, | |
119 | ``REMOVE_EH_INFO`` should be true when the statement is going to be | |
120 | removed from the ``IL`` and not reinserted elsewhere. | |
121 | ||
122 | .. function:: void gsi_link_seq_before (gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode) | |
123 | ||
124 | Links the sequence of statements ``SEQ`` before the statement pointed | |
125 | by iterator ``I``. ``MODE`` indicates what to do with the iterator | |
126 | after insertion (see ``enum gsi_iterator_update`` above). | |
127 | ||
128 | .. function:: void gsi_link_before (gimple_stmt_iterator *i, gimple g, enum gsi_iterator_update mode) | |
129 | ||
130 | Links statement ``G`` before the statement pointed-to by iterator ``I``. | |
131 | Updates iterator ``I`` according to ``MODE``. | |
132 | ||
133 | .. function:: void gsi_link_seq_after (gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode) | |
134 | ||
135 | Links sequence ``SEQ`` after the statement pointed-to by iterator ``I``. | |
136 | ``MODE`` is as in ``gsi_insert_after``. | |
137 | ||
138 | .. function:: void gsi_link_after (gimple_stmt_iterator *i, gimple g, enum gsi_iterator_update mode) | |
139 | ||
140 | Links statement ``G`` after the statement pointed-to by iterator ``I``. | |
141 | ``MODE`` is as in ``gsi_insert_after``. | |
142 | ||
143 | .. function:: gimple_seq gsi_split_seq_after (gimple_stmt_iterator i) | |
144 | ||
145 | Move all statements in the sequence after ``I`` to a new sequence. | |
146 | Return this new sequence. | |
147 | ||
148 | .. function:: gimple_seq gsi_split_seq_before (gimple_stmt_iterator *i) | |
149 | ||
150 | Move all statements in the sequence before ``I`` to a new sequence. | |
151 | Return this new sequence. | |
152 | ||
153 | .. function:: void gsi_replace (gimple_stmt_iterator *i, gimple stmt, bool update_eh_info) | |
154 | ||
155 | Replace the statement pointed-to by ``I`` to ``STMT``. If ``UPDATE_EH_INFO`` | |
156 | is true, the exception handling information of the original | |
157 | statement is moved to the new statement. | |
158 | ||
159 | .. function:: void gsi_insert_before (gimple_stmt_iterator *i, gimple stmt, enum gsi_iterator_update mode) | |
160 | ||
161 | Insert statement ``STMT`` before the statement pointed-to by iterator | |
162 | ``I``, update ``STMT`` 's basic block and scan it for new operands. ``MODE`` | |
163 | specifies how to update iterator ``I`` after insertion (see enum | |
164 | ``gsi_iterator_update``). | |
165 | ||
166 | .. function:: void gsi_insert_seq_before (gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode) | |
167 | ||
168 | Like ``gsi_insert_before``, but for all the statements in ``SEQ``. | |
169 | ||
170 | .. function:: void gsi_insert_after (gimple_stmt_iterator *i, gimple stmt, enum gsi_iterator_update mode) | |
171 | ||
172 | Insert statement ``STMT`` after the statement pointed-to by iterator | |
173 | ``I``, update ``STMT`` 's basic block and scan it for new operands. ``MODE`` | |
174 | specifies how to update iterator ``I`` after insertion (see enum | |
175 | ``gsi_iterator_update``). | |
176 | ||
177 | .. function:: void gsi_insert_seq_after (gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode) | |
178 | ||
179 | Like ``gsi_insert_after``, but for all the statements in ``SEQ``. | |
180 | ||
181 | .. function:: gimple_stmt_iterator gsi_for_stmt (gimple stmt) | |
182 | ||
183 | Finds iterator for ``STMT``. | |
184 | ||
185 | .. function:: void gsi_move_after (gimple_stmt_iterator *from, gimple_stmt_iterator *to) | |
186 | ||
187 | Move the statement at ``FROM`` so it comes right after the statement | |
188 | at ``TO``. | |
189 | ||
190 | .. function:: void gsi_move_before (gimple_stmt_iterator *from, gimple_stmt_iterator *to) | |
191 | ||
192 | Move the statement at ``FROM`` so it comes right before the statement | |
193 | at ``TO``. | |
194 | ||
195 | .. function:: void gsi_move_to_bb_end (gimple_stmt_iterator *from, basic_block bb) | |
196 | ||
197 | Move the statement at ``FROM`` to the end of basic block ``BB``. | |
198 | ||
199 | .. function:: void gsi_insert_on_edge (edge e, gimple stmt) | |
200 | ||
201 | Add ``STMT`` to the pending list of edge ``E``. No actual insertion is | |
202 | made until a call to ``gsi_commit_edge_inserts`` () is made. | |
203 | ||
204 | .. function:: void gsi_insert_seq_on_edge (edge e, gimple_seq seq) | |
205 | ||
206 | Add the sequence of statements in ``SEQ`` to the pending list of edge | |
207 | ``E``. No actual insertion is made until a call to | |
208 | ``gsi_commit_edge_inserts`` () is made. | |
209 | ||
210 | .. function:: basic_block gsi_insert_on_edge_immediate (edge e, gimple stmt) | |
211 | ||
212 | Similar to ``gsi_insert_on_edge`` + ``gsi_commit_edge_inserts``. If a new | |
213 | block has to be created, it is returned. | |
214 | ||
215 | .. function:: void gsi_commit_one_edge_insert (edge e, basic_block *new_bb) | |
216 | ||
217 | Commit insertions pending at edge ``E``. If a new block is created, | |
218 | set ``NEW_BB`` to this block, otherwise set it to ``NULL``. | |
219 | ||
220 | .. function:: void gsi_commit_edge_inserts (void) | |
221 | ||
222 | This routine will commit all pending edge insertions, creating | |
3ed1b4ce | 223 | any new basic blocks which are necessary. |