aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-iterator.c
diff options
context:
space:
mode:
authorMichael Matz <matz@gcc.gnu.org>2012-05-02 16:41:48 +0000
committerMichael Matz <matz@gcc.gnu.org>2012-05-02 16:41:48 +0000
commit355a76735231beec33c140af2d9e6adca486225c (patch)
treea909112c3b26051d56924ebe9435b84f207b2091 /gcc/gimple-iterator.c
parent63dc7fbee074066f132d5092e53e6d62757bb922 (diff)
downloadgcc-355a76735231beec33c140af2d9e6adca486225c.zip
gcc-355a76735231beec33c140af2d9e6adca486225c.tar.gz
gcc-355a76735231beec33c140af2d9e6adca486225c.tar.bz2
coretypes.h (gimple_seq, [...]): Typedef as gimple.
* coretypes.h (gimple_seq, const_gimple_seq): Typedef as gimple. * gimple.h (struct gimple_seq_node_d, struct gimple_seq_d): Remove. (const_gimple_seq_node): Remove. (gimple_seq_node): Typedef as gimple. (struct gimple_statement_base): Add next and prev members, adjust all WORD markers in using structs. (union gimple_statement_d): Link via gsbase.next field for GC and PCH. (gimple_seq_first, gimple_seq_first_stmt, gimple_seq_last, gimple_seq_last_stmt): Adjust as gimple_seq, gimple_seq_node and gimple are the same. (gimple_seq_set_last, gimple_seq_set_first): Don't allocate gimple_seq, adjust. (gimple_init_singleton): New function. (gsi_start_1, gsi_last_1, gsi_end_p, gsi_one_before_end_p): Adjust. (gsi_next, gsi_prev): Adjust, handle prev cyclic list correctly. (gsi_stmt): Adjust. (gsi_stmt_ptr): Remove. (enum gimple_alloc_kind): Remove gimple_alloc_kind_seq member. * gimple-iterator.c (update_bb_for_stmts): Take last parameter again, adjust for above changes. (update_call_edge_frequencies): Adjust for above changes. (gsi_insert_seq_nodes_before): Rewrite for new data structure. (gsi_insert_seq_nodes_after): Ditto. (gsi_split_seq_after): Ditto. (gsi_set_stmt): Ditto. (gsi_split_seq_before): Ditto. (gsi_remove): Ditto. (gsi_insert_seq_before_without_update): Don't free sequence. (gsi_insert_seq_after_without_update): Ditto. (gsi_replace): Assert some more invariants. (gsi_insert_before_without_update, gsi_insert_after_without_update): Tidy. (gsi_for_stmt): Don't search for stmt. (gsi_insert_on_edge_immediate): Tidy. * gimple.c (gimple_alloc_k): Remove "sequences". (gimple_seq_cache): Remove. (gimple_alloc_stat): Make stmt a singleton sequence. (gimple_seq_alloc, gimple_seq_free): Remove. (gimple_assign_set_rhs_with_ops_1): Ensure new stmt is a singleton. (gimple_copy): Ditto. * gimplify.c (gimplify_cleanup_point_expr): Use gsi_set_stmt, create iterator from correct sequence. * tree-phinodes.c (make_phi_node): Make stmt a singleton. * gimple.h (gimple_stmt_iterator <seq>): Make it be pointer to gimple_seq. (gimple_seq_set_last, gimple_seq_set_first): Take pointer to sequence, lazily allocate it. (bb_seq_addr): New function. (gsi_start_1): Rename from gsi_start, but take pointer to sequence. (gsi_start): Macro to wrap gsi_start_1 taking pointer of argument. (gsi_none): New function. (gsi_start_bb): Adjust. (gsi_last_1): Rename from gsi_last, but take pointer to sequence. (gsi_last): Macro to wrap gsi_last_1 taking pointer of argument. (gsi_last_bb): Adjust. (gsi_seq): Adjust. * tree-flow-inline.h (phi_nodes_ptr): New function. * gimple-iterator.c (gsi_insert_seq_nodes_before): Adjust to datastructure and interface change. (gsi_insert_seq_before_without_update): Ditto. (gsi_insert_seq_nodes_after): Ditto. (gsi_insert_seq_after_without_update): Ditto. (gsi_split_seq_after): Ditto, don't use gimple_seq_alloc. (gsi_split_seq_before): Ditto. (gsi_start_phis): Adjust. * tree-vect-loop.c (vect_determine_vectorization_factor): Use gsi_none. (vect_transform_loop): Ditto. * gimple.c (gimple_seq_add_stmt, gimple_seq_add_seq, gimple_seq_copy): Don't use gimple_seq_alloc. * gimplify.c (gimple_seq_add_stmt_without_update): Ditto. (gimplify_seq_add_seq): Ditto. * lto-streamer-in.c (make_new_block): Ditto. * tree-cfg.c (create_bb): Ditto. * tree-sra.c (initialize_parameter_reductions): Ditto. * gimple.h (gimple_seq_first, gimple_seq_first_stmt, gimple_seq_last, gimple_seq_last_stmt, gimple_seq_set_last, gimple_seq_set_first, gimple_seq_empty_p, gimple_seq_alloc_with_stmt, bb_seq, set_bb_seq): Move down to after gimple_statement_d definition. * gimple-fold.c (gimplify_and_update_call_from_tree): Use gsi_replace_with_seq, instead of inserting itself. * gimple-iterator.c (gsi_replace_with_seq): New function. * tree-ssa-forwprop.c (forward_propagate_comparison): Take iterator instead of statement, advance it. (ssa_forward_propagate_and_combine): Adjust call to above. * tree-phinodes.c (add_phi_node_to_bb): Tidy, don't use gimple_seq_alloc. * omp-low.c (finalize_task_copyfn): Don't use gimple_seq_alloc. * tree-nested.c (walk_gimple_omp_for): Ditto. * trans-mem.c (lower_transaction): Ditto. * tree-eh.c (do_return_redirection): Ditto. (do_goto_redirection): Ditto. (lower_try_finally_switch): Ditto. * gimplify.c (gimplify_stmt): Ditto. (gimplify_scan_omp_clauses): Ditto. (gimplify_omp_for): Ditto. (gimplify_function_tree): Ditto. * gimple-fold.c (gimplify_and_update_call_from_tree): Ditto. * tree-mudflap.c (mf_decl_cache_locals): Ditto. (mf_build_check_statement_for): Ditto. (mx_register_decls): Ditto. * graphite-sese-to-poly.c (remove_invariant_phi): Ditto, and don't use itertors to append. (insert_stmts): Ditto. (insert_out_of_ssa_copy): Ditto. (insert_out_of_ssa_copy_on_edge): Ditto. * gimple.h (gimple_bind_body_ptr): New function. (gimple_bind_body): Use it. (gimple_catch_handler): Use gimple_catch_handler_ptr. (gimple_eh_filter_failure_ptr): New function. (gimple_eh_filter_failure): Use it. (gimple_eh_else_n_body_ptr): New function. (gimple_eh_else_n_body): Use it. (gimple_eh_else_e_body_ptr): New function. (gimple_eh_else_e_body): Use it. (gimple_try_eval_ptr): New function. (gimple_try_eval): Use it. (gimple_try_cleanup_ptr): New function. (gimple_try_cleanup): Use it. (gimple_wce_cleanup_ptr): New function. (gimple_wce_cleanup): Use it. (gimple_omp_body_ptr): New function. (gimple_omp_body): Use it. (gimple_omp_for_pre_body_ptr): New function. (gimple_omp_for_pre_body): Use it. (gimple_transaction_body_ptr): New function. (gimple_transaction_body): Use it. (gsi_split_seq_before): Adjust to return nothing and take pointer to sequence. (gsi_set_stmt): Declare. (gsi_replace_with_seq): Declare. (walk_gimple_seq_mod): Declare. * function.h (struct function <gimple_body>): Use typedef gimple_seq. * gimple-iterator.c (gsi_set_stmt): New function. (gsi_split_seq_before): Return new sequence via pointer argument. (gsi_replace): Use gsi_set_stmt. * tree-ssa-loop-im.c (move_computations_stmt): First remove then insert stmt. * tree-complex.c (update_complex_components_on_edge): Don't copy gsi. * tree-phinodes.c (resize_phi_node): Don't resize stmt in-place, return new stmt. (reserve_phi_args_for_new_edge): Change call to above, use gsi_set_stmt. * omp-low.c (lower_omp): Change prototype to take pointer to sequence. (lower_rec_input_clauses): Use gimple_seq_add_seq instead of iterators. Adjust call to lower_omp. (lower_lastprivate_clauses): Adjust call to lower_omp. (lower_reduction_clauses): Ditto. (expand_omp_taskreg): Nullify non-cfg body of child_fn. (lower_omp_sections): Don't explicitely count sequence length, nullify lowered bodies earlier, ensure stmts are part of only one sequence, adjust call to lower_omp. (lower_omp_single): Ensure stmts are part of only one sequence, adjust call to lower_omp. (lower_omp_master): Ditto. (lower_omp_ordered): Ditto. (lower_omp_critical): Ditto. (lower_omp_for): Ditto. (lower_omp_taskreg): Ditto, tidy. (lower_omp_1): Adjust calls to lower_omp. (execute_lower_omp): Ditto. (lower_omp): Adjust to take pointer to sequence. (diagnose_sb_2): Use walk_gimple_seq_mod. (diagnose_omp_structured_block_errors): Ditto and set possibly changed function body. * gimple-low.c (lower_function_body): Set function body after it stabilizes. (lower_sequence): Adjust to take pointer to sequence. (lower_omp_directive): Ensure stmt isn't put twice into the sequence, adjust call to lower_sequence. (lower_stmt): Adjust calls to lower_sequence. (lower_gimple_bind): Ditto. (gimple_try_catch_may_fallthru): Call gsi_start with lvalue. * tree-nested.c (walk_body): Take pointer to sequence, use walk_gimple_seq_mod. (walk_function): Adjust call to walk_body, set possibly changed body. (walk_gimple_omp_for): Adjust calls to walk_body. (convert_nonlocal_omp_clauses): Ditto. (convert_nonlocal_reference_stmt): Ditto. (convert_local_omp_clauses): Ditto. (convert_local_reference_stmt): Ditto. (convert_tramp_reference_stmt): Ditto. (convert_gimple_call): Ditto. (convert_nl_goto_reference): Use local iterator copy. * gimple.c (walk_gimple_seq_mod): Renamed from walk_gimple_seq, but taking pointer to sequence, ensure gsi_start is called with callers lvalue. (walk_gimple_seq): New wrapper around walk_gimple_seq_mod, asserting that the sequence head didn't change. (walk_gimple_stmt): Replace all calls to walk_gimple_seq with walk_gimple_seq_mod. * trans-mem.c (lower_transaction): Use walk_gimple_seq_mod. (execute_lower_tm): Ditto, and set possibly changed body. * tree-eh.c (lower_eh_constructs_1): Take pointer to sequence, call gsi_start with that lvalue. (replace_goto_queue_stmt_list): Ditto. (replace_goto_queue_1): Adjust calls to replace_goto_queue_stmt_list. (replace_goto_queue): Ditto. (lower_try_finally_nofallthru): Adjust calls to lower_eh_constructs_1. (lower_try_finally_onedest): Ditto. (lower_try_finally_copy): Ditto. (lower_try_finally_switch): Ditto. (lower_try_finally): Ditto. (lower_eh_filter): Ditto. (lower_eh_must_not_throw): Ditto. (lower_cleanup): Ditto. (lower_eh_constructs_2): Ditto. (lower_catch): Ditto, and ensure gsi_start is called with lvalue. (lower_eh_constructs): Adjust calls to lower_eh_constructs_1, and set possibly changed body. (optimize_double_finally): Call gsi_start with lvalue. * tree-cfg.c (make_blocks): Adjust call to gsi_split_seq_before. (gimple_split_block): Ditto. (gimple_merge_blocks): Use gsi_start_phis. (move_stmt_r): Use walk_gimple_seq_mod. * tree-ssa-dse.c (dse_enter_block): Use gsi_last_bb. * cgraphbuild.c (build_cgraph_edges): Use gsi_start_phis. (rebuild_cgraph_edges): Ditto. (cgraph_rebuild_references): Ditto. * ipa-prop.c (ipa_analyze_params_uses): Ditto. * tree-inline.c (copy_phis_for_bb): Ditto. * tree-ssa-dce.c: Ditto. * cgraphunit.c (cgraph_analyze_function): Use gimple_has_body_p. From-SVN: r187053
Diffstat (limited to 'gcc/gimple-iterator.c')
-rw-r--r--gcc/gimple-iterator.c228
1 files changed, 137 insertions, 91 deletions
diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c
index e387c16..dd78faa 100644
--- a/gcc/gimple-iterator.c
+++ b/gcc/gimple-iterator.c
@@ -57,12 +57,17 @@ update_modified_stmts (gimple_seq seq)
starting at FIRST and LAST. */
static void
-update_bb_for_stmts (gimple_seq_node first, basic_block bb)
+update_bb_for_stmts (gimple_seq_node first, gimple_seq_node last,
+ basic_block bb)
{
gimple_seq_node n;
- for (n = first; n; n = n->next)
- gimple_set_bb (n->stmt, bb);
+ for (n = first; n; n = n->gsbase.next)
+ {
+ gimple_set_bb (n, bb);
+ if (n == last)
+ break;
+ }
}
/* Set the frequencies for the cgraph_edges for each of the calls
@@ -75,8 +80,8 @@ update_call_edge_frequencies (gimple_seq_node first, basic_block bb)
int bb_freq = 0;
gimple_seq_node n;
- for (n = first; n ; n = n->next)
- if (is_gimple_call (n->stmt))
+ for (n = first; n ; n = n->gsbase.next)
+ if (is_gimple_call (n))
{
struct cgraph_edge *e;
@@ -89,7 +94,7 @@ update_call_edge_frequencies (gimple_seq_node first, basic_block bb)
(current_function_decl, bb));
}
- e = cgraph_edge (cfun_node, n->stmt);
+ e = cgraph_edge (cfun_node, n);
if (e != NULL)
e->frequency = bb_freq;
}
@@ -113,32 +118,37 @@ gsi_insert_seq_nodes_before (gimple_stmt_iterator *i,
basic_block bb;
gimple_seq_node cur = i->ptr;
+ gcc_assert (!cur || cur->gsbase.prev);
+
if ((bb = gsi_bb (*i)) != NULL)
- update_bb_for_stmts (first, bb);
+ update_bb_for_stmts (first, last, bb);
/* Link SEQ before CUR in the sequence. */
if (cur)
{
- first->prev = cur->prev;
- if (first->prev)
- first->prev->next = first;
+ first->gsbase.prev = cur->gsbase.prev;
+ if (first->gsbase.prev->gsbase.next)
+ first->gsbase.prev->gsbase.next = first;
else
gimple_seq_set_first (i->seq, first);
- last->next = cur;
- cur->prev = last;
+ last->gsbase.next = cur;
+ cur->gsbase.prev = last;
}
else
{
- gimple_seq_node itlast = gimple_seq_last (i->seq);
+ 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). */
- first->prev = itlast;
+ last->gsbase.next = NULL;
if (itlast)
- itlast->next = first;
+ {
+ first->gsbase.prev = itlast;
+ itlast->gsbase.next = first;
+ }
else
gimple_seq_set_first (i->seq, first);
gimple_seq_set_last (i->seq, last);
@@ -178,15 +188,11 @@ gsi_insert_seq_before_without_update (gimple_stmt_iterator *i, gimple_seq seq,
return;
/* Don't allow inserting a sequence into itself. */
- gcc_assert (seq != i->seq);
+ 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)
{
@@ -230,25 +236,30 @@ gsi_insert_seq_nodes_after (gimple_stmt_iterator *i,
basic_block bb;
gimple_seq_node cur = i->ptr;
+ gcc_assert (!cur || cur->gsbase.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, bb);
+ update_bb_for_stmts (first, last, bb);
/* Link SEQ after CUR. */
if (cur)
{
- last->next = cur->next;
- if (last->next)
- last->next->prev = last;
+ last->gsbase.next = cur->gsbase.next;
+ if (last->gsbase.next)
+ {
+ last->gsbase.next->gsbase.prev = last;
+ }
else
gimple_seq_set_last (i->seq, last);
- first->prev = cur;
- cur->next = first;
+ first->gsbase.prev = cur;
+ cur->gsbase.next = first;
}
else
{
- gcc_assert (!gimple_seq_last (i->seq));
+ gcc_assert (!gimple_seq_last (*i->seq));
+ last->gsbase.next = NULL;
gimple_seq_set_first (i->seq, first);
gimple_seq_set_last (i->seq, last);
}
@@ -289,15 +300,11 @@ gsi_insert_seq_after_without_update (gimple_stmt_iterator *i, gimple_seq seq,
return;
/* Don't allow inserting a sequence into itself. */
- gcc_assert (seq != i->seq);
+ 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)
{
@@ -329,59 +336,81 @@ gimple_seq
gsi_split_seq_after (gimple_stmt_iterator i)
{
gimple_seq_node cur, next;
- gimple_seq old_seq, new_seq;
+ 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;
+ gcc_assert (cur && cur->gsbase.next);
+ next = cur->gsbase.next;
- old_seq = i.seq;
- new_seq = gimple_seq_alloc ();
+ pold_seq = i.seq;
- gimple_seq_set_first (new_seq, next);
- gimple_seq_set_last (new_seq, gimple_seq_last (old_seq));
- gimple_seq_set_last (old_seq, cur);
- cur->next = NULL;
- next->prev = NULL;
+ 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->gsbase.next = NULL;
return new_seq;
}
+/* Set the statement to which GSI points to STMT. This only updates
+ the iterator and the gimple sequence, it doesn't do the bookkeeping
+ of gsi_replace. */
+
+void
+gsi_set_stmt (gimple_stmt_iterator *gsi, gimple stmt)
+{
+ gimple orig_stmt = gsi_stmt (*gsi);
+ gimple prev, next;
+
+ stmt->gsbase.next = next = orig_stmt->gsbase.next;
+ stmt->gsbase.prev = prev = orig_stmt->gsbase.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->gsbase.next)
+ prev->gsbase.next = stmt;
+ else
+ gimple_seq_set_first (gsi->seq, stmt);
+ if (next)
+ next->gsbase.prev = stmt;
+ else
+ gimple_seq_set_last (gsi->seq, stmt);
+
+ gsi->ptr = stmt;
+}
+
+
/* Move all statements in the sequence before I to a new sequence.
Return this new sequence. I is set to the head of the new list. */
-gimple_seq
-gsi_split_seq_before (gimple_stmt_iterator *i)
+void
+gsi_split_seq_before (gimple_stmt_iterator *i, gimple_seq *pnew_seq)
{
gimple_seq_node cur, prev;
- gimple_seq old_seq, new_seq;
+ gimple_seq old_seq;
cur = i->ptr;
/* How can we possibly split after the end? */
gcc_assert (cur);
- prev = cur->prev;
+ prev = cur->gsbase.prev;
- old_seq = i->seq;
- new_seq = gimple_seq_alloc ();
- i->seq = new_seq;
+ old_seq = *i->seq;
+ if (!prev->gsbase.next)
+ *i->seq = NULL;
+ i->seq = pnew_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));
+ 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);
- cur->prev = NULL;
- if (prev)
- prev->next = NULL;
- else
- gimple_seq_set_first (old_seq, NULL);
-
- return new_seq;
+ gimple_seq_set_last (&old_seq, prev);
+ if (prev->gsbase.next)
+ prev->gsbase.next = NULL;
}
@@ -416,12 +445,38 @@ gsi_replace (gimple_stmt_iterator *gsi, gimple stmt, bool update_eh_info)
gimple_remove_stmt_histograms (cfun, orig_stmt);
delink_stmt_imm_use (orig_stmt);
- *gsi_stmt_ptr (gsi) = stmt;
+ gsi_set_stmt (gsi, stmt);
gimple_set_modified (stmt, true);
update_modified_stmt (stmt);
}
+/* Replace the statement pointed-to by GSI with the sequence SEQ.
+ If UPDATE_EH_INFO is true, the exception handling information of
+ the original statement is moved to the last statement of the new
+ sequence. If the old statement is an assignment, then so must
+ be the last statement of the new sequence, and they must have the
+ same LHS. */
+
+void
+gsi_replace_with_seq (gimple_stmt_iterator *gsi, gimple_seq seq,
+ bool update_eh_info)
+{
+ gimple_stmt_iterator seqi;
+ gimple last;
+ if (gimple_seq_empty_p (seq))
+ {
+ gsi_remove (gsi, true);
+ return;
+ }
+ seqi = gsi_last (seq);
+ last = gsi_stmt (seqi);
+ gsi_remove (&seqi, false);
+ gsi_insert_seq_before (gsi, seq, GSI_SAME_STMT);
+ gsi_replace (gsi, last, update_eh_info);
+}
+
+
/* Insert statement STMT before the statement pointed-to by iterator I.
M specifies how to update iterator I after insertion (see enum
gsi_iterator_update).
@@ -435,12 +490,7 @@ void
gsi_insert_before_without_update (gimple_stmt_iterator *i, gimple stmt,
enum gsi_iterator_update m)
{
- gimple_seq_node n;
-
- n = ggc_alloc_gimple_seq_node_d ();
- n->prev = n->next = NULL;
- n->stmt = stmt;
- gsi_insert_seq_nodes_before (i, n, n, m);
+ gsi_insert_seq_nodes_before (i, stmt, stmt, m);
}
/* Insert statement STMT before the statement pointed-to by iterator I.
@@ -470,12 +520,7 @@ void
gsi_insert_after_without_update (gimple_stmt_iterator *i, gimple stmt,
enum gsi_iterator_update m)
{
- gimple_seq_node n;
-
- n = ggc_alloc_gimple_seq_node_d ();
- n->prev = n->next = NULL;
- n->stmt = stmt;
- gsi_insert_seq_nodes_after (i, n, n, m);
+ gsi_insert_seq_nodes_after (i, stmt, stmt, m);
}
@@ -525,19 +570,24 @@ gsi_remove (gimple_stmt_iterator *i, bool remove_permanently)
/* Update the iterator and re-wire the links in I->SEQ. */
cur = i->ptr;
- next = cur->next;
- prev = cur->prev;
-
- if (prev)
- prev->next = next;
- else
- gimple_seq_set_first (i->seq, next);
+ next = cur->gsbase.next;
+ prev = cur->gsbase.prev;
+ /* See gsi_set_stmt for why we don't reset prev/next of STMT. */
if (next)
- next->prev = prev;
- else
+ /* Cur is not last. */
+ next->gsbase.prev = prev;
+ else if (prev->gsbase.next)
+ /* Cur is last but not first. */
gimple_seq_set_last (i->seq, prev);
+ if (prev->gsbase.next)
+ /* Cur is not first. */
+ prev->gsbase.next = next;
+ else
+ /* Cur is first. */
+ *i->seq = next;
+
i->ptr = next;
return require_eh_edge_purge;
@@ -557,11 +607,8 @@ gsi_for_stmt (gimple stmt)
else
i = gsi_start_bb (bb);
- for (; !gsi_end_p (i); gsi_next (&i))
- if (gsi_stmt (i) == stmt)
- return i;
-
- gcc_unreachable ();
+ i.ptr = stmt;
+ return i;
}
@@ -727,7 +774,6 @@ basic_block
gsi_insert_on_edge_immediate (edge e, gimple stmt)
{
gimple_stmt_iterator gsi;
- struct gimple_seq_node_d node;
basic_block new_bb = NULL;
bool ins_after;
@@ -735,9 +781,7 @@ gsi_insert_on_edge_immediate (edge e, gimple stmt)
ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb);
- node.stmt = stmt;
- node.prev = node.next = NULL;
- update_call_edge_frequencies (&node, gsi.bb);
+ update_call_edge_frequencies (stmt, gsi.bb);
if (ins_after)
gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
@@ -820,5 +864,7 @@ gsi_commit_one_edge_insert (edge e, basic_block *new_bb)
gimple_stmt_iterator
gsi_start_phis (basic_block bb)
{
- return gsi_start (phi_nodes (bb));
+ gimple_seq *pseq = phi_nodes_ptr (bb);
+ /* XXX check only necessary because ENTRY/EXIT blocks don't have il.gimple */
+ return pseq ? gsi_start_1 (pseq) : gsi_none ();
}