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_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_stmt_iterator gsi_start_bb(basic_block bb)#

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

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_stmt_iterator gsi_last_bb(basic_block bb)#

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

bool gsi_end_p(gimple_stmt_iterator i)#

Return TRUE if at the end of I.

bool gsi_one_before_end_p(gimple_stmt_iterator i)#

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

void gsi_next(gimple_stmt_iterator *i)#

Advance the iterator to the next gimple statement.

void gsi_prev(gimple_stmt_iterator *i)#

Advance the iterator to the previous gimple statement.

gimple gsi_stmt(gimple_stmt_iterator i)#

Return the current stmt.

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 *gsi_stmt_ptr(gimple_stmt_iterator *i)#

Return a pointer to the current stmt.

basic_block gsi_bb(gimple_stmt_iterator i)#

Return the basic block associated with this iterator.

gimple_seq gsi_seq(gimple_stmt_iterator i)#

Return the sequence associated with this iterator.

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.

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

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

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

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

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

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.

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

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.

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

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_stmt_iterator gsi_for_stmt(gimple stmt)#

Finds iterator for STMT.

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.

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.

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.

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.

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.

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.

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.

void gsi_commit_edge_inserts(void)#

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