Sequence iterators (GNU Compiler Collection (GCC) Internals)

### 12.10 Sequence iterators ¶

Sequence iterators are convenience constructs for iterating through statements in a sequence. Given a sequence `SEQ`, here is a typical use of gimple sequence iterators:

    gimple_stmt_iterator gsi;

    for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi))
      {
        gimple g = gsi_stmt (gsi);
        /* Do something with gimple statement G.  */
      }

Backward iterations are possible:

            for (gsi = gsi_last (seq); !gsi_end_p (gsi); gsi_prev (&gsi))

Forward and backward iterations on basic blocks are possible with `gsi_start_bb` and `gsi_last_bb`.

In the documentation below we sometimes refer to enum `gsi_iterator_update`. The valid options for this enumeration are:

- `GSI_NEW_STMT` Only valid when a single statement is added. Move the iterator to it.
- `GSI_SAME_STMT` Leave the iterator at the same statement.
- `GSI_CONTINUE_LINKING` Move iterator to whatever position is suitable for linking other statements in the same direction.

Below is a list of the functions used to manipulate and use statement iterators.

GIMPLE function: `gimple_stmt_iterator` gsi_start `(gimple_seq seq)` ¶

  Return a new iterator pointing to the sequence `SEQ`’s first statement. If `SEQ` is empty, the iterator’s basic block is `NULL`. Use `gsi_start_bb` instead when the iterator needs to always have the correct basic block set.

GIMPLE function: `gimple_stmt_iterator` gsi_start_bb `(basic_block bb)` ¶

  Return a new iterator pointing to the first statement in basic block `BB`.

GIMPLE function: `gimple_stmt_iterator` gsi_last `(gimple_seq seq)` ¶

  Return a new iterator initially pointing to the last statement of sequence `SEQ`. If `SEQ` is empty, the iterator’s basic block is `NULL`. Use `gsi_last_bb` instead when the iterator needs to always have the correct basic block set.

GIMPLE function: `gimple_stmt_iterator` gsi_last_bb `(basic_block bb)` ¶

  Return a new iterator pointing to the last statement in basic block `BB`.

GIMPLE function: `bool` gsi_end_p `(gimple_stmt_iterator i)` ¶

  Return `TRUE` if at the end of `I`.

GIMPLE function: `bool` gsi_one_before_end_p `(gimple_stmt_iterator i)` ¶

  Return `TRUE` if we’re one statement before the end of `I`.

GIMPLE function: `void` gsi_next `(gimple_stmt_iterator *i)` ¶

  Advance the iterator to the next gimple statement.

GIMPLE function: `void` gsi_prev `(gimple_stmt_iterator *i)` ¶

  Advance the iterator to the previous gimple statement.

GIMPLE function: `gimple` gsi_stmt `(gimple_stmt_iterator i)` ¶

  Return the current stmt.

GIMPLE function: `gimple_stmt_iterator` gsi_after_labels `(basic_block bb)` ¶

  Return a block statement iterator that points to the first non-label statement in block `BB`.

GIMPLE function: `gimple *` gsi_stmt_ptr `(gimple_stmt_iterator *i)` ¶

  Return a pointer to the current stmt.

GIMPLE function: `basic_block` gsi_bb `(gimple_stmt_iterator i)` ¶

  Return the basic block associated with this iterator.

GIMPLE function: `gimple_seq` gsi_seq `(gimple_stmt_iterator i)` ¶

  Return the sequence associated with this iterator.

GIMPLE function: `void` gsi_remove `(gimple_stmt_iterator *i, bool remove_eh_info)` ¶

  Remove the current stmt from the sequence. The iterator is updated to point to the next statement. When `REMOVE_EH_INFO` is true we remove the statement pointed to by iterator `I` from the `EH` tables. Otherwise we do not modify the `EH` tables. Generally, `REMOVE_EH_INFO` should be true when the statement is going to be removed from the `IL` and not reinserted elsewhere.

GIMPLE function: `void` gsi_link_seq_before `(gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode)` ¶

  Links the sequence of statements `SEQ` before the statement pointed by iterator `I`. `MODE` indicates what to do with the iterator after insertion (see `enum gsi_iterator_update` above).

