gimple_seq gsi_split_seq_before (gimple_stmt_iterator *i) { gimple_seq_node cur, prev; gimple_seq old_seq, new_seq; cur = i->ptr; /* How can we possibly split after the end? */ gcc_assert (cur); prev = cur->prev; old_seq = i->seq; new_seq = gimple_seq_alloc (); i->seq = new_seq; /* Set the limits on NEW_SEQ. */ gimple_seq_set_first (new_seq, cur); gimple_seq_set_last (new_seq, gimple_seq_last (old_seq)); /* Cut OLD_SEQ before I. */ gimple_seq_set_last (old_seq, prev); cur->prev = NULL; if (prev) prev->next = NULL; else gimple_seq_set_first (old_seq, NULL); return new_seq; }
void gsi_split_seq_before (gimple_stmt_iterator *i, gimple_seq *pnew_seq) { gimple_seq_node cur, prev; gimple_seq old_seq; cur = i->ptr; /* How can we possibly split after the end? */ gcc_assert (cur); prev = cur->prev; old_seq = *i->seq; if (!prev->next) *i->seq = NULL; i->seq = pnew_seq; /* Set the limits on NEW_SEQ. */ gimple_seq_set_first (pnew_seq, cur); gimple_seq_set_last (pnew_seq, gimple_seq_last (old_seq)); /* Cut OLD_SEQ before I. */ gimple_seq_set_last (&old_seq, prev); if (prev->next) prev->next = NULL; }
static void gsi_insert_seq_nodes_after (gimple_stmt_iterator *i, gimple_seq_node first, gimple_seq_node last, enum gsi_iterator_update m) { basic_block bb; gimple_seq_node cur = i->ptr; gcc_assert (!cur || cur->prev); /* If the iterator is inside a basic block, we need to update the basic block information for all the nodes between FIRST and LAST. */ if ((bb = gsi_bb (*i)) != NULL) update_bb_for_stmts (first, last, bb); /* Link SEQ after CUR. */ if (cur) { last->next = cur->next; if (last->next) { last->next->prev = last; } else gimple_seq_set_last (i->seq, last); first->prev = cur; cur->next = first; } else { gcc_assert (!gimple_seq_last (*i->seq)); last->next = NULL; gimple_seq_set_first (i->seq, first); gimple_seq_set_last (i->seq, last); } /* Update the iterator, if requested. */ switch (m) { case GSI_NEW_STMT: i->ptr = first; break; case GSI_CONTINUE_LINKING: i->ptr = last; break; case GSI_SAME_STMT: gcc_assert (cur); break; default: gcc_unreachable (); } }
void gsi_insert_seq_after_without_update (gimple_stmt_iterator *i, gimple_seq seq, enum gsi_iterator_update mode) { gimple_seq_node first, last; if (seq == NULL) return; /* Don't allow inserting a sequence into itself. */ gcc_assert (seq != i->seq); first = gimple_seq_first (seq); last = gimple_seq_last (seq); gimple_seq_set_first (seq, NULL); gimple_seq_set_last (seq, NULL); gimple_seq_free (seq); /* Empty sequences need no work. */ if (!first || !last) { gcc_assert (first == last); return; } gsi_insert_seq_nodes_after (i, first, last, mode); }
static void gsi_insert_seq_nodes_before (gimple_stmt_iterator *i, gimple_seq_node first, gimple_seq_node last, enum gsi_iterator_update mode) { basic_block bb; gimple_seq_node cur = i->ptr; gcc_assert (!cur || cur->prev); if ((bb = gsi_bb (*i)) != NULL) update_bb_for_stmts (first, last, bb); /* Link SEQ before CUR in the sequence. */ if (cur) { first->prev = cur->prev; if (first->prev->next) first->prev->next = first; else gimple_seq_set_first (i->seq, first); last->next = cur; cur->prev = last; } else { gimple_seq_node itlast = gimple_seq_last (*i->seq); /* If CUR is NULL, we link at the end of the sequence (this case happens when gsi_after_labels is called for a basic block that contains only labels, so it returns an iterator after the end of the block, and we need to insert before it; it might be cleaner to add a flag to the iterator saying whether we are at the start or end of the list). */ last->next = NULL; if (itlast) { first->prev = itlast; itlast->next = first; } else gimple_seq_set_first (i->seq, first); gimple_seq_set_last (i->seq, last); } /* Update the iterator, if requested. */ switch (mode) { case GSI_NEW_STMT: case GSI_CONTINUE_LINKING: i->ptr = first; break; case GSI_SAME_STMT: break; default: gcc_unreachable (); } }
gimple_seq gsi_split_seq_after (gimple_stmt_iterator i) { gimple_seq_node cur, next; gimple_seq *pold_seq, new_seq; cur = i.ptr; /* How can we possibly split after the end, or before the beginning? */ gcc_assert (cur && cur->next); next = cur->next; pold_seq = i.seq; gimple_seq_set_first (&new_seq, next); gimple_seq_set_last (&new_seq, gimple_seq_last (*pold_seq)); gimple_seq_set_last (pold_seq, cur); cur->next = NULL; return new_seq; }
bool gsi_remove (gimple_stmt_iterator *i, bool remove_permanently) { gimple_seq_node cur, next, prev; gimple *stmt = gsi_stmt (*i); bool require_eh_edge_purge = false; if (gimple_code (stmt) != GIMPLE_PHI) insert_debug_temps_for_defs (i); /* Free all the data flow information for STMT. */ gimple_set_bb (stmt, NULL); delink_stmt_imm_use (stmt); gimple_set_modified (stmt, true); if (remove_permanently) { require_eh_edge_purge = remove_stmt_from_eh_lp (stmt); gimple_remove_stmt_histograms (cfun, stmt); } /* Update the iterator and re-wire the links in I->SEQ. */ cur = i->ptr; next = cur->next; prev = cur->prev; /* See gsi_set_stmt for why we don't reset prev/next of STMT. */ if (next) /* Cur is not last. */ next->prev = prev; else if (prev->next) /* Cur is last but not first. */ gimple_seq_set_last (i->seq, prev); if (prev->next) /* Cur is not first. */ prev->next = next; else /* Cur is first. */ *i->seq = next; i->ptr = next; return require_eh_edge_purge; }
void gsi_set_stmt (gimple_stmt_iterator *gsi, gimple *stmt) { gimple *orig_stmt = gsi_stmt (*gsi); gimple *prev, *next; stmt->next = next = orig_stmt->next; stmt->prev = prev = orig_stmt->prev; /* Note how we don't clear next/prev of orig_stmt. This is so that copies of *GSI our callers might still hold (to orig_stmt) can be advanced as if they too were replaced. */ if (prev->next) prev->next = stmt; else gimple_seq_set_first (gsi->seq, stmt); if (next) next->prev = stmt; else gimple_seq_set_last (gsi->seq, stmt); gsi->ptr = stmt; }