### 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.