GIMPLE function: `void` gsi_link_before `(gimple_stmt_iterator *i, gimple g, enum gsi_iterator_update mode)` ¶

  Links statement `G` before the statement pointed-to by iterator `I`. Updates iterator `I` according to `MODE`.

GIMPLE function: `void` gsi_link_seq_after `(gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode)` ¶

  Links sequence `SEQ` after the statement pointed-to by iterator `I`. `MODE` is as in `gsi_insert_after`.

GIMPLE function: `void` gsi_link_after `(gimple_stmt_iterator *i, gimple g, enum gsi_iterator_update mode)` ¶

  Links statement `G` after the statement pointed-to by iterator `I`. `MODE` is as in `gsi_insert_after`.

GIMPLE function: `gimple_seq` gsi_split_seq_after `(gimple_stmt_iterator i)` ¶

  Move all statements in the sequence after `I` to a new sequence. Return this new sequence.

GIMPLE function: `gimple_seq` gsi_split_seq_before `(gimple_stmt_iterator *i)` ¶

  Move all statements in the sequence before `I` to a new sequence. Return this new sequence.

GIMPLE function: `void` gsi_replace `(gimple_stmt_iterator *i, gimple stmt, bool update_eh_info)` ¶

  Replace the statement pointed-to by `I` to `STMT`. If `UPDATE_EH_INFO` is true, the exception handling information of the original statement is moved to the new statement.

GIMPLE function: `void` gsi_insert_before `(gimple_stmt_iterator *i, gimple stmt, enum gsi_iterator_update mode)` ¶

  Insert statement `STMT` before the statement pointed-to by iterator `I`, update `STMT`’s basic block and scan it for new operands. `MODE` specifies how to update iterator `I` after insertion (see enum `gsi_iterator_update`).

GIMPLE function: `void` gsi_insert_seq_before `(gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode)` ¶

  Like `gsi_insert_before`, but for all the statements in `SEQ`.

GIMPLE function: `void` gsi_insert_after `(gimple_stmt_iterator *i, gimple stmt, enum gsi_iterator_update mode)` ¶

  Insert statement `STMT` after the statement pointed-to by iterator `I`, update `STMT`’s basic block and scan it for new operands. `MODE` specifies how to update iterator `I` after insertion (see enum `gsi_iterator_update`).

GIMPLE function: `void` gsi_insert_seq_after `(gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode)` ¶

  Like `gsi_insert_after`, but for all the statements in `SEQ`.

GIMPLE function: `gimple_stmt_iterator` gsi_for_stmt `(gimple stmt)` ¶

  Finds iterator for `STMT`.

GIMPLE function: `void` gsi_move_after `(gimple_stmt_iterator *from, gimple_stmt_iterator *to)` ¶

  Move the statement at `FROM` so it comes right after the statement at `TO`.

GIMPLE function: `void` gsi_move_before `(gimple_stmt_iterator *from, gimple_stmt_iterator *to)` ¶

  Move the statement at `FROM` so it comes right before the statement at `TO`.

GIMPLE function: `void` gsi_move_to_bb_end `(gimple_stmt_iterator *from, basic_block bb)` ¶

  Move the statement at `FROM` to the end of basic block `BB`.

GIMPLE function: `void` gsi_insert_on_edge `(edge e, gimple stmt)` ¶

  Add `STMT` to the pending list of edge `E`. No actual insertion is made until a call to `gsi_commit_edge_inserts`() is made.

GIMPLE function: `void` gsi_insert_seq_on_edge `(edge e, gimple_seq seq)` ¶

  Add the sequence of statements in `SEQ` to the pending list of edge `E`. No actual insertion is made until a call to `gsi_commit_edge_inserts`() is made.

GIMPLE function: `basic_block` gsi_insert_on_edge_immediate `(edge e, gimple stmt)` ¶

  Similar to `gsi_insert_on_edge`+`gsi_commit_edge_inserts`. If a new block has to be created, it is returned.

GIMPLE function: `void` gsi_commit_one_edge_insert `(edge e, basic_block *new_bb)` ¶

  Commit insertions pending at edge `E`. If a new block is created, set `NEW_BB` to this block, otherwise set it to `NULL`.

GIMPLE function: `void` gsi_commit_edge_inserts `(void)` ¶

  This routine will commit all pending edge insertions, creating any new basic blocks which are necessary.