* 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
+2012-05-02 Michael Matz <matz@suse.de>
+
+ * 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.
+
+2012-05-02 Michael Matz <matz@suse.de>
+
+ * 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.
+
+2012-05-02 Michael Matz <matz@suse.de>
+
+ * 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.
+
+2012-05-02 Michael Matz <matz@suse.de>
+
+ * 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.
+
+2012-05-02 Michael Matz <matz@suse.de>
+
+ * 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.
+
+2012-05-02 Michael Matz <matz@suse.de>
+
+ * 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.
+
2012-05-02 Kirill Yukhin <kirill.yukhin@intel.com>
Andi Kleen <ak@linux.intel.com>
- * coretypes (MEMMODEL_MASK): New.
+ * coretypes.h (MEMMODEL_MASK): New.
* builtins.c (get_memmodel): Add val. Call target.memmodel_check
and return new variable.
(expand_builtin_atomic_exchange): Mask memmodel values.
IPA_REF_ADDR, stmt);
}
}
- for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node,
mark_load, mark_store, mark_address);
}
mark_store, mark_address);
}
- for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node,
mark_load, mark_store, mark_address);
}
mark_store, mark_address);
}
- for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
walk_stmt_load_store_addr_ops (gsi_stmt (gsi), node,
mark_load, mark_store, mark_address);
}
function we lower it, which will require gimplified nested
functions, so we can end up here with an already gimplified
body. */
- if (!gimple_body (decl))
+ if (!gimple_has_body_p (decl))
gimplify_function_tree (decl);
dump_function (TDI_generic, decl);
struct cl_option_handlers;
struct diagnostic_context;
typedef struct diagnostic_context diagnostic_context;
-struct gimple_seq_d;
-typedef struct gimple_seq_d *gimple_seq;
-typedef const struct gimple_seq_d *const_gimple_seq;
+typedef gimple gimple_seq;
+typedef gimple const_gimple_seq;
/* Address space number for named address space support. */
typedef unsigned char addr_space_t;
struct control_flow_graph *cfg;
/* GIMPLE body for this function. */
- struct gimple_seq_d *gimple_body;
+ gimple_seq gimple_body;
/* SSA and dataflow information. */
struct gimple_df *gimple_df;
tree lhs;
gimple stmt, new_stmt;
gimple_stmt_iterator i;
- gimple_seq stmts = gimple_seq_alloc();
+ gimple_seq stmts = NULL;
struct gimplify_ctx gctx;
- gimple last;
gimple laststore;
tree reaching_vuse;
/* Second iterate over the statements forward, assigning virtual
operands to their uses. */
- last = NULL;
reaching_vuse = gimple_vuse (stmt);
for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
{
- /* Do not insert the last stmt in this loop but remember it
- for replacing the original statement. */
- if (last)
- {
- gsi_insert_before (si_p, last, GSI_NEW_STMT);
- gsi_next (si_p);
- }
new_stmt = gsi_stmt (i);
/* The replacement can expose previously unreferenced variables. */
if (gimple_in_ssa_p (cfun))
gimple_set_modified (new_stmt, true);
if (gimple_vdef (new_stmt))
reaching_vuse = gimple_vdef (new_stmt);
- last = new_stmt;
}
/* If the new sequence does not do a store release the virtual
}
}
- /* Finally replace rhe original statement with the last. */
- gsi_replace (si_p, last, false);
+ /* Finally replace the original statement with the sequence. */
+ gsi_replace_with_seq (si_p, stmts, false);
}
/* Return the string length, maximum string length or maximum value of
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
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;
(current_function_decl, bb));
}
- e = cgraph_edge (cfun_node, n->stmt);
+ e = cgraph_edge (cfun_node, n);
if (e != NULL)
e->frequency = bb_freq;
}
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);
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)
{
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);
}
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)
{
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;
}
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).
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.
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);
}
/* 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;
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;
}
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;
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);
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 ();
}
i = gsi_start (lowered_body);
lower_gimple_bind (&i, &data);
- /* Once the old body has been lowered, replace it with the new
- lowered sequence. */
- gimple_set_body (current_function_decl, lowered_body);
-
i = gsi_last (lowered_body);
/* If the function falls off the end, we need a null return statement.
gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
}
+ /* Once the old body has been lowered, replace it with the new
+ lowered sequence. */
+ gimple_set_body (current_function_decl, lowered_body);
+
gcc_assert (data.block == DECL_INITIAL (current_function_decl));
BLOCK_SUBBLOCKS (data.block)
= blocks_nreverse (BLOCK_SUBBLOCKS (data.block));
do it explicitly. DATA is passed through the recursion. */
static void
-lower_sequence (gimple_seq seq, struct lower_data *data)
+lower_sequence (gimple_seq *seq, struct lower_data *data)
{
gimple_stmt_iterator gsi;
- for (gsi = gsi_start (seq); !gsi_end_p (gsi); )
+ for (gsi = gsi_start (*seq); !gsi_end_p (gsi); )
lower_stmt (&gsi, data);
}
stmt = gsi_stmt (*gsi);
- lower_sequence (gimple_omp_body (stmt), data);
- gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
- gsi_insert_seq_before (gsi, gimple_omp_body (stmt), GSI_SAME_STMT);
+ lower_sequence (gimple_omp_body_ptr (stmt), data);
+ gsi_insert_seq_after (gsi, gimple_omp_body (stmt), GSI_CONTINUE_LINKING);
gimple_omp_set_body (stmt, NULL);
- gsi_remove (gsi, false);
+ gsi_next (gsi);
}
case GIMPLE_TRY:
{
bool try_cannot_fallthru;
- lower_sequence (gimple_try_eval (stmt), data);
+ lower_sequence (gimple_try_eval_ptr (stmt), data);
try_cannot_fallthru = data->cannot_fallthru;
data->cannot_fallthru = false;
- lower_sequence (gimple_try_cleanup (stmt), data);
+ lower_sequence (gimple_try_cleanup_ptr (stmt), data);
/* See gimple_stmt_may_fallthru for the rationale. */
if (gimple_try_kind (stmt) == GIMPLE_TRY_FINALLY)
{
case GIMPLE_CATCH:
data->cannot_fallthru = false;
- lower_sequence (gimple_catch_handler (stmt), data);
+ lower_sequence (gimple_catch_handler_ptr (stmt), data);
break;
case GIMPLE_EH_FILTER:
data->cannot_fallthru = false;
- lower_sequence (gimple_eh_filter_failure (stmt), data);
+ lower_sequence (gimple_eh_filter_failure_ptr (stmt), data);
break;
case GIMPLE_EH_ELSE:
- lower_sequence (gimple_eh_else_n_body (stmt), data);
- lower_sequence (gimple_eh_else_e_body (stmt), data);
+ lower_sequence (gimple_eh_else_n_body_ptr (stmt), data);
+ lower_sequence (gimple_eh_else_e_body_ptr (stmt), data);
break;
case GIMPLE_NOP:
return;
case GIMPLE_TRANSACTION:
- lower_sequence (gimple_transaction_body (stmt), data);
+ lower_sequence (gimple_transaction_body_ptr (stmt), data);
break;
default:
}
record_vars (gimple_bind_vars (stmt));
- lower_sequence (gimple_bind_body (stmt), data);
+ lower_sequence (gimple_bind_body_ptr (stmt), data);
if (new_block)
{
if (gimple_seq_may_fallthru (gimple_try_eval (stmt)))
return true;
- i = gsi_start (gimple_try_cleanup (stmt));
+ i = gsi_start (*gimple_try_cleanup_ptr (stmt));
switch (gimple_code (gsi_stmt (i)))
{
case GIMPLE_CATCH:
"assignments",
"phi nodes",
"conditionals",
- "sequences",
"everything else"
};
#endif /* GATHER_STATISTICS */
-/* A cache of gimple_seq objects. Sequences are created and destroyed
- fairly often during gimplification. */
-static GTY ((deletable)) struct gimple_seq_d *gimple_seq_cache;
-
/* Private API manipulation functions shared only with some
other files. */
extern void gimple_set_stored_syms (gimple, bitmap, bitmap_obstack *);
/* Do not call gimple_set_modified here as it has other side
effects and this tuple is still not completely built. */
stmt->gsbase.modified = 1;
+ gimple_init_singleton (stmt);
return stmt;
}
#endif /* ENABLE_GIMPLE_CHECKING */
-/* Allocate a new GIMPLE sequence in GC memory and return it. If
- there are free sequences in GIMPLE_SEQ_CACHE return one of those
- instead. */
-
-gimple_seq
-gimple_seq_alloc (void)
-{
- gimple_seq seq = gimple_seq_cache;
- if (seq)
- {
- gimple_seq_cache = gimple_seq_cache->next_free;
- gcc_assert (gimple_seq_cache != seq);
- memset (seq, 0, sizeof (*seq));
- }
- else
- {
- seq = ggc_alloc_cleared_gimple_seq_d ();
-#ifdef GATHER_STATISTICS
- gimple_alloc_counts[(int) gimple_alloc_kind_seq]++;
- gimple_alloc_sizes[(int) gimple_alloc_kind_seq] += sizeof (*seq);
-#endif
- }
-
- return seq;
-}
-
-/* Return SEQ to the free pool of GIMPLE sequences. */
-
-void
-gimple_seq_free (gimple_seq seq)
-{
- if (seq == NULL)
- return;
-
- gcc_assert (gimple_seq_first (seq) == NULL);
- gcc_assert (gimple_seq_last (seq) == NULL);
-
- /* If this triggers, it's a sign that the same list is being freed
- twice. */
- gcc_assert (seq != gimple_seq_cache || gimple_seq_cache == NULL);
-
- /* Add SEQ to the pool of free sequences. */
- seq->next_free = gimple_seq_cache;
- gimple_seq_cache = seq;
-}
-
-
/* Link gimple statement GS to the end of the sequence *SEQ_P. If
*SEQ_P is NULL, a new sequence is allocated. */
gimple_seq_add_stmt (gimple_seq *seq_p, gimple gs)
{
gimple_stmt_iterator si;
-
if (gs == NULL)
return;
- if (*seq_p == NULL)
- *seq_p = gimple_seq_alloc ();
-
si = gsi_last (*seq_p);
gsi_insert_after (&si, gs, GSI_NEW_STMT);
}
gimple_seq_add_seq (gimple_seq *dst_p, gimple_seq src)
{
gimple_stmt_iterator si;
-
if (src == NULL)
return;
- if (*dst_p == NULL)
- *dst_p = gimple_seq_alloc ();
-
si = gsi_last (*dst_p);
gsi_insert_seq_after (&si, src, GSI_NEW_STMT);
}
gimple_seq_copy (gimple_seq src)
{
gimple_stmt_iterator gsi;
- gimple_seq new_seq = gimple_seq_alloc ();
+ gimple_seq new_seq = NULL;
gimple stmt;
for (gsi = gsi_start (src); !gsi_end_p (gsi); gsi_next (&gsi))
}
-/* Walk all the statements in the sequence SEQ calling walk_gimple_stmt
+/* Walk all the statements in the sequence *PSEQ calling walk_gimple_stmt
on each one. WI is as in walk_gimple_stmt.
If walk_gimple_stmt returns non-NULL, the walk is stopped, and the
Otherwise, all the statements are walked and NULL returned. */
gimple
-walk_gimple_seq (gimple_seq seq, walk_stmt_fn callback_stmt,
- walk_tree_fn callback_op, struct walk_stmt_info *wi)
+walk_gimple_seq_mod (gimple_seq *pseq, walk_stmt_fn callback_stmt,
+ walk_tree_fn callback_op, struct walk_stmt_info *wi)
{
gimple_stmt_iterator gsi;
- for (gsi = gsi_start (seq); !gsi_end_p (gsi); )
+ for (gsi = gsi_start (*pseq); !gsi_end_p (gsi); )
{
tree ret = walk_gimple_stmt (&gsi, callback_stmt, callback_op, wi);
if (ret)
}
+/* Like walk_gimple_seq_mod, but ensure that the head of SEQ isn't
+ changed by the callbacks. */
+
+gimple
+walk_gimple_seq (gimple_seq seq, walk_stmt_fn callback_stmt,
+ walk_tree_fn callback_op, struct walk_stmt_info *wi)
+{
+ gimple_seq seq2 = seq;
+ gimple ret = walk_gimple_seq_mod (&seq2, callback_stmt, callback_op, wi);
+ gcc_assert (seq2 == seq);
+ return ret;
+}
+
+
/* Helper function for walk_gimple_stmt. Walk operands of a GIMPLE_ASM. */
static tree
switch (gimple_code (stmt))
{
case GIMPLE_BIND:
- ret = walk_gimple_seq (gimple_bind_body (stmt), callback_stmt,
- callback_op, wi);
+ ret = walk_gimple_seq_mod (gimple_bind_body_ptr (stmt), callback_stmt,
+ callback_op, wi);
if (ret)
return wi->callback_result;
break;
case GIMPLE_CATCH:
- ret = walk_gimple_seq (gimple_catch_handler (stmt), callback_stmt,
- callback_op, wi);
+ ret = walk_gimple_seq_mod (gimple_catch_handler_ptr (stmt), callback_stmt,
+ callback_op, wi);
if (ret)
return wi->callback_result;
break;
case GIMPLE_EH_FILTER:
- ret = walk_gimple_seq (gimple_eh_filter_failure (stmt), callback_stmt,
+ ret = walk_gimple_seq_mod (gimple_eh_filter_failure_ptr (stmt), callback_stmt,
callback_op, wi);
if (ret)
return wi->callback_result;
break;
case GIMPLE_EH_ELSE:
- ret = walk_gimple_seq (gimple_eh_else_n_body (stmt),
+ ret = walk_gimple_seq_mod (gimple_eh_else_n_body_ptr (stmt),
callback_stmt, callback_op, wi);
if (ret)
return wi->callback_result;
- ret = walk_gimple_seq (gimple_eh_else_e_body (stmt),
+ ret = walk_gimple_seq_mod (gimple_eh_else_e_body_ptr (stmt),
callback_stmt, callback_op, wi);
if (ret)
return wi->callback_result;
break;
case GIMPLE_TRY:
- ret = walk_gimple_seq (gimple_try_eval (stmt), callback_stmt, callback_op,
+ ret = walk_gimple_seq_mod (gimple_try_eval_ptr (stmt), callback_stmt, callback_op,
wi);
if (ret)
return wi->callback_result;
- ret = walk_gimple_seq (gimple_try_cleanup (stmt), callback_stmt,
+ ret = walk_gimple_seq_mod (gimple_try_cleanup_ptr (stmt), callback_stmt,
callback_op, wi);
if (ret)
return wi->callback_result;
break;
case GIMPLE_OMP_FOR:
- ret = walk_gimple_seq (gimple_omp_for_pre_body (stmt), callback_stmt,
+ ret = walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt), callback_stmt,
callback_op, wi);
if (ret)
return wi->callback_result;
case GIMPLE_OMP_TASK:
case GIMPLE_OMP_SECTIONS:
case GIMPLE_OMP_SINGLE:
- ret = walk_gimple_seq (gimple_omp_body (stmt), callback_stmt,
+ ret = walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), callback_stmt,
callback_op, wi);
if (ret)
return wi->callback_result;
break;
case GIMPLE_WITH_CLEANUP_EXPR:
- ret = walk_gimple_seq (gimple_wce_cleanup (stmt), callback_stmt,
+ ret = walk_gimple_seq_mod (gimple_wce_cleanup_ptr (stmt), callback_stmt,
callback_op, wi);
if (ret)
return wi->callback_result;
break;
case GIMPLE_TRANSACTION:
- ret = walk_gimple_seq (gimple_transaction_body (stmt),
+ ret = walk_gimple_seq_mod (gimple_transaction_body_ptr (stmt),
callback_stmt, callback_op, wi);
if (ret)
return wi->callback_result;
tree lhs = gimple_assign_lhs (stmt);
gimple new_stmt = gimple_alloc (gimple_code (stmt), new_rhs_ops + 1);
memcpy (new_stmt, stmt, gimple_size (gimple_code (stmt)));
+ gimple_init_singleton (new_stmt);
gsi_replace (gsi, new_stmt, true);
stmt = new_stmt;
/* Return a deep copy of statement STMT. All the operands from STMT
are reallocated and copied using unshare_expr. The DEF, USE, VDEF
- and VUSE operand arrays are set to empty in the new copy. */
+ and VUSE operand arrays are set to empty in the new copy. The new
+ copy isn't part of any sequence. */
gimple
gimple_copy (gimple stmt)
/* Shallow copy all the fields from STMT. */
memcpy (copy, stmt, gimple_size (code));
+ gimple_init_singleton (copy);
/* If STMT has sub-statements, deep-copy them as well. */
if (gimple_has_substatements (stmt))
#include "tree-ssa-alias.h"
#include "internal-fn.h"
-struct gimple_seq_node_d;
-typedef struct gimple_seq_node_d *gimple_seq_node;
-typedef const struct gimple_seq_node_d *const_gimple_seq_node;
+typedef gimple gimple_seq_node;
/* For each block, the PHI nodes that need to be rewritten are stored into
these vectors. */
GF_PLF_2 = 1 << 1
};
-/* A node in a gimple_seq_d. */
-struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) gimple_seq_node_d {
- gimple stmt;
- struct gimple_seq_node_d *prev;
- struct gimple_seq_node_d *next;
-};
-
-/* A double-linked sequence of gimple statements. */
-struct GTY ((chain_next ("%h.next_free"))) gimple_seq_d {
- /* First and last statements in the sequence. */
- gimple_seq_node first;
- gimple_seq_node last;
-
- /* Sequences are created/destroyed frequently. To minimize
- allocation activity, deallocated sequences are kept in a pool of
- available sequences. This is the pointer to the next free
- sequence in the pool. */
- gimple_seq next_free;
-};
-
-
-/* Return the first node in GIMPLE sequence S. */
-
-static inline gimple_seq_node
-gimple_seq_first (const_gimple_seq s)
-{
- return s ? s->first : NULL;
-}
-
-
-/* Return the first statement in GIMPLE sequence S. */
-
-static inline gimple
-gimple_seq_first_stmt (const_gimple_seq s)
-{
- gimple_seq_node n = gimple_seq_first (s);
- return (n) ? n->stmt : NULL;
-}
-
-
-/* Return the last node in GIMPLE sequence S. */
-
-static inline gimple_seq_node
-gimple_seq_last (const_gimple_seq s)
-{
- return s ? s->last : NULL;
-}
-
-
-/* Return the last statement in GIMPLE sequence S. */
-
-static inline gimple
-gimple_seq_last_stmt (const_gimple_seq s)
-{
- gimple_seq_node n = gimple_seq_last (s);
- return (n) ? n->stmt : NULL;
-}
-
-
-/* Set the last node in GIMPLE sequence S to LAST. */
-
-static inline void
-gimple_seq_set_last (gimple_seq s, gimple_seq_node last)
-{
- s->last = last;
-}
-
-
-/* Set the first node in GIMPLE sequence S to FIRST. */
-
-static inline void
-gimple_seq_set_first (gimple_seq s, gimple_seq_node first)
-{
- s->first = first;
-}
-
-
-/* Return true if GIMPLE sequence S is empty. */
-
-static inline bool
-gimple_seq_empty_p (const_gimple_seq s)
-{
- return s == NULL || s->first == NULL;
-}
-
-
-void gimple_seq_add_stmt (gimple_seq *, gimple);
-
-/* Link gimple statement GS to the end of the sequence *SEQ_P. If
- *SEQ_P is NULL, a new sequence is allocated. This function is
- similar to gimple_seq_add_stmt, but does not scan the operands.
- During gimplification, we need to manipulate statement sequences
- before the def/use vectors have been constructed. */
-void gimple_seq_add_stmt_without_update (gimple_seq *, gimple);
-
-/* Allocate a new sequence and initialize its first element with STMT. */
-
-static inline gimple_seq
-gimple_seq_alloc_with_stmt (gimple stmt)
-{
- gimple_seq seq = NULL;
- gimple_seq_add_stmt (&seq, stmt);
- return seq;
-}
-
-
-/* Returns the sequence of statements in BB. */
-
-static inline gimple_seq
-bb_seq (const_basic_block bb)
-{
- return (!(bb->flags & BB_RTL) && bb->il.gimple) ? bb->il.gimple->seq : NULL;
-}
-
-
-/* Sets the sequence of statements in BB to SEQ. */
-
-static inline void
-set_bb_seq (basic_block bb, gimple_seq seq)
-{
- gcc_checking_assert (!(bb->flags & BB_RTL));
- bb->il.gimple->seq = seq;
-}
-
/* Iterator object for GIMPLE statement sequences. */
typedef struct
are necessary to handle edge cases such as when statement is
added to an empty basic block or when the last statement of a
block/sequence is removed. */
- gimple_seq seq;
+ gimple_seq *seq;
basic_block bb;
} gimple_stmt_iterator;
Basic block holding this statement. */
struct basic_block_def *bb;
- /* [ WORD 4 ]
+ /* [ WORD 4-5 ]
+ Linked lists of gimple statements. The next pointers form
+ a NULL terminated list, the prev pointers are a cyclic list.
+ A gimple statement is hence also a double-ended list of
+ statements, with the pointer itself being the first element,
+ and the prev pointer being the last. */
+ gimple next;
+ gimple GTY((skip)) prev;
+
+ /* [ WORD 6 ]
Lexical block holding this statement. */
tree block;
};
struct GTY(()) gimple_statement_with_ops_base
{
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5-6 ]
+ /* [ WORD 7-8 ]
SSA operand vectors. NOTE: It should be possible to
amalgamate these vectors with the operand vector OP. However,
the SSA operand vectors are organized differently and contain
struct GTY(()) gimple_statement_with_ops
{
- /* [ WORD 1-6 ] */
+ /* [ WORD 1-8 ] */
struct gimple_statement_with_ops_base opbase;
- /* [ WORD 7 ]
+ /* [ WORD 9 ]
Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this
structure cannot be embedded inside another one. */
struct GTY(()) gimple_statement_with_memory_ops_base
{
- /* [ WORD 1-6 ] */
+ /* [ WORD 1-8 ] */
struct gimple_statement_with_ops_base opbase;
- /* [ WORD 7-8 ]
+ /* [ WORD 9-10 ]
Virtual operands for this statement. The GC will pick them
up via the ssa_names array. */
tree GTY((skip (""))) vdef;
struct GTY(()) gimple_statement_with_memory_ops
{
- /* [ WORD 1-8 ] */
+ /* [ WORD 1-10 ] */
struct gimple_statement_with_memory_ops_base membase;
- /* [ WORD 9 ]
+ /* [ WORD 11 ]
Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this
structure cannot be embedded inside another one. */
struct GTY(()) gimple_statement_call
{
- /* [ WORD 1-8 ] */
+ /* [ WORD 1-10 ] */
struct gimple_statement_with_memory_ops_base membase;
- /* [ WORD 9-12 ] */
+ /* [ WORD 11-14 ] */
struct pt_solution call_used;
struct pt_solution call_clobbered;
- /* [ WORD 13 ] */
+ /* [ WORD 15 ] */
union GTY ((desc ("%1.membase.opbase.gsbase.subcode & GF_CALL_INTERNAL"))) {
tree GTY ((tag ("0"))) fntype;
enum internal_fn GTY ((tag ("GF_CALL_INTERNAL"))) internal_fn;
} u;
- /* [ WORD 14 ]
+ /* [ WORD 16 ]
Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this
structure cannot be embedded inside another one. */
/* OpenMP statements (#pragma omp). */
struct GTY(()) gimple_statement_omp {
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5 ] */
+ /* [ WORD 7 ] */
gimple_seq body;
};
/* GIMPLE_BIND */
struct GTY(()) gimple_statement_bind {
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5 ]
+ /* [ WORD 7 ]
Variables declared in this scope. */
tree vars;
- /* [ WORD 6 ]
+ /* [ WORD 8 ]
This is different than the BLOCK field in gimple_statement_base,
which is analogous to TREE_BLOCK (i.e., the lexical block holding
this statement). This field is the equivalent of BIND_EXPR_BLOCK
gimple-low.c. */
tree block;
- /* [ WORD 7 ] */
+ /* [ WORD 9 ] */
gimple_seq body;
};
/* GIMPLE_CATCH */
struct GTY(()) gimple_statement_catch {
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5 ] */
+ /* [ WORD 7 ] */
tree types;
- /* [ WORD 6 ] */
+ /* [ WORD 8 ] */
gimple_seq handler;
};
/* GIMPLE_EH_FILTER */
struct GTY(()) gimple_statement_eh_filter {
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5 ]
+ /* [ WORD 7 ]
Filter types. */
tree types;
- /* [ WORD 6 ]
+ /* [ WORD 8 ]
Failure actions. */
gimple_seq failure;
};
/* GIMPLE_EH_ELSE */
struct GTY(()) gimple_statement_eh_else {
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5,6 ] */
+ /* [ WORD 7,8 ] */
gimple_seq n_body, e_body;
};
/* GIMPLE_EH_MUST_NOT_THROW */
struct GTY(()) gimple_statement_eh_mnt {
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5 ] Abort function decl. */
+ /* [ WORD 7 ] Abort function decl. */
tree fndecl;
};
/* GIMPLE_PHI */
struct GTY(()) gimple_statement_phi {
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5 ] */
+ /* [ WORD 7 ] */
unsigned capacity;
unsigned nargs;
- /* [ WORD 6 ] */
+ /* [ WORD 8 ] */
tree result;
- /* [ WORD 7 ] */
+ /* [ WORD 9 ] */
struct phi_arg_d GTY ((length ("%h.nargs"))) args[1];
};
struct GTY(()) gimple_statement_eh_ctrl
{
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5 ]
+ /* [ WORD 7 ]
Exception region number. */
int region;
};
/* GIMPLE_TRY */
struct GTY(()) gimple_statement_try {
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5 ]
+ /* [ WORD 7 ]
Expression to evaluate. */
gimple_seq eval;
- /* [ WORD 6 ]
+ /* [ WORD 8 ]
Cleanup expression. */
gimple_seq cleanup;
};
/* GIMPLE_WITH_CLEANUP_EXPR */
struct GTY(()) gimple_statement_wce {
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
/* Subcode: CLEANUP_EH_ONLY. True if the cleanup should only be
scope. This flag is analogous to the CLEANUP_EH_ONLY flag
in TARGET_EXPRs. */
- /* [ WORD 5 ]
+ /* [ WORD 7 ]
Cleanup expression. */
gimple_seq cleanup;
};
struct GTY(()) gimple_statement_asm
{
- /* [ WORD 1-8 ] */
+ /* [ WORD 1-10 ] */
struct gimple_statement_with_memory_ops_base membase;
- /* [ WORD 9 ]
+ /* [ WORD 11 ]
__asm__ statement. */
const char *string;
- /* [ WORD 10 ]
+ /* [ WORD 12 ]
Number of inputs, outputs, clobbers, labels. */
unsigned char ni;
unsigned char no;
unsigned char nc;
unsigned char nl;
- /* [ WORD 11 ]
+ /* [ WORD 13 ]
Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this
structure cannot be embedded inside another one. */
/* GIMPLE_OMP_CRITICAL */
struct GTY(()) gimple_statement_omp_critical {
- /* [ WORD 1-5 ] */
+ /* [ WORD 1-7 ] */
struct gimple_statement_omp omp;
- /* [ WORD 6 ]
+ /* [ WORD 8 ]
Critical section name. */
tree name;
};
/* GIMPLE_OMP_FOR */
struct GTY(()) gimple_statement_omp_for {
- /* [ WORD 1-5 ] */
+ /* [ WORD 1-7 ] */
struct gimple_statement_omp omp;
- /* [ WORD 6 ] */
+ /* [ WORD 8 ] */
tree clauses;
- /* [ WORD 7 ]
+ /* [ WORD 9 ]
Number of elements in iter array. */
size_t collapse;
- /* [ WORD 8 ] */
+ /* [ WORD 10 ] */
struct gimple_omp_for_iter * GTY((length ("%h.collapse"))) iter;
- /* [ WORD 9 ]
+ /* [ WORD 11 ]
Pre-body evaluated before the loop body begins. */
gimple_seq pre_body;
};
/* GIMPLE_OMP_PARALLEL */
struct GTY(()) gimple_statement_omp_parallel {
- /* [ WORD 1-5 ] */
+ /* [ WORD 1-7 ] */
struct gimple_statement_omp omp;
- /* [ WORD 6 ]
+ /* [ WORD 8 ]
Clauses. */
tree clauses;
- /* [ WORD 7 ]
+ /* [ WORD 9 ]
Child function holding the body of the parallel region. */
tree child_fn;
- /* [ WORD 8 ]
+ /* [ WORD 10 ]
Shared data argument. */
tree data_arg;
};
/* GIMPLE_OMP_TASK */
struct GTY(()) gimple_statement_omp_task {
- /* [ WORD 1-8 ] */
+ /* [ WORD 1-10 ] */
struct gimple_statement_omp_parallel par;
- /* [ WORD 9 ]
+ /* [ WORD 11 ]
Child function holding firstprivate initialization if needed. */
tree copy_fn;
- /* [ WORD 10-11 ]
+ /* [ WORD 12-13 ]
Size and alignment in bytes of the argument data block. */
tree arg_size;
tree arg_align;
/* GIMPLE_OMP_SECTIONS */
struct GTY(()) gimple_statement_omp_sections {
- /* [ WORD 1-5 ] */
+ /* [ WORD 1-7 ] */
struct gimple_statement_omp omp;
- /* [ WORD 6 ] */
+ /* [ WORD 8 ] */
tree clauses;
- /* [ WORD 7 ]
+ /* [ WORD 9 ]
The control variable used for deciding which of the sections to
execute. */
tree control;
do not need the body field. */
struct GTY(()) gimple_statement_omp_continue {
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5 ] */
+ /* [ WORD 7 ] */
tree control_def;
- /* [ WORD 6 ] */
+ /* [ WORD 8 ] */
tree control_use;
};
/* GIMPLE_OMP_SINGLE */
struct GTY(()) gimple_statement_omp_single {
- /* [ WORD 1-5 ] */
+ /* [ WORD 1-7 ] */
struct gimple_statement_omp omp;
- /* [ WORD 6 ] */
+ /* [ WORD 7 ] */
tree clauses;
};
contains a sequence, which we don't need here. */
struct GTY(()) gimple_statement_omp_atomic_load {
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5-6 ] */
+ /* [ WORD 7-8 ] */
tree rhs, lhs;
};
See note on GIMPLE_OMP_ATOMIC_LOAD. */
struct GTY(()) gimple_statement_omp_atomic_store {
- /* [ WORD 1-4 ] */
+ /* [ WORD 1-6 ] */
struct gimple_statement_base gsbase;
- /* [ WORD 5 ] */
+ /* [ WORD 7 ] */
tree val;
};
/* Define the overall contents of a gimple tuple. It may be any of the
structures declared above for various types of tuples. */
-union GTY ((desc ("gimple_statement_structure (&%h)"), variable_size)) gimple_statement_d {
+union GTY ((desc ("gimple_statement_structure (&%h)"),
+ chain_next ("%h.gsbase.next"), variable_size)) gimple_statement_d {
struct gimple_statement_base GTY ((tag ("GSS_BASE"))) gsbase;
struct gimple_statement_with_ops GTY ((tag ("GSS_WITH_OPS"))) gsops;
struct gimple_statement_with_memory_ops_base GTY ((tag ("GSS_WITH_MEM_OPS_BASE"))) gsmembase;
extern bool useless_type_conversion_p (tree, tree);
extern bool types_compatible_p (tree, tree);
+/* Return the first node in GIMPLE sequence S. */
+
+static inline gimple_seq_node
+gimple_seq_first (const_gimple_seq s)
+{
+ return s;
+}
+
+
+/* Return the first statement in GIMPLE sequence S. */
+
+static inline gimple
+gimple_seq_first_stmt (const_gimple_seq s)
+{
+ gimple_seq_node n = gimple_seq_first (s);
+ return n;
+}
+
+
+/* Return the last node in GIMPLE sequence S. */
+
+static inline gimple_seq_node
+gimple_seq_last (const_gimple_seq s)
+{
+ return s ? s->gsbase.prev : NULL;
+}
+
+
+/* Return the last statement in GIMPLE sequence S. */
+
+static inline gimple
+gimple_seq_last_stmt (const_gimple_seq s)
+{
+ gimple_seq_node n = gimple_seq_last (s);
+ return n;
+}
+
+
+/* Set the last node in GIMPLE sequence *PS to LAST. */
+
+static inline void
+gimple_seq_set_last (gimple_seq *ps, gimple_seq_node last)
+{
+ (*ps)->gsbase.prev = last;
+}
+
+
+/* Set the first node in GIMPLE sequence *PS to FIRST. */
+
+static inline void
+gimple_seq_set_first (gimple_seq *ps, gimple_seq_node first)
+{
+ *ps = first;
+}
+
+
+/* Return true if GIMPLE sequence S is empty. */
+
+static inline bool
+gimple_seq_empty_p (const_gimple_seq s)
+{
+ return s == NULL;
+}
+
+
+void gimple_seq_add_stmt (gimple_seq *, gimple);
+
+/* Link gimple statement GS to the end of the sequence *SEQ_P. If
+ *SEQ_P is NULL, a new sequence is allocated. This function is
+ similar to gimple_seq_add_stmt, but does not scan the operands.
+ During gimplification, we need to manipulate statement sequences
+ before the def/use vectors have been constructed. */
+void gimple_seq_add_stmt_without_update (gimple_seq *, gimple);
+
+/* Allocate a new sequence and initialize its first element with STMT. */
+
+static inline gimple_seq
+gimple_seq_alloc_with_stmt (gimple stmt)
+{
+ gimple_seq seq = NULL;
+ gimple_seq_add_stmt (&seq, stmt);
+ return seq;
+}
+
+
+/* Returns the sequence of statements in BB. */
+
+static inline gimple_seq
+bb_seq (const_basic_block bb)
+{
+ return (!(bb->flags & BB_RTL) && bb->il.gimple) ? bb->il.gimple->seq : NULL;
+}
+
+static inline gimple_seq *
+bb_seq_addr (const_basic_block bb)
+{
+ return (!(bb->flags & BB_RTL) && bb->il.gimple) ? &bb->il.gimple->seq : NULL;
+}
+
+/* Sets the sequence of statements in BB to SEQ. */
+
+static inline void
+set_bb_seq (basic_block bb, gimple_seq seq)
+{
+ gcc_checking_assert (!(bb->flags & BB_RTL));
+ bb->il.gimple->seq = seq;
+}
+
+
/* Return the code for GIMPLE statement G. */
static inline enum gimple_code
}
+/* Make statement G a singleton sequence. */
+
+static inline void
+gimple_init_singleton (gimple g)
+{
+ g->gsbase.next = NULL;
+ g->gsbase.prev = g;
+}
+
+
/* Return true if GIMPLE statement G has register or memory operands. */
static inline bool
}
+static inline gimple_seq *
+gimple_bind_body_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_BIND);
+ return &gs->gimple_bind.body;
+}
+
/* Return the GIMPLE sequence contained in the GIMPLE_BIND statement GS. */
static inline gimple_seq
gimple_bind_body (gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_BIND);
- return gs->gimple_bind.body;
+ return *gimple_bind_body_ptr (gs);
}
}
-/* Return the GIMPLE sequence representing the body of the handler of
- GIMPLE_CATCH statement GS. */
-
-static inline gimple_seq
-gimple_catch_handler (gimple gs)
-{
- GIMPLE_CHECK (gs, GIMPLE_CATCH);
- return gs->gimple_catch.handler;
-}
-
-
/* Return a pointer to the GIMPLE sequence representing the body of
the handler of GIMPLE_CATCH statement GS. */
}
+/* Return the GIMPLE sequence representing the body of the handler of
+ GIMPLE_CATCH statement GS. */
+
+static inline gimple_seq
+gimple_catch_handler (gimple gs)
+{
+ return *gimple_catch_handler_ptr (gs);
+}
+
+
/* Set T to be the set of types handled by GIMPLE_CATCH GS. */
static inline void
}
+/* Return a pointer to the sequence of statement to execute when
+ GIMPLE_EH_FILTER statement fails. */
+
+static inline gimple_seq *
+gimple_eh_filter_failure_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_EH_FILTER);
+ return &gs->gimple_eh_filter.failure;
+}
+
+
/* Return the sequence of statement to execute when GIMPLE_EH_FILTER
statement fails. */
static inline gimple_seq
gimple_eh_filter_failure (gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_EH_FILTER);
- return gs->gimple_eh_filter.failure;
+ return *gimple_eh_filter_failure_ptr (gs);
}
/* GIMPLE_EH_ELSE accessors. */
+static inline gimple_seq *
+gimple_eh_else_n_body_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_EH_ELSE);
+ return &gs->gimple_eh_else.n_body;
+}
+
static inline gimple_seq
gimple_eh_else_n_body (gimple gs)
+{
+ return *gimple_eh_else_n_body_ptr (gs);
+}
+
+static inline gimple_seq *
+gimple_eh_else_e_body_ptr (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_EH_ELSE);
- return gs->gimple_eh_else.n_body;
+ return &gs->gimple_eh_else.e_body;
}
static inline gimple_seq
gimple_eh_else_e_body (gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_EH_ELSE);
- return gs->gimple_eh_else.e_body;
+ return *gimple_eh_else_e_body_ptr (gs);
}
static inline void
}
+/* Return a pointer to the sequence of statements used as the
+ body for GIMPLE_TRY GS. */
+
+static inline gimple_seq *
+gimple_try_eval_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_TRY);
+ return &gs->gimple_try.eval;
+}
+
+
/* Return the sequence of statements used as the body for GIMPLE_TRY GS. */
static inline gimple_seq
gimple_try_eval (gimple gs)
+{
+ return *gimple_try_eval_ptr (gs);
+}
+
+
+/* Return a pointer to the sequence of statements used as the cleanup body for
+ GIMPLE_TRY GS. */
+
+static inline gimple_seq *
+gimple_try_cleanup_ptr (gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_TRY);
- return gs->gimple_try.eval;
+ return &gs->gimple_try.cleanup;
}
static inline gimple_seq
gimple_try_cleanup (gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_TRY);
- return gs->gimple_try.cleanup;
+ return *gimple_try_cleanup_ptr (gs);
}
}
+/* Return a pointer to the cleanup sequence for cleanup statement GS. */
+
+static inline gimple_seq *
+gimple_wce_cleanup_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR);
+ return &gs->gimple_wce.cleanup;
+}
+
+
/* Return the cleanup sequence for cleanup statement GS. */
static inline gimple_seq
gimple_wce_cleanup (gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR);
- return gs->gimple_wce.cleanup;
+ return *gimple_wce_cleanup_ptr (gs);
}
gimple_set_op (dbg, 1, value);
}
+/* Return a pointer to the body for the OMP statement GS. */
+
+static inline gimple_seq *
+gimple_omp_body_ptr (gimple gs)
+{
+ return &gs->omp.body;
+}
+
/* Return the body for the OMP statement GS. */
static inline gimple_seq
gimple_omp_body (gimple gs)
{
- return gs->omp.body;
+ return *gimple_omp_body_ptr (gs);
}
/* Set BODY to be the body for the OMP statement GS. */
}
+/* Return a pointer to the sequence of statements to execute before the OMP_FOR
+ statement GS starts. */
+
+static inline gimple_seq *
+gimple_omp_for_pre_body_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
+ return &gs->gimple_omp_for.pre_body;
+}
+
+
/* Return the sequence of statements to execute before the OMP_FOR
statement GS starts. */
static inline gimple_seq
gimple_omp_for_pre_body (gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_OMP_FOR);
- return gs->gimple_omp_for.pre_body;
+ return *gimple_omp_for_pre_body_ptr (gs);
}
g->gimple_omp_continue.control_use = use;
}
+/* Return a pointer to the body for the GIMPLE_TRANSACTION statement GS. */
+
+static inline gimple_seq *
+gimple_transaction_body_ptr (gimple gs)
+{
+ GIMPLE_CHECK (gs, GIMPLE_TRANSACTION);
+ return &gs->gimple_transaction.body;
+}
+
/* Return the body for the GIMPLE_TRANSACTION statement GS. */
static inline gimple_seq
gimple_transaction_body (gimple gs)
{
- GIMPLE_CHECK (gs, GIMPLE_TRANSACTION);
- return gs->gimple_transaction.body;
+ return *gimple_transaction_body_ptr (gs);
}
/* Return the label associated with a GIMPLE_TRANSACTION. */
/* Return a new iterator pointing to GIMPLE_SEQ's first statement. */
static inline gimple_stmt_iterator
-gsi_start (gimple_seq seq)
+gsi_start_1 (gimple_seq *seq)
{
gimple_stmt_iterator i;
- i.ptr = gimple_seq_first (seq);
+ i.ptr = gimple_seq_first (*seq);
i.seq = seq;
- i.bb = (i.ptr && i.ptr->stmt) ? gimple_bb (i.ptr->stmt) : NULL;
+ i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
return i;
}
+#define gsi_start(x) gsi_start_1(&(x))
+
+static inline gimple_stmt_iterator
+gsi_none (void)
+{
+ gimple_stmt_iterator i;
+ i.ptr = NULL;
+ i.seq = NULL;
+ i.bb = NULL;
+ return i;
+}
/* Return a new iterator pointing to the first statement in basic block BB. */
gsi_start_bb (basic_block bb)
{
gimple_stmt_iterator i;
- gimple_seq seq;
+ gimple_seq *seq;
- seq = bb_seq (bb);
- i.ptr = gimple_seq_first (seq);
- i.seq = seq;
- i.bb = bb;
+ seq = bb_seq_addr (bb);
+ if (!seq)
+ /* XXX Only necessary because of ENTRY/EXIT block which don't have
+ il.gimple */
+ {
+ i.ptr = NULL;
+ i.seq = NULL;
+ i.bb = NULL;
+ }
+ else
+ {
+ i.ptr = gimple_seq_first (*seq);
+ i.seq = seq;
+ i.bb = bb;
+ }
return i;
}
/* Return a new iterator initially pointing to GIMPLE_SEQ's last statement. */
static inline gimple_stmt_iterator
-gsi_last (gimple_seq seq)
+gsi_last_1 (gimple_seq *seq)
{
gimple_stmt_iterator i;
- i.ptr = gimple_seq_last (seq);
+ i.ptr = gimple_seq_last (*seq);
i.seq = seq;
- i.bb = (i.ptr && i.ptr->stmt) ? gimple_bb (i.ptr->stmt) : NULL;
+ i.bb = i.ptr ? gimple_bb (i.ptr) : NULL;
return i;
}
+#define gsi_last(x) gsi_last_1(&(x))
/* Return a new iterator pointing to the last statement in basic block BB. */
gsi_last_bb (basic_block bb)
{
gimple_stmt_iterator i;
- gimple_seq seq;
+ gimple_seq *seq;
- seq = bb_seq (bb);
- i.ptr = gimple_seq_last (seq);
- i.seq = seq;
- i.bb = bb;
+ seq = bb_seq_addr (bb);
+ if (!seq)
+ /* XXX Only necessary because of ENTRY/EXIT block which don't have
+ il.gimple */
+ {
+ i.ptr = NULL;
+ i.seq = NULL;
+ i.bb = NULL;
+ }
+ else
+ {
+ i.ptr = gimple_seq_last (*seq);
+ i.seq = seq;
+ i.bb = bb;
+ }
return i;
}
static inline bool
gsi_one_before_end_p (gimple_stmt_iterator i)
{
- return i.ptr != NULL && i.ptr->next == NULL;
+ return i.ptr != NULL && i.ptr->gsbase.next == NULL;
}
static inline void
gsi_next (gimple_stmt_iterator *i)
{
- i->ptr = i->ptr->next;
+ i->ptr = i->ptr->gsbase.next;
}
/* Advance the iterator to the previous gimple statement. */
static inline void
gsi_prev (gimple_stmt_iterator *i)
{
- i->ptr = i->ptr->prev;
+ gimple prev = i->ptr->gsbase.prev;
+ if (prev->gsbase.next)
+ i->ptr = prev;
+ else
+ i->ptr = NULL;
}
/* Return the current stmt. */
static inline gimple
gsi_stmt (gimple_stmt_iterator i)
{
- return i.ptr->stmt;
+ return i.ptr;
}
/* Return a block statement iterator that points to the first non-label
return i;
}
-/* Return a pointer to the current stmt.
-
- NOTE: You may want to use gsi_replace on the iterator itself,
- as this performs additional bookkeeping that will not be done
- if you simply assign through a pointer returned by gsi_stmt_ptr. */
-
-static inline gimple *
-gsi_stmt_ptr (gimple_stmt_iterator *i)
-{
- return &i->ptr->stmt;
-}
-
/* Return the basic block associated with this iterator. */
static inline gimple_seq
gsi_seq (gimple_stmt_iterator i)
{
- return i.seq;
+ return *i.seq;
}
/* In gimple-iterator.c */
gimple_stmt_iterator gsi_start_phis (basic_block);
gimple_seq gsi_split_seq_after (gimple_stmt_iterator);
-gimple_seq gsi_split_seq_before (gimple_stmt_iterator *);
+void gsi_split_seq_before (gimple_stmt_iterator *, gimple_seq *);
+void gsi_set_stmt (gimple_stmt_iterator *, gimple);
void gsi_replace (gimple_stmt_iterator *, gimple, bool);
+void gsi_replace_with_seq (gimple_stmt_iterator *, gimple_seq, bool);
void gsi_insert_before (gimple_stmt_iterator *, gimple,
enum gsi_iterator_update);
void gsi_insert_before_without_update (gimple_stmt_iterator *, gimple,
gimple walk_gimple_seq (gimple_seq, walk_stmt_fn, walk_tree_fn,
struct walk_stmt_info *);
+gimple walk_gimple_seq_mod (gimple_seq *, walk_stmt_fn, walk_tree_fn,
+ struct walk_stmt_info *);
tree walk_gimple_stmt (gimple_stmt_iterator *, walk_stmt_fn, walk_tree_fn,
struct walk_stmt_info *);
tree walk_gimple_op (gimple, walk_tree_fn, struct walk_stmt_info *);
gimple_alloc_kind_assign, /* Assignments. */
gimple_alloc_kind_phi, /* PHI nodes. */
gimple_alloc_kind_cond, /* Conditionals. */
- gimple_alloc_kind_seq, /* Sequences. */
gimple_alloc_kind_rest, /* Everything else. */
gimple_alloc_kind_all
};
if (gs == NULL)
return;
- if (*seq_p == NULL)
- *seq_p = gimple_seq_alloc ();
-
si = gsi_last (*seq_p);
-
gsi_insert_after_without_update (&si, gs, GSI_NEW_STMT);
}
if (src == NULL)
return;
- if (*dst_p == NULL)
- *dst_p = gimple_seq_alloc ();
-
si = gsi_last (*dst_p);
gsi_insert_seq_after_without_update (&si, src, GSI_NEW_STMT);
}
gtry = gimple_build_try (seq, gimple_wce_cleanup (wce), kind);
/* Do not use gsi_replace here, as it may scan operands.
We want to do a simple structural modification only. */
- *gsi_stmt_ptr (&iter) = gtry;
- iter = gsi_start (seq);
+ gsi_set_stmt (&iter, gtry);
+ iter = gsi_start (gtry->gimple_try.eval);
}
}
else
{
gimple_seq_node last;
- if (!*seq_p)
- *seq_p = gimple_seq_alloc ();
-
last = gimple_seq_last (*seq_p);
gimplify_expr (stmt_p, seq_p, NULL, is_gimple_stmt, fb_none);
return last != gimple_seq_last (*seq_p);
gimplify_omp_ctxp = ctx;
push_gimplify_context (&gctx);
- OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = gimple_seq_alloc ();
- OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = gimple_seq_alloc ();
+ OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
+ OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
gimplify_and_add (OMP_CLAUSE_REDUCTION_INIT (c),
&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
- for_body = gimple_seq_alloc ();
+ for_body = NULL;
gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
== TREE_VEC_LENGTH (OMP_FOR_COND (for_stmt)));
gcc_assert (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
/* The tree body of the function is no longer needed, replace it
with the new GIMPLE body. */
- seq = gimple_seq_alloc ();
+ seq = NULL;
gimple_seq_add_stmt (&seq, bind);
gimple_set_body (fndecl, seq);
/* Replace the current function body with the body
wrapped in the try/finally TF. */
- seq = gimple_seq_alloc ();
+ seq = NULL;
gimple_seq_add_stmt (&seq, new_bind);
gimple_set_body (fndecl, seq);
}
edge e = gimple_phi_arg_edge (phi, entry);
tree var;
gimple stmt;
- gimple_seq stmts;
- gimple_stmt_iterator gsi;
+ gimple_seq stmts = NULL;
if (tree_contains_chrecs (scev, NULL))
scev = gimple_phi_arg_def (phi, entry);
stmt = gimple_build_assign (res, var);
remove_phi_node (psi, false);
- if (!stmts)
- stmts = gimple_seq_alloc ();
-
- gsi = gsi_last (stmts);
- gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ gimple_seq_add_stmt (&stmts, stmt);
gsi_insert_seq_on_edge (e, stmts);
gsi_commit_edge_inserts ();
SSA_NAME_DEF_STMT (res) = stmt;
gimple_stmt_iterator gsi;
VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
- if (!stmts)
- stmts = gimple_seq_alloc ();
-
- gsi = gsi_last (stmts);
- gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ gimple_seq_add_stmt (&stmts, stmt);
for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
insert_out_of_ssa_copy (scop_p scop, tree res, tree expr, gimple after_stmt)
{
gimple_seq stmts;
- gimple_stmt_iterator si;
gimple_stmt_iterator gsi;
tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
gimple stmt = gimple_build_assign (res, var);
VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
- if (!stmts)
- stmts = gimple_seq_alloc ();
- si = gsi_last (stmts);
- gsi_insert_after (&si, stmt, GSI_NEW_STMT);
+ gimple_seq_add_stmt (&stmts, stmt);
for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
insert_out_of_ssa_copy_on_edge (scop_p scop, edge e, tree res, tree expr)
{
gimple_stmt_iterator gsi;
- gimple_seq stmts;
+ gimple_seq stmts = NULL;
tree var = force_gimple_operand (expr, &stmts, true, NULL_TREE);
gimple stmt = gimple_build_assign (res, var);
basic_block bb;
VEC (gimple, heap) *x = VEC_alloc (gimple, heap, 3);
- if (!stmts)
- stmts = gimple_seq_alloc ();
-
- gsi = gsi_last (stmts);
- gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ gimple_seq_add_stmt (&stmts, stmt);
for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi))
VEC_safe_push (gimple, heap, x, gsi_stmt (gsi));
visit_ref_for_mod_analysis,
visit_ref_for_mod_analysis);
}
- for (gsi = gsi_start (phi_nodes (bb)); !gsi_end_p (gsi); gsi_next (&gsi))
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
walk_stmt_load_store_addr_ops (gsi_stmt (gsi), info,
visit_ref_for_mod_analysis,
visit_ref_for_mod_analysis,
bb->il.gimple = ggc_alloc_cleared_gimple_bb_info ();
n_basic_blocks_for_function (fn)++;
bb->flags = 0;
- set_bb_seq (bb, gimple_seq_alloc ());
+ set_bb_seq (bb, NULL);
return bb;
}
return walk_tree (tp, scan_omp_1_op, &wi, NULL);
}
-static void lower_omp (gimple_seq, omp_context *);
+static void lower_omp (gimple_seq *, omp_context *);
static tree lookup_decl_in_outer_ctx (tree, omp_context *);
static tree maybe_lookup_decl_in_outer_ctx (tree, omp_context *);
{
struct function *child_cfun;
tree child_fn, old_fn;
- gimple_seq seq, new_seq;
+ gimple_seq seq = NULL, new_seq;
gimple bind;
child_fn = gimple_omp_task_copy_fn (task_stmt);
push_cfun (child_cfun);
current_function_decl = child_fn;
bind = gimplify_body (child_fn, false);
- seq = gimple_seq_alloc ();
gimple_seq_add_stmt (&seq, bind);
new_seq = maybe_catch_exception (seq);
if (new_seq != seq)
{
bind = gimple_build_bind (NULL, new_seq, NULL);
- seq = gimple_seq_alloc ();
+ seq = NULL;
gimple_seq_add_stmt (&seq, bind);
}
gimple_set_body (child_fn, seq);
lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
omp_context *ctx)
{
- gimple_stmt_iterator diter;
tree c, dtor, copyin_seq, x, ptr;
bool copyin_by_ref = false;
bool lastprivate_firstprivate = false;
int pass;
- *dlist = gimple_seq_alloc ();
- diter = gsi_start (*dlist);
copyin_seq = NULL;
/* Do all the fixed sized types in the first pass, and the variable sized
dtor = x;
gimplify_stmt (&dtor, &tseq);
- gsi_insert_seq_before (&diter, tseq, GSI_SAME_STMT);
+ gimple_seq_add_seq (dlist, tseq);
}
break;
x = build_fold_addr_expr_loc (clause_loc, x);
SET_DECL_VALUE_EXPR (placeholder, x);
DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
- lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
+ lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c), ctx);
gimple_seq_add_seq (ilist,
OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c));
OMP_CLAUSE_REDUCTION_GIMPLE_INIT (c) = NULL;
if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
{
- lower_omp (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
+ lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
gimple_seq_add_seq (stmt_list,
OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
}
ref = build_fold_addr_expr_loc (clause_loc, ref);
SET_DECL_VALUE_EXPR (placeholder, ref);
DECL_HAS_VALUE_EXPR_P (placeholder) = 1;
- lower_omp (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
+ lower_omp (&OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c), ctx);
gimple_seq_add_seq (&sub_seq, OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c));
OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (c) = NULL;
OMP_CLAUSE_REDUCTION_PLACEHOLDER (c) = NULL;
&& !DECL_EXTERNAL (t))
varpool_finalize_decl (t);
DECL_SAVED_TREE (child_fn) = NULL;
- gimple_set_body (child_fn, bb_seq (single_succ (entry_bb)));
+ /* We'll create a CFG for child_fn, so no gimple body is needed. */
+ gimple_set_body (child_fn, NULL);
TREE_USED (block) = 1;
/* Reset DECL_CONTEXT on function arguments. */
{
tree block, control;
gimple_stmt_iterator tgsi;
- unsigned i, len;
gimple stmt, new_stmt, bind, t;
- gimple_seq ilist, dlist, olist, new_body, body;
+ gimple_seq ilist, dlist, olist, new_body;
struct gimplify_ctx gctx;
stmt = gsi_stmt (*gsi_p);
lower_rec_input_clauses (gimple_omp_sections_clauses (stmt),
&ilist, &dlist, ctx);
- tgsi = gsi_start (gimple_omp_body (stmt));
- for (len = 0; !gsi_end_p (tgsi); len++, gsi_next (&tgsi))
- continue;
-
- tgsi = gsi_start (gimple_omp_body (stmt));
- body = NULL;
- for (i = 0; i < len; i++, gsi_next (&tgsi))
+ new_body = gimple_omp_body (stmt);
+ gimple_omp_set_body (stmt, NULL);
+ tgsi = gsi_start (new_body);
+ for (; !gsi_end_p (tgsi); gsi_next (&tgsi))
{
omp_context *sctx;
gimple sec_start;
sctx = maybe_lookup_ctx (sec_start);
gcc_assert (sctx);
- gimple_seq_add_stmt (&body, sec_start);
-
- lower_omp (gimple_omp_body (sec_start), sctx);
- gimple_seq_add_seq (&body, gimple_omp_body (sec_start));
+ lower_omp (gimple_omp_body_ptr (sec_start), sctx);
+ gsi_insert_seq_after (&tgsi, gimple_omp_body (sec_start),
+ GSI_CONTINUE_LINKING);
gimple_omp_set_body (sec_start, NULL);
- if (i == len - 1)
+ if (gsi_one_before_end_p (tgsi))
{
gimple_seq l = NULL;
lower_lastprivate_clauses (gimple_omp_sections_clauses (stmt), NULL,
&l, ctx);
- gimple_seq_add_seq (&body, l);
+ gsi_insert_seq_after (&tgsi, l, GSI_CONTINUE_LINKING);
gimple_omp_section_set_last (sec_start);
}
- gimple_seq_add_stmt (&body, gimple_build_omp_return (false));
+ gsi_insert_after (&tgsi, gimple_build_omp_return (false),
+ GSI_CONTINUE_LINKING);
}
block = make_node (BLOCK);
- bind = gimple_build_bind (NULL, body, block);
+ bind = gimple_build_bind (NULL, new_body, block);
olist = NULL;
lower_reduction_clauses (gimple_omp_sections_clauses (stmt), &olist, ctx);
block = make_node (BLOCK);
new_stmt = gimple_build_bind (NULL, NULL, block);
+ gsi_replace (gsi_p, new_stmt, true);
pop_gimplify_context (new_stmt);
gimple_bind_append_vars (new_stmt, ctx->block_vars);
gimple_seq_add_stmt (&new_body, t);
gimple_bind_set_body (new_stmt, new_body);
- gimple_omp_set_body (stmt, NULL);
-
- gsi_replace (gsi_p, new_stmt, true);
}
push_gimplify_context (&gctx);
+ block = make_node (BLOCK);
+ bind = gimple_build_bind (NULL, NULL, block);
+ gsi_replace (gsi_p, bind, true);
bind_body = NULL;
+ dlist = NULL;
lower_rec_input_clauses (gimple_omp_single_clauses (single_stmt),
&bind_body, &dlist, ctx);
- lower_omp (gimple_omp_body (single_stmt), ctx);
+ lower_omp (gimple_omp_body_ptr (single_stmt), ctx);
gimple_seq_add_stmt (&bind_body, single_stmt);
(!!find_omp_clause (gimple_omp_single_clauses (single_stmt),
OMP_CLAUSE_NOWAIT));
gimple_seq_add_stmt (&bind_body, t);
-
- block = make_node (BLOCK);
- bind = gimple_build_bind (NULL, bind_body, block);
+ gimple_bind_set_body (bind, bind_body);
pop_gimplify_context (bind);
gimple_bind_append_vars (bind, ctx->block_vars);
BLOCK_VARS (block) = ctx->block_vars;
- gsi_replace (gsi_p, bind, true);
if (BLOCK_VARS (block))
TREE_USED (block) = 1;
}
push_gimplify_context (&gctx);
block = make_node (BLOCK);
- bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
- block);
+ bind = gimple_build_bind (NULL, NULL, block);
+ gsi_replace (gsi_p, bind, true);
+ gimple_bind_add_stmt (bind, stmt);
bfn_decl = builtin_decl_explicit (BUILT_IN_OMP_GET_THREAD_NUM);
x = build_call_expr_loc (loc, bfn_decl, 0);
gimplify_and_add (x, &tseq);
gimple_bind_add_seq (bind, tseq);
- lower_omp (gimple_omp_body (stmt), ctx);
+ lower_omp (gimple_omp_body_ptr (stmt), ctx);
gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
gimple_bind_add_seq (bind, gimple_omp_body (stmt));
gimple_omp_set_body (stmt, NULL);
gimple_bind_append_vars (bind, ctx->block_vars);
BLOCK_VARS (block) = ctx->block_vars;
- gsi_replace (gsi_p, bind, true);
}
push_gimplify_context (&gctx);
block = make_node (BLOCK);
- bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt),
- block);
+ bind = gimple_build_bind (NULL, NULL, block);
+ gsi_replace (gsi_p, bind, true);
+ gimple_bind_add_stmt (bind, stmt);
x = gimple_build_call (builtin_decl_explicit (BUILT_IN_GOMP_ORDERED_START),
0);
gimple_bind_add_stmt (bind, x);
- lower_omp (gimple_omp_body (stmt), ctx);
+ lower_omp (gimple_omp_body_ptr (stmt), ctx);
gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
gimple_bind_add_seq (bind, gimple_omp_body (stmt));
gimple_omp_set_body (stmt, NULL);
gimple_bind_append_vars (bind, ctx->block_vars);
BLOCK_VARS (block) = gimple_bind_vars (bind);
- gsi_replace (gsi_p, bind, true);
}
push_gimplify_context (&gctx);
block = make_node (BLOCK);
- bind = gimple_build_bind (NULL, gimple_seq_alloc_with_stmt (stmt), block);
+ bind = gimple_build_bind (NULL, NULL, block);
+ gsi_replace (gsi_p, bind, true);
+ gimple_bind_add_stmt (bind, stmt);
tbody = gimple_bind_body (bind);
gimplify_and_add (lock, &tbody);
gimple_bind_set_body (bind, tbody);
- lower_omp (gimple_omp_body (stmt), ctx);
+ lower_omp (gimple_omp_body_ptr (stmt), ctx);
gimple_omp_set_body (stmt, maybe_catch_exception (gimple_omp_body (stmt)));
gimple_bind_add_seq (bind, gimple_omp_body (stmt));
gimple_omp_set_body (stmt, NULL);
pop_gimplify_context (bind);
gimple_bind_append_vars (bind, ctx->block_vars);
BLOCK_VARS (block) = gimple_bind_vars (bind);
- gsi_replace (gsi_p, bind, true);
}
push_gimplify_context (&gctx);
- lower_omp (gimple_omp_for_pre_body (stmt), ctx);
- lower_omp (gimple_omp_body (stmt), ctx);
+ lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
+ lower_omp (gimple_omp_body_ptr (stmt), ctx);
block = make_node (BLOCK);
new_stmt = gimple_build_bind (NULL, NULL, block);
+ /* Replace at gsi right away, so that 'stmt' is no member
+ of a sequence anymore as we're going to add to to a different
+ one below. */
+ gsi_replace (gsi_p, new_stmt, true);
/* Move declaration of temporaries in the loop body before we make
it go away. */
gimple_bind_set_body (new_stmt, body);
gimple_omp_set_body (stmt, NULL);
gimple_omp_for_set_pre_body (stmt, NULL);
- gsi_replace (gsi_p, new_stmt, true);
}
/* Callback for walk_stmts. Check if the current statement only contains
par_olist = NULL;
par_ilist = NULL;
lower_rec_input_clauses (clauses, &par_ilist, &par_olist, ctx);
- lower_omp (par_body, ctx);
+ lower_omp (&par_body, ctx);
if (gimple_code (stmt) == GIMPLE_OMP_PARALLEL)
lower_reduction_clauses (clauses, &par_olist, ctx);
gimple_omp_set_body (stmt, new_body);
bind = gimple_build_bind (NULL, NULL, gimple_bind_block (par_bind));
- gimple_bind_add_stmt (bind, stmt);
- if (ilist || olist)
- {
- gimple_seq_add_stmt (&ilist, bind);
- gimple_seq_add_seq (&ilist, olist);
- bind = gimple_build_bind (NULL, ilist, NULL);
- }
-
gsi_replace (gsi_p, bind, true);
+ gimple_bind_add_seq (bind, ilist);
+ gimple_bind_add_stmt (bind, stmt);
+ gimple_bind_add_seq (bind, olist);
pop_gimplify_context (NULL);
}
gimple_regimplify_operands (stmt, gsi_p);
break;
case GIMPLE_CATCH:
- lower_omp (gimple_catch_handler (stmt), ctx);
+ lower_omp (gimple_catch_handler_ptr (stmt), ctx);
break;
case GIMPLE_EH_FILTER:
- lower_omp (gimple_eh_filter_failure (stmt), ctx);
+ lower_omp (gimple_eh_filter_failure_ptr (stmt), ctx);
break;
case GIMPLE_TRY:
- lower_omp (gimple_try_eval (stmt), ctx);
- lower_omp (gimple_try_cleanup (stmt), ctx);
+ lower_omp (gimple_try_eval_ptr (stmt), ctx);
+ lower_omp (gimple_try_cleanup_ptr (stmt), ctx);
break;
case GIMPLE_BIND:
- lower_omp (gimple_bind_body (stmt), ctx);
+ lower_omp (gimple_bind_body_ptr (stmt), ctx);
break;
case GIMPLE_OMP_PARALLEL:
case GIMPLE_OMP_TASK:
}
static void
-lower_omp (gimple_seq body, omp_context *ctx)
+lower_omp (gimple_seq *body, omp_context *ctx)
{
location_t saved_location = input_location;
- gimple_stmt_iterator gsi = gsi_start (body);
- for (gsi = gsi_start (body); !gsi_end_p (gsi); gsi_next (&gsi))
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi))
lower_omp_1 (&gsi, ctx);
input_location = saved_location;
}
if (task_shared_vars)
push_gimplify_context (&gctx);
- lower_omp (body, NULL);
+ lower_omp (&body, NULL);
if (task_shared_vars)
pop_gimplify_context (NULL);
}
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
wi->info = stmt;
- walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
+ walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
wi->info = context;
break;
wi->info = stmt;
/* gimple_omp_for_{index,initial,final} are all DECLs; no need to
walk them. */
- walk_gimple_seq (gimple_omp_for_pre_body (stmt),
- diagnose_sb_2, NULL, wi);
- walk_gimple_seq (gimple_omp_body (stmt), diagnose_sb_2, NULL, wi);
+ walk_gimple_seq_mod (gimple_omp_for_pre_body_ptr (stmt),
+ diagnose_sb_2, NULL, wi);
+ walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), diagnose_sb_2, NULL, wi);
wi->info = context;
break;
memset (&wi, 0, sizeof (wi));
wi.want_locations = true;
- walk_gimple_seq (body, diagnose_sb_2, NULL, &wi);
+ walk_gimple_seq_mod (&body, diagnose_sb_2, NULL, &wi);
+
+ gimple_set_body (current_function_decl, body);
splay_tree_delete (all_labels);
all_labels = NULL;
us some idea of what we're dealing with. */
memset (&this_wi, 0, sizeof (this_wi));
this_wi.info = (void *) &this_state;
- walk_gimple_seq (gimple_transaction_body (stmt),
- lower_sequence_tm, NULL, &this_wi);
+ walk_gimple_seq_mod (gimple_transaction_body_ptr (stmt),
+ lower_sequence_tm, NULL, &this_wi);
/* If there was absolutely nothing transaction related inside the
transaction, we may elide it. Likewise if this is a nested
gimple_seq n_seq, e_seq;
n_seq = gimple_seq_alloc_with_stmt (g);
- e_seq = gimple_seq_alloc ();
+ e_seq = NULL;
g = gimple_build_call (builtin_decl_explicit (BUILT_IN_EH_POINTER),
1, integer_zero_node);
execute_lower_tm (void)
{
struct walk_stmt_info wi;
+ gimple_seq body;
/* Transactional clones aren't created until a later pass. */
gcc_assert (!decl_is_tm_clone (current_function_decl));
+ body = gimple_body (current_function_decl);
memset (&wi, 0, sizeof (wi));
- walk_gimple_seq (gimple_body (current_function_decl),
- lower_sequence_no_tm, NULL, &wi);
+ walk_gimple_seq_mod (&body, lower_sequence_no_tm, NULL, &wi);
+ gimple_set_body (current_function_decl, body);
return 0;
}
if (start_new_block || stmt_starts_bb_p (stmt, prev_stmt))
{
if (!first_stmt_of_seq)
- seq = gsi_split_seq_before (&i);
+ gsi_split_seq_before (&i, &seq);
bb = create_basic_block (seq, NULL, bb);
start_new_block = false;
}
bb->index = last_basic_block;
bb->flags = BB_NEW;
bb->il.gimple = ggc_alloc_cleared_gimple_bb_info ();
- set_bb_seq (bb, h ? (gimple_seq) h : gimple_seq_alloc ());
+ set_bb_seq (bb, h ? (gimple_seq) h : NULL);
/* Add the new block to the linked list of blocks. */
link_block (bb, after);
gimple_merge_blocks (basic_block a, basic_block b)
{
gimple_stmt_iterator last, gsi, psi;
- gimple_seq phis = phi_nodes (b);
if (dump_file)
fprintf (dump_file, "Merging blocks %d and %d\n", a->index, b->index);
/* Remove all single-valued PHI nodes from block B of the form
V_i = PHI <V_j> by propagating V_j to all the uses of V_i. */
gsi = gsi_last_bb (a);
- for (psi = gsi_start (phis); !gsi_end_p (psi); )
+ for (psi = gsi_start_phis (b); !gsi_end_p (psi); )
{
gimple phi = gsi_stmt (psi);
tree def = gimple_phi_result (phi), use = gimple_phi_arg_def (phi, 0);
brings ugly quadratic memory consumption in the inliner.
(We are still quadratic since we need to update stmt BB pointers,
sadly.) */
- list = gsi_split_seq_before (&gsi);
+ gsi_split_seq_before (&gsi, &list);
set_bb_seq (new_bb, list);
for (gsi_tgt = gsi_start (list);
!gsi_end_p (gsi_tgt); gsi_next (&gsi_tgt))
p->remap_decls_p = false;
*handled_ops_p = true;
- walk_gimple_seq (gimple_omp_body (stmt), move_stmt_r,
- move_stmt_op, wi);
+ walk_gimple_seq_mod (gimple_omp_body_ptr (stmt), move_stmt_r,
+ move_stmt_op, wi);
p->remap_decls_p = save_remap_decls_p;
}
static void
update_complex_assignment (gimple_stmt_iterator *gsi, tree r, tree i)
{
- gimple_stmt_iterator orig_si = *gsi;
gimple stmt;
- if (gimple_in_ssa_p (cfun))
- update_complex_components (gsi, gsi_stmt (*gsi), r, i);
-
- gimple_assign_set_rhs_with_ops (&orig_si, COMPLEX_EXPR, r, i);
- stmt = gsi_stmt (orig_si);
+ gimple_assign_set_rhs_with_ops (gsi, COMPLEX_EXPR, r, i);
+ stmt = gsi_stmt (*gsi);
update_stmt (stmt);
if (maybe_clean_eh_stmt (stmt))
gimple_purge_dead_eh_edges (gimple_bb (stmt));
+
+ if (gimple_in_ssa_p (cfun))
+ update_complex_components (gsi, gsi_stmt (*gsi), r, i);
}
#define LARGE_GOTO_QUEUE 20
-static void lower_eh_constructs_1 (struct leh_state *state, gimple_seq seq);
+static void lower_eh_constructs_1 (struct leh_state *state, gimple_seq *seq);
static gimple_seq
find_goto_replacement (struct leh_tf_state *tf, treemple stmt)
/* The real work of replace_goto_queue. Returns with TSI updated to
point to the next statement. */
-static void replace_goto_queue_stmt_list (gimple_seq, struct leh_tf_state *);
+static void replace_goto_queue_stmt_list (gimple_seq *, struct leh_tf_state *);
static void
replace_goto_queue_1 (gimple stmt, struct leh_tf_state *tf,
break;
case GIMPLE_TRY:
- replace_goto_queue_stmt_list (gimple_try_eval (stmt), tf);
- replace_goto_queue_stmt_list (gimple_try_cleanup (stmt), tf);
+ replace_goto_queue_stmt_list (gimple_try_eval_ptr (stmt), tf);
+ replace_goto_queue_stmt_list (gimple_try_cleanup_ptr (stmt), tf);
break;
case GIMPLE_CATCH:
- replace_goto_queue_stmt_list (gimple_catch_handler (stmt), tf);
+ replace_goto_queue_stmt_list (gimple_catch_handler_ptr (stmt), tf);
break;
case GIMPLE_EH_FILTER:
- replace_goto_queue_stmt_list (gimple_eh_filter_failure (stmt), tf);
+ replace_goto_queue_stmt_list (gimple_eh_filter_failure_ptr (stmt), tf);
break;
case GIMPLE_EH_ELSE:
- replace_goto_queue_stmt_list (gimple_eh_else_n_body (stmt), tf);
- replace_goto_queue_stmt_list (gimple_eh_else_e_body (stmt), tf);
+ replace_goto_queue_stmt_list (gimple_eh_else_n_body_ptr (stmt), tf);
+ replace_goto_queue_stmt_list (gimple_eh_else_e_body_ptr (stmt), tf);
break;
default:
/* A subroutine of replace_goto_queue. Handles GIMPLE_SEQ. */
static void
-replace_goto_queue_stmt_list (gimple_seq seq, struct leh_tf_state *tf)
+replace_goto_queue_stmt_list (gimple_seq *seq, struct leh_tf_state *tf)
{
- gimple_stmt_iterator gsi = gsi_start (seq);
+ gimple_stmt_iterator gsi = gsi_start (*seq);
while (!gsi_end_p (gsi))
replace_goto_queue_1 (gsi_stmt (gsi), tf, &gsi);
{
if (tf->goto_queue_active == 0)
return;
- replace_goto_queue_stmt_list (tf->top_p_seq, tf);
- replace_goto_queue_stmt_list (eh_seq, tf);
+ replace_goto_queue_stmt_list (&tf->top_p_seq, tf);
+ replace_goto_queue_stmt_list (&eh_seq, tf);
}
/* Add a new record to the goto queue contained in TF. NEW_STMT is the
q->cont_stmt = q->stmt.g;
- if (!q->repl_stmt)
- q->repl_stmt = gimple_seq_alloc ();
-
if (mod)
gimple_seq_add_seq (&q->repl_stmt, mod);
gimple x;
gcc_assert (q->is_label);
- if (!q->repl_stmt)
- q->repl_stmt = gimple_seq_alloc ();
q->cont_stmt = gimple_build_goto (VEC_index (tree, tf->dest_array, q->index));
if (eh_else)
{
finally = gimple_eh_else_n_body (eh_else);
- lower_eh_constructs_1 (state, finally);
+ lower_eh_constructs_1 (state, &finally);
gimple_seq_add_seq (&tf->top_p_seq, finally);
if (tf->may_throw)
{
finally = gimple_eh_else_e_body (eh_else);
- lower_eh_constructs_1 (state, finally);
+ lower_eh_constructs_1 (state, &finally);
emit_post_landing_pad (&eh_seq, tf->region);
gimple_seq_add_seq (&eh_seq, finally);
}
else
{
- lower_eh_constructs_1 (state, finally);
+ lower_eh_constructs_1 (state, &finally);
gimple_seq_add_seq (&tf->top_p_seq, finally);
if (tf->may_throw)
finally = gimple_eh_else_n_body (x);
}
- lower_eh_constructs_1 (state, finally);
+ lower_eh_constructs_1 (state, &finally);
if (tf->may_throw)
{
if (tf->may_fallthru)
{
seq = lower_try_finally_dup_block (finally, state);
- lower_eh_constructs_1 (state, seq);
+ lower_eh_constructs_1 (state, &seq);
gimple_seq_add_seq (&new_stmt, seq);
tmp = lower_try_finally_fallthru_label (tf);
seq = gimple_eh_else_e_body (eh_else);
else
seq = lower_try_finally_dup_block (finally, state);
- lower_eh_constructs_1 (state, seq);
+ lower_eh_constructs_1 (state, &seq);
emit_post_landing_pad (&eh_seq, tf->region);
gimple_seq_add_seq (&eh_seq, seq);
gimple_seq_add_stmt (&new_stmt, x);
seq = lower_try_finally_dup_block (finally, state);
- lower_eh_constructs_1 (state, seq);
+ lower_eh_constructs_1 (state, &seq);
gimple_seq_add_seq (&new_stmt, seq);
gimple_seq_add_stmt (&new_stmt, q->cont_stmt);
int nlabels, ndests, j, last_case_index;
tree last_case;
VEC (tree,heap) *case_label_vec;
- gimple_seq switch_body;
+ gimple_seq switch_body = NULL;
gimple x, eh_else;
tree tmp;
gimple switch_stmt;
/* The location of the finally block. */
location_t finally_loc;
- switch_body = gimple_seq_alloc ();
finally = gimple_try_cleanup (tf->top_p);
eh_else = get_eh_else (finally);
: tf_loc;
/* Lower the finally block itself. */
- lower_eh_constructs_1 (state, finally);
+ lower_eh_constructs_1 (state, &finally);
/* Prepare for switch statement generation. */
nlabels = VEC_length (tree, tf->dest_array);
if (tf->may_throw)
{
finally = gimple_eh_else_e_body (eh_else);
- lower_eh_constructs_1 (state, finally);
+ lower_eh_constructs_1 (state, &finally);
emit_post_landing_pad (&eh_seq, tf->region);
gimple_seq_add_seq (&eh_seq, finally);
entrance through a particular edge. */
for (; q < qe; ++q)
{
- gimple_seq mod;
+ gimple_seq mod = NULL;
int switch_id;
unsigned int case_index;
- mod = gimple_seq_alloc ();
-
if (q->index < 0)
{
x = gimple_build_assign (finally_tmp,
old_eh_seq = eh_seq;
eh_seq = NULL;
- lower_eh_constructs_1 (&this_state, gimple_try_eval(tp));
+ lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
/* Determine if the try block is escaped through the bottom. */
this_tf.may_fallthru = gimple_seq_may_fallthru (gimple_try_eval (tp));
struct leh_state this_state = *state;
gimple_stmt_iterator gsi;
tree out_label;
- gimple_seq new_seq;
+ gimple_seq new_seq, cleanup;
gimple x;
location_t try_catch_loc = gimple_location (tp);
this_state.cur_region = try_region;
}
- lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
+ lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
if (!eh_region_may_contain_throw (try_region))
return gimple_try_eval (tp);
this_state.ehp_region = try_region;
out_label = NULL;
- for (gsi = gsi_start (gimple_try_cleanup (tp));
+ cleanup = gimple_try_cleanup (tp);
+ for (gsi = gsi_start (cleanup);
!gsi_end_p (gsi);
gsi_next (&gsi))
{
c = gen_eh_region_catch (try_region, gimple_catch_types (gcatch));
handler = gimple_catch_handler (gcatch);
- lower_eh_constructs_1 (&this_state, handler);
+ lower_eh_constructs_1 (&this_state, &handler);
c->label = create_artificial_label (UNKNOWN_LOCATION);
x = gimple_build_label (c->label);
this_state.cur_region = this_region;
}
- lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
+ lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
if (!eh_region_may_contain_throw (this_region))
return gimple_try_eval (tp);
x = gimple_build_label (this_region->u.allowed.label);
gimple_seq_add_stmt (&new_seq, x);
- lower_eh_constructs_1 (&this_state, gimple_eh_filter_failure (inner));
+ lower_eh_constructs_1 (&this_state, gimple_eh_filter_failure_ptr (inner));
gimple_seq_add_seq (&new_seq, gimple_eh_filter_failure (inner));
gimple_try_set_cleanup (tp, new_seq);
this_state.cur_region = this_region;
}
- lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
+ lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
return gimple_try_eval (tp);
}
this_state.cur_region = this_region;
}
- lower_eh_constructs_1 (&this_state, gimple_try_eval (tp));
+ lower_eh_constructs_1 (&this_state, gimple_try_eval_ptr (tp));
if (cleanup_dead || !eh_region_may_contain_throw (this_region))
return gimple_try_eval (tp);
{
/* In this case honor_protect_cleanup_actions had nothing to do,
and we should process this normally. */
- lower_eh_constructs_1 (state, gimple_try_cleanup (tp));
+ lower_eh_constructs_1 (state, gimple_try_cleanup_ptr (tp));
result = frob_into_branch_around (tp, this_region,
fake_tf.fallthru_label);
}
if (!x)
{
replace = gimple_try_eval (stmt);
- lower_eh_constructs_1 (state, replace);
+ lower_eh_constructs_1 (state, &replace);
}
else
switch (gimple_code (x))
/* A helper to unwrap a gimple_seq and feed stmts to lower_eh_constructs_2. */
static void
-lower_eh_constructs_1 (struct leh_state *state, gimple_seq seq)
+lower_eh_constructs_1 (struct leh_state *state, gimple_seq *pseq)
{
gimple_stmt_iterator gsi;
- for (gsi = gsi_start (seq); !gsi_end_p (gsi);)
+ for (gsi = gsi_start (*pseq); !gsi_end_p (gsi);)
lower_eh_constructs_2 (state, &gsi);
}
memset (&null_state, 0, sizeof (null_state));
collect_finally_tree_1 (bodyp, NULL);
- lower_eh_constructs_1 (&null_state, bodyp);
+ lower_eh_constructs_1 (&null_state, &bodyp);
+ gimple_set_body (current_function_decl, bodyp);
/* We assume there's a return statement, or something, at the end of
the function, and thus ploping the EH sequence afterward won't
{
gimple oneh;
gimple_stmt_iterator gsi;
+ gimple_seq cleanup;
- gsi = gsi_start (gimple_try_cleanup (one));
+ cleanup = gimple_try_cleanup (one);
+ gsi = gsi_start (cleanup);
if (!gsi_one_before_end_p (gsi))
return;
return bb->il.gimple->phi_nodes;
}
+static inline gimple_seq *
+phi_nodes_ptr (const_basic_block bb)
+{
+ gcc_checking_assert (!(bb->flags & BB_RTL));
+ if (!bb->il.gimple)
+ return NULL;
+ return &bb->il.gimple->phi_nodes;
+}
+
/* Set PHI nodes of a basic block BB to SEQ. */
static inline void
edge new_edge;
bool inserted = false;
- for (si = gsi_start (phi_nodes (bb)); !gsi_end_p (si); gsi_next (&si))
+ for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
tree res, new_res;
gimple new_phi;
mf_decl_cache_locals (void)
{
gimple g;
- gimple_seq seq = gimple_seq_alloc ();
+ gimple_seq seq = NULL;
/* Build the cache vars. */
mf_cache_shift_decl_l
mf_limit = make_rename_temp (mf_uintptr_type, "__mf_limit");
/* Build: __mf_base = (uintptr_t) <base address expression>. */
- seq = gimple_seq_alloc ();
+ seq = NULL;
t = fold_convert_loc (location, mf_uintptr_type,
unshare_expr (base));
t = force_gimple_operand (t, &stmts, false, NULL_TREE);
This is the body of the conditional. */
- seq = gimple_seq_alloc ();
+ seq = NULL;
/* u is a string, so it is already a gimple value. */
u = mf_file_function_line_tree (location);
/* NB: we pass the overall [base..limit] range to mf_check. */
gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
e = split_block (then_bb, g);
then_bb = e->dest;
- seq = gimple_seq_alloc ();
+ seq = NULL;
}
g = gimple_build_assign (mf_cache_shift_decl_l, mf_cache_shift_decl);
if (finally_stmts != NULL)
{
gimple stmt = gimple_build_try (seq, finally_stmts, GIMPLE_TRY_FINALLY);
- gimple_seq new_seq = gimple_seq_alloc ();
+ gimple_seq new_seq = NULL;
gimple_seq_add_stmt (&new_seq, stmt);
return new_seq;
return field;
}
-/* Invoke CALLBACK on all statements of GIMPLE sequence SEQ. */
+/* Invoke CALLBACK on all statements of GIMPLE sequence *PSEQ. */
static void
walk_body (walk_stmt_fn callback_stmt, walk_tree_fn callback_op,
- struct nesting_info *info, gimple_seq seq)
+ struct nesting_info *info, gimple_seq *pseq)
{
struct walk_stmt_info wi;
memset (&wi, 0, sizeof (wi));
wi.info = info;
wi.val_only = true;
- walk_gimple_seq (seq, callback_stmt, callback_op, &wi);
+ walk_gimple_seq_mod (pseq, callback_stmt, callback_op, &wi);
}
walk_function (walk_stmt_fn callback_stmt, walk_tree_fn callback_op,
struct nesting_info *info)
{
- walk_body (callback_stmt, callback_op, info, gimple_body (info->context));
+ gimple_seq body = gimple_body (info->context);
+ walk_body (callback_stmt, callback_op, info, &body);
+ gimple_set_body (info->context, body);
}
/* Invoke CALLBACK on a GIMPLE_OMP_FOR's init, cond, incr and pre-body. */
tree t;
size_t i;
- walk_body (callback_stmt, callback_op, info, gimple_omp_for_pre_body (for_stmt));
+ walk_body (callback_stmt, callback_op, info, gimple_omp_for_pre_body_ptr (for_stmt));
- seq = gimple_seq_alloc ();
+ seq = NULL;
memset (&wi, 0, sizeof (wi));
wi.info = info;
wi.gsi = gsi_last (seq);
walk_tree (&TREE_OPERAND (t, 1), callback_op, &wi, NULL);
}
- if (gimple_seq_empty_p (seq))
- gimple_seq_free (seq);
- else
+ seq = gsi_seq (wi.gsi);
+ if (!gimple_seq_empty_p (seq))
{
gimple_seq pre_body = gimple_omp_for_pre_body (for_stmt);
annotate_all_with_location (seq, gimple_location (for_stmt));
= info->context;
walk_body (convert_nonlocal_reference_stmt,
convert_nonlocal_reference_op, info,
- OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause));
+ &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause));
walk_body (convert_nonlocal_reference_stmt,
convert_nonlocal_reference_op, info,
- OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause));
+ &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause));
DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
= old_context;
}
case OMP_CLAUSE_LASTPRIVATE:
walk_body (convert_nonlocal_reference_stmt,
convert_nonlocal_reference_op, info,
- OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
+ &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
break;
default:
info->new_local_var_chain = NULL;
walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
- info, gimple_omp_body (stmt));
+ info, gimple_omp_body_ptr (stmt));
if (info->new_local_var_chain)
declare_vars (info->new_local_var_chain,
walk_gimple_omp_for (stmt, convert_nonlocal_reference_stmt,
convert_nonlocal_reference_op, info);
walk_body (convert_nonlocal_reference_stmt,
- convert_nonlocal_reference_op, info, gimple_omp_body (stmt));
+ convert_nonlocal_reference_op, info, gimple_omp_body_ptr (stmt));
info->suppress_expansion = save_suppress;
break;
save_suppress = info->suppress_expansion;
convert_nonlocal_omp_clauses (gimple_omp_sections_clauses_ptr (stmt), wi);
walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
- info, gimple_omp_body (stmt));
+ info, gimple_omp_body_ptr (stmt));
info->suppress_expansion = save_suppress;
break;
save_suppress = info->suppress_expansion;
convert_nonlocal_omp_clauses (gimple_omp_single_clauses_ptr (stmt), wi);
walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
- info, gimple_omp_body (stmt));
+ info, gimple_omp_body_ptr (stmt));
info->suppress_expansion = save_suppress;
break;
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_ORDERED:
walk_body (convert_nonlocal_reference_stmt, convert_nonlocal_reference_op,
- info, gimple_omp_body (stmt));
+ info, gimple_omp_body_ptr (stmt));
break;
case GIMPLE_BIND:
= info->context;
walk_body (convert_local_reference_stmt,
convert_local_reference_op, info,
- OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause));
+ &OMP_CLAUSE_REDUCTION_GIMPLE_INIT (clause));
walk_body (convert_local_reference_stmt,
convert_local_reference_op, info,
- OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause));
+ &OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (clause));
DECL_CONTEXT (OMP_CLAUSE_REDUCTION_PLACEHOLDER (clause))
= old_context;
}
case OMP_CLAUSE_LASTPRIVATE:
walk_body (convert_local_reference_stmt,
convert_local_reference_op, info,
- OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
+ &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
break;
default:
info->new_local_var_chain = NULL;
walk_body (convert_local_reference_stmt, convert_local_reference_op, info,
- gimple_omp_body (stmt));
+ gimple_omp_body_ptr (stmt));
if (info->new_local_var_chain)
declare_vars (info->new_local_var_chain,
walk_gimple_omp_for (stmt, convert_local_reference_stmt,
convert_local_reference_op, info);
walk_body (convert_local_reference_stmt, convert_local_reference_op,
- info, gimple_omp_body (stmt));
+ info, gimple_omp_body_ptr (stmt));
info->suppress_expansion = save_suppress;
break;
save_suppress = info->suppress_expansion;
convert_local_omp_clauses (gimple_omp_sections_clauses_ptr (stmt), wi);
walk_body (convert_local_reference_stmt, convert_local_reference_op,
- info, gimple_omp_body (stmt));
+ info, gimple_omp_body_ptr (stmt));
info->suppress_expansion = save_suppress;
break;
save_suppress = info->suppress_expansion;
convert_local_omp_clauses (gimple_omp_single_clauses_ptr (stmt), wi);
walk_body (convert_local_reference_stmt, convert_local_reference_op,
- info, gimple_omp_body (stmt));
+ info, gimple_omp_body_ptr (stmt));
info->suppress_expansion = save_suppress;
break;
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_ORDERED:
walk_body (convert_local_reference_stmt, convert_local_reference_op,
- info, gimple_omp_body (stmt));
+ info, gimple_omp_body_ptr (stmt));
break;
case GIMPLE_COND:
/* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field). */
field = get_nl_goto_field (i);
- x = get_frame_field (info, target_context, field, &wi->gsi);
+ x = get_frame_field (info, target_context, field, gsi);
x = build_addr (x, target_context);
- x = gsi_gimplify_val (info, x, &wi->gsi);
+ x = gsi_gimplify_val (info, x, gsi);
call = gimple_build_call (builtin_decl_implicit (BUILT_IN_NONLOCAL_GOTO),
2, build_addr (new_label, target_context), x);
- gsi_replace (&wi->gsi, call, false);
+ gsi_replace (gsi, call, false);
/* We have handled all of STMT's operands, no need to keep going. */
*handled_ops_p = true;
save_local_var_chain = info->new_local_var_chain;
info->new_local_var_chain = NULL;
walk_body (convert_tramp_reference_stmt, convert_tramp_reference_op,
- info, gimple_omp_body (stmt));
+ info, gimple_omp_body_ptr (stmt));
if (info->new_local_var_chain)
declare_vars (info->new_local_var_chain,
gimple_seq_first_stmt (gimple_omp_body (stmt)),
case GIMPLE_OMP_TASK:
save_static_chain_added = info->static_chain_added;
info->static_chain_added = 0;
- walk_body (convert_gimple_call, NULL, info, gimple_omp_body (stmt));
+ walk_body (convert_gimple_call, NULL, info, gimple_omp_body_ptr (stmt));
for (i = 0; i < 2; i++)
{
tree c, decl;
case GIMPLE_OMP_FOR:
walk_body (convert_gimple_call, NULL, info,
- gimple_omp_for_pre_body (stmt));
+ gimple_omp_for_pre_body_ptr (stmt));
/* FALLTHRU */
case GIMPLE_OMP_SECTIONS:
case GIMPLE_OMP_SECTION:
case GIMPLE_OMP_MASTER:
case GIMPLE_OMP_ORDERED:
case GIMPLE_OMP_CRITICAL:
- walk_body (convert_gimple_call, NULL, info, gimple_omp_body (stmt));
+ walk_body (convert_gimple_call, NULL, info, gimple_omp_body_ptr (stmt));
break;
default:
- sizeof (struct phi_arg_d)
+ sizeof (struct phi_arg_d) * len));
phi->gsbase.code = GIMPLE_PHI;
+ gimple_init_singleton (phi);
phi->gimple_phi.nargs = len;
phi->gimple_phi.capacity = capacity;
if (TREE_CODE (var) == SSA_NAME)
/* Resize an existing PHI node. The only way is up. Return the
possibly relocated phi. */
-static void
-resize_phi_node (gimple *phi, size_t len)
+static gimple
+resize_phi_node (gimple phi, size_t len)
{
size_t old_size, i;
gimple new_phi;
- gcc_assert (len > gimple_phi_capacity (*phi));
+ gcc_assert (len > gimple_phi_capacity (phi));
/* The garbage collector will not look at the PHI node beyond the
first PHI_NUM_ARGS elements. Therefore, all we have to copy is a
portion of the PHI node currently in use. */
old_size = sizeof (struct gimple_statement_phi)
- + (gimple_phi_num_args (*phi) - 1) * sizeof (struct phi_arg_d);
+ + (gimple_phi_num_args (phi) - 1) * sizeof (struct phi_arg_d);
new_phi = allocate_phi_node (len);
- memcpy (new_phi, *phi, old_size);
+ memcpy (new_phi, phi, old_size);
for (i = 0; i < gimple_phi_num_args (new_phi); i++)
{
use_operand_p imm, old_imm;
imm = gimple_phi_arg_imm_use_ptr (new_phi, i);
- old_imm = gimple_phi_arg_imm_use_ptr (*phi, i);
+ old_imm = gimple_phi_arg_imm_use_ptr (phi, i);
imm->use = gimple_phi_arg_def_ptr (new_phi, i);
relink_imm_use_stmt (imm, old_imm, new_phi);
}
imm->loc.stmt = new_phi;
}
- *phi = new_phi;
+ return new_phi;
}
/* Reserve PHI arguments for a new edge to basic block BB. */
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
- gimple *loc = gsi_stmt_ptr (&gsi);
+ gimple stmt = gsi_stmt (gsi);
- if (len > gimple_phi_capacity (*loc))
+ if (len > gimple_phi_capacity (stmt))
{
- gimple old_phi = *loc;
-
- resize_phi_node (loc, cap);
+ gimple new_phi = resize_phi_node (stmt, cap);
/* The result of the PHI is defined by this PHI node. */
- SSA_NAME_DEF_STMT (gimple_phi_result (*loc)) = *loc;
+ SSA_NAME_DEF_STMT (gimple_phi_result (new_phi)) = new_phi;
+ gsi_set_stmt (&gsi, new_phi);
- release_phi_node (old_phi);
+ release_phi_node (stmt);
+ stmt = new_phi;
}
/* We represent a "missing PHI argument" by placing NULL_TREE in
example, the loop optimizer duplicates several basic blocks,
redirects edges, and then fixes up PHI arguments later in
batch. */
- SET_PHI_ARG_DEF (*loc, len - 1, NULL_TREE);
+ SET_PHI_ARG_DEF (stmt, len - 1, NULL_TREE);
- (*loc)->gimple_phi.nargs++;
+ stmt->gimple_phi.nargs++;
}
}
void
add_phi_node_to_bb (gimple phi, basic_block bb)
{
- gimple_stmt_iterator gsi;
+ gimple_seq seq = phi_nodes (bb);
/* Add the new PHI node to the list of PHI nodes for block BB. */
- if (phi_nodes (bb) == NULL)
- set_phi_nodes (bb, gimple_seq_alloc ());
-
- gsi = gsi_last (phi_nodes (bb));
- gsi_insert_after (&gsi, phi, GSI_NEW_STMT);
+ if (seq == NULL)
+ set_phi_nodes (bb, gimple_seq_alloc_with_stmt (phi));
+ else
+ {
+ gimple_seq_add_stmt (&seq, phi);
+ gcc_assert (seq == phi_nodes (bb));
+ }
/* Associate BB to the PHI node. */
gimple_set_bb (phi, bb);
gimple_seq seq = NULL;
tree parm;
+ gsi = gsi_start (seq);
for (parm = DECL_ARGUMENTS (current_function_decl);
parm;
parm = DECL_CHAIN (parm))
if (!access_vec)
continue;
- if (!seq)
- {
- seq = gimple_seq_alloc ();
- gsi = gsi_start (seq);
- }
-
for (access = VEC_index (access_p, access_vec, 0);
access;
access = access->next_grp)
EXPR_LOCATION (parm));
}
+ seq = gsi_seq (gsi);
if (seq)
gsi_insert_seq_on_edge_immediate (single_succ_edge (ENTRY_BLOCK_PTR), seq);
}
remove_dead_phis (basic_block bb)
{
bool something_changed = false;
- gimple_seq phis;
gimple phi;
gimple_stmt_iterator gsi;
- phis = phi_nodes (bb);
- for (gsi = gsi_start (phis); !gsi_end_p (gsi);)
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);)
{
stats.total_phis++;
phi = gsi_stmt (gsi);
{
gimple_stmt_iterator gsi;
- for (gsi = gsi_last (bb_seq (bb)); !gsi_end_p (gsi); gsi_prev (&gsi))
+ for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
dse_optimize_stmt (gsi);
}
}
-/* Forward propagate the comparison defined in STMT like
+/* Forward propagate the comparison defined in *DEFGSI like
cond_1 = x CMP y to uses of the form
a_1 = (T')cond_1
a_1 = !cond_1
a_1 = cond_1 != 0
- Returns true if stmt is now unused. */
+ Returns true if stmt is now unused. Advance DEFGSI to the next
+ statement. */
static bool
-forward_propagate_comparison (gimple stmt)
+forward_propagate_comparison (gimple_stmt_iterator *defgsi)
{
+ gimple stmt = gsi_stmt (*defgsi);
tree name = gimple_assign_lhs (stmt);
gimple use_stmt;
tree tmp = NULL_TREE;
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))
|| (TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME
&& SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs2 (stmt))))
- return false;
+ goto bailout;
/* Do not un-cse comparisons. But propagate through copies. */
use_stmt = get_prop_dest_stmt (name, &name);
if (!use_stmt
|| !is_gimple_assign (use_stmt))
- return false;
+ goto bailout;
code = gimple_assign_rhs_code (use_stmt);
lhs = gimple_assign_lhs (use_stmt);
if (!INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
- return false;
+ goto bailout;
/* We can propagate the condition into a statement that
computes the logical negation of the comparison result. */
enum tree_code inv_code;
inv_code = invert_tree_comparison (gimple_assign_rhs_code (stmt), nans);
if (inv_code == ERROR_MARK)
- return false;
+ goto bailout;
tmp = build2 (inv_code, TREE_TYPE (lhs), gimple_assign_rhs1 (stmt),
gimple_assign_rhs2 (stmt));
}
else
- return false;
+ goto bailout;
gsi = gsi_for_stmt (use_stmt);
gimple_assign_set_rhs_from_tree (&gsi, unshare_expr (tmp));
fprintf (dump_file, "'\n");
}
+ /* When we remove stmt now the iterator defgsi goes off it's current
+ sequence, hence advance it now. */
+ gsi_next (defgsi);
+
/* Remove defining statements. */
return remove_prop_source_from_use (name);
+
+bailout:
+ gsi_next (defgsi);
+ return false;
}
}
else if (TREE_CODE_CLASS (code) == tcc_comparison)
{
- if (forward_propagate_comparison (stmt))
+ if (forward_propagate_comparison (&gsi))
cfg_changed = true;
- gsi_next (&gsi);
}
else
gsi_next (&gsi);
}
mark_virtual_ops_for_renaming (stmt);
- gsi_insert_on_edge (loop_preheader_edge (level), stmt);
gsi_remove (&bsi, false);
+ gsi_insert_on_edge (loop_preheader_edge (level), stmt);
}
}
HOST_WIDE_INT dummy;
gimple stmt, pattern_stmt = NULL;
gimple_seq pattern_def_seq = NULL;
- gimple_stmt_iterator pattern_def_si = gsi_start (NULL);
+ gimple_stmt_iterator pattern_def_si = gsi_none ();
bool analyze_pattern_stmt = false;
if (vect_print_dump_info (REPORT_DETAILS))
}
else
{
- pattern_def_si = gsi_start (NULL);
+ pattern_def_si = gsi_none ();
analyze_pattern_stmt = false;
}
}
gimple_seq cond_expr_stmt_list = NULL;
gimple stmt, pattern_stmt;
gimple_seq pattern_def_seq = NULL;
- gimple_stmt_iterator pattern_def_si = gsi_start (NULL);
+ gimple_stmt_iterator pattern_def_si = gsi_none ();
bool transform_pattern_stmt = false;
if (vect_print_dump_info (REPORT_DETAILS))
}
else
{
- pattern_def_si = gsi_start (NULL);
+ pattern_def_si = gsi_none ();
transform_pattern_stmt = false;
}
}