From a8dd994c7a99799ae005c4c60081b04ddfd0d11f Mon Sep 17 00:00:00 2001 From: matz Date: Sun, 26 Apr 2009 19:35:04 +0000 Subject: [PATCH] gcc/ Expand from SSA. * builtins.c (fold_builtin_next_arg): Handle SSA names. * tree-ssa-copyrename.c (rename_ssa_copies): Use ssa_name() directly. * tree-ssa-coalesce.c (create_outofssa_var_map): Mark only useful SSA names. (compare_pairs): Swap cost comparison. (coalesce_ssa_name): Don't use change_partition_var. * tree-nrv.c (struct nrv_data): Add modified member. (finalize_nrv_r): Set it. (tree_nrv): Use it to update statements. (pass_nrv): Require PROP_ssa. * tree-mudflap.c (mf_decl_cache_locals, mf_build_check_statement_for): Use make_rename_temp. (pass_mudflap_2): Require PROP_ssa, run ssa update at finish. * alias.c (find_base_decl): Handle SSA names. * emit-rtl (set_reg_attrs_for_parm): Make non-static. (component_ref_for_mem_expr): Don't leak SSA names into RTL. * rtl.h (set_reg_attrs_for_parm): Declare. * tree-optimize.c (pass_cleanup_cfg_post_optimizing): Rename to "optimized", remove unused locals at finish. (execute_free_datastructures): Make global, call delete_tree_cfg_annotations. (execute_free_cfg_annotations): Don't call delete_tree_cfg_annotations. * ssaexpand.h: New file. * expr.c (toplevel): Include ssaexpand.h. (expand_assignment): Handle SSA names the same as register variables. (expand_expr_real_1): Expand SSA names. * cfgexpand.c (toplevel): Include ssaexpand.h. (SA): New global variable. (gimple_cond_pred_to_tree): Fold TERed comparisons into predicates. (SSAVAR): New macro. (set_rtl): New helper function. (add_stack_var): Deal with SSA names, use set_rtl. (expand_one_stack_var_at): Likewise. (expand_one_stack_var): Deal with SSA names. (stack_var_size_cmp): Use code (SSA_NAME / DECL) as tie breaker before unique numbers. (expand_stack_vars): Use set_rtl. (expand_one_var): Accept SSA names, add asserts for them, feed them to above subroutines. (expand_used_vars): Expand all partitions (without default defs), then only the local decls (ignoring those expanded already). (expand_gimple_cond): Remove edges when jumpif() expands an unconditional jump. (expand_gimple_basic_block): Don't clear EDGE_EXECUTABLE here, or remove abnormal edges. Ignore insns setting the LHS of a TERed SSA name. (gimple_expand_cfg): Call into rewrite_out_of_ssa, initialize members of SA; deal with PARM_DECL partitions here; expand all PHI nodes, free tree datastructures and SA. Commit instructions on edges, clear EDGE_EXECUTABLE and remove abnormal edges here. (pass_expand): Require and destroy PROP_ssa, verify SSA form, flow info and statements at start, collect garbage at finish. * tree-ssa-live.h (struct _var_map): Remove partition_to_var member. (VAR_ANN_PARTITION) Remove. (change_partition_var): Don't declare. (partition_to_var): Always return SSA names. (var_to_partition): Only accept SSA names. (register_ssa_partition): Only check argument. * tree-ssa-live.c (init_var_map): Don't allocate partition_to_var member. (delete_var_map): Don't free it. (var_union): Only accept SSA names, simplify. (partition_view_init): Mark only useful SSA names as used. (partition_view_fini): Only deal with SSA names. (change_partition_var): Remove. (dump_var_map): Use ssa_name instead of partition_to_var member. * tree-ssa.c (delete_tree_ssa): Don't remove PHI nodes on RTL basic blocks. * tree-outof-ssa.c (toplevel): Include ssaexpand.h and expr.h. (struct _elim_graph): New member const_dests; nodes member vector of ints. (set_location_for_edge): New static helper. (create_temp): Remove. (insert_partition_copy_on_edge, insert_part_to_rtx_on_edge, insert_value_copy_on_edge, insert_rtx_to_part_on_edge): New functions. (new_elim_graph): Allocate const_dests member. (clean_elim_graph): Truncate const_dests member. (delete_elim_graph): Free const_dests member. (elim_graph_size): Adapt to new type of nodes member. (elim_graph_add_node): Likewise. (eliminate_name): Likewise. (eliminate_build): Don't take basic block argument, deal only with partition numbers, not variables. (get_temp_reg): New static helper. (elim_create): Use it, deal with RTL temporaries instead of trees. (eliminate_phi): Adjust all calls to new signature. (assign_vars, replace_use_variable, replace_def_variable): Remove. (rewrite_trees): Only do checking. (edge_leader, stmt_list, leader_has_match, leader_match): Remove. (same_stmt_list_p, identical_copies_p, identical_stmt_lists_p, init_analyze_edges_for_bb, fini_analyze_edges_for_bb, contains_tree_r, MAX_STMTS_IN_LATCH, process_single_block_loop_latch, analyze_edges_for_bb, perform_edge_inserts): Remove. (expand_phi_nodes): New global function. (remove_ssa_form): Take ssaexpand parameter. Don't call removed functions, initialize new parameter, remember partitions having a default def. (finish_out_of_ssa): New global function. (rewrite_out_of_ssa): Make global. Adjust call to remove_ssa_form, don't reset in_ssa_p here, don't disable TER when mudflap. (pass_del_ssa): Remove. * tree-flow.h (struct var_ann_d): Remove out_of_ssa_tag and partition members. (execute_free_datastructures): Declare. * Makefile.in (SSAEXPAND_H): New variable. (tree-outof-ssa.o, expr.o, cfgexpand.o): Depend on SSAEXPAND_H. * basic-block.h (commit_one_edge_insertion): Declare. * passes.c (init_optimization_passes): Move pass_nrv and pass_mudflap2 before pass_cleanup_cfg_post_optimizing, remove pass_del_ssa, pass_free_datastructures, pass_free_cfg_annotations. * cfgrtl.c (commit_one_edge_insertion): Make global, don't declare. (redirect_branch_edge): Deal with super block when expanding, split out jump patching itself into ... (patch_jump_insn): ... here, new static helper. testsuite/ Expand from SSA. * gcc.dg/tree-ssa/20030728-1.c: Use -rtl-expand-details dump and change regexps. * gcc.target/i386/pr37248-1.c: Modified. * gcc.target/i386/pr37248-3.c: Modified. * gcc.target/i386/pr37248-2.c: Modified. * gnat.dg/aliasing1.adb: Modified. * gnat.dg/pack9.adb: Modified. * gnat.dg/aliasing2.adb: Modified. * gcc.dg/strict-overflow-2.c: Modified. * gcc.dg/autopar/reduc-1char.c: Modified. * gcc.dg/autopar/reduc-2char.c: Modified. * gcc.dg/autopar/reduc-1.c: Modified. * gcc.dg/autopar/reduc-2.c: Modified. * gcc.dg/autopar/reduc-3.c: Modified. * gcc.dg/autopar/reduc-6.c: Modified. * gcc.dg/autopar/reduc-7.c: Modified. * gcc.dg/autopar/reduc-8.c: Modified. * gcc.dg/autopar/reduc-9.c: Modified. * gcc.dg/autopar/reduc-1short.c: Modified. * gcc.dg/autopar/reduc-2short.c: Modified. * gcc.dg/autopar/parallelization-1.c: Modified. * gcc.dg/strict-overflow-4.c: Modified. * gcc.dg/strict-overflow-6.c: Modified. * gcc.dg/gomp/combined-1.c: Modified. * gcc.dg/no-strict-overflow-1.c: Modified. * gcc.dg/no-strict-overflow-3.c: Modified. * gcc.dg/no-strict-overflow-5.c: Modified. * gcc.dg/tree-ssa/reassoc-13.c: Modified. * gcc.dg/tree-ssa/pr18134.c: Modified. * gcc.dg/tree-ssa/20030824-1.c: Modified. * gcc.dg/tree-ssa/vector-2.c: Modified. * gcc.dg/tree-ssa/forwprop-9.c: Modified. * gcc.dg/tree-ssa/loop-21.c: Modified. * gcc.dg/tree-ssa/20030824-2.c: Modified. * gcc.dg/tree-ssa/vector-3.c: Modified. * gcc.dg/tree-ssa/asm-3.c: Modified. * gcc.dg/tree-ssa/pr23294.c: Modified. * gcc.dg/tree-ssa/loop-22.c: Modified. * gcc.dg/tree-ssa/loop-15.c: Modified. * gcc.dg/tree-ssa/prefetch-4.c: Modified. * gcc.dg/tree-ssa/pr22051-1.c: Modified. * gcc.dg/tree-ssa/pr20139.c: Modified. * gcc.dg/tree-ssa/scev-cast.c: Modified. * gcc.dg/tree-ssa/pr22051-2.c: Modified. * gcc.dg/tree-ssa/reassoc-1.c: Modified. * gcc.dg/tree-ssa/loop-5.c: Modified. * gcc.dg/tree-ssa/pr19431.c: Modified. * gcc.dg/tree-ssa/pr32044.c: Modified. * gcc.dg/tree-ssa/prefetch-7.c: Modified. * gcc.dg/tree-ssa/loop-19.c: Modified. * gcc.dg/tree-ssa/loop-28.c: Modified. * gcc.dg/tree-ssa/ssa-pre-15.c: Modified. * gcc.dg/tree-ssa/divide-1.c: Modified. * gcc.dg/tree-ssa/inline-1.c: Modified. * gcc.dg/tree-ssa/divide-3.c: Modified. * gcc.dg/tree-ssa/pr30978.c: Modified. * gcc.dg/tree-ssa/alias-6.c: Modified. * gcc.dg/tree-ssa/divide-4.c: Modified. * gcc.dg/tree-ssa/alias-11.c: Modified. * gcc.dg/no-strict-overflow-7.c: Modified. * gcc.dg/strict-overflow-1.c: Modified. * gcc.dg/pr15784-4.c: Modified. * gcc.dg/pr34263.c: Modified. * gcc.dg/strict-overflow-3.c: Modified. * gcc.dg/tree-prof/stringop-1.c: Modified. * gcc.dg/tree-prof/val-prof-1.c: Modified. * gcc.dg/tree-prof/val-prof-2.c: Modified. * gcc.dg/tree-prof/val-prof-3.c: Modified. * gcc.dg/tree-prof/val-prof-4.c: Modified. * gcc.dg/no-strict-overflow-2.c: Modified. * gcc.dg/no-strict-overflow-4.c: Modified. * gcc.dg/no-strict-overflow-6.c: Modified. * g++.dg/tree-ssa/pr27090.C: Modified. * g++.dg/tree-ssa/tmmti-2.C: Modified. * g++.dg/tree-ssa/ptrmemfield.C: Modified. * g++.dg/tree-ssa/pr19807.C: Modified. * g++.dg/opt/pr30965.C: Modified. * g++.dg/init/new17.C: Modified. * gfortran.dg/whole_file_6.f90: Modified. * gfortran.dg/whole_file_5.f90: Modified. * gfortran.dg/reassoc_1.f90: Modified. * gfortran.dg/reassoc_3.f90: Modified. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@146817 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 123 +++ gcc/Makefile.in | 7 +- gcc/alias.c | 3 + gcc/basic-block.h | 1 + gcc/builtins.c | 3 + gcc/cfgexpand.c | 316 +++++-- gcc/cfgrtl.c | 86 +- gcc/emit-rtl.c | 7 +- gcc/expr.c | 26 +- gcc/passes.c | 10 +- gcc/rtl.h | 1 + gcc/ssaexpand.h | 80 ++ gcc/testsuite/ChangeLog | 86 ++ gcc/testsuite/g++.dg/init/new17.C | 6 +- gcc/testsuite/g++.dg/opt/pr30965.C | 2 +- gcc/testsuite/g++.dg/tree-ssa/pr19807.C | 10 +- gcc/testsuite/g++.dg/tree-ssa/pr27090.C | 2 +- gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C | 8 +- gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C | 4 +- gcc/testsuite/gcc.dg/autopar/parallelization-1.c | 6 +- gcc/testsuite/gcc.dg/autopar/reduc-1.c | 4 +- gcc/testsuite/gcc.dg/autopar/reduc-1char.c | 4 +- gcc/testsuite/gcc.dg/autopar/reduc-1short.c | 4 +- gcc/testsuite/gcc.dg/autopar/reduc-2.c | 4 +- gcc/testsuite/gcc.dg/autopar/reduc-2char.c | 4 +- gcc/testsuite/gcc.dg/autopar/reduc-2short.c | 4 +- gcc/testsuite/gcc.dg/autopar/reduc-3.c | 4 +- gcc/testsuite/gcc.dg/autopar/reduc-6.c | 4 +- gcc/testsuite/gcc.dg/autopar/reduc-7.c | 4 +- gcc/testsuite/gcc.dg/autopar/reduc-8.c | 4 +- gcc/testsuite/gcc.dg/autopar/reduc-9.c | 4 +- gcc/testsuite/gcc.dg/gomp/combined-1.c | 6 +- gcc/testsuite/gcc.dg/no-strict-overflow-1.c | 6 +- gcc/testsuite/gcc.dg/no-strict-overflow-2.c | 6 +- gcc/testsuite/gcc.dg/no-strict-overflow-3.c | 6 +- gcc/testsuite/gcc.dg/no-strict-overflow-4.c | 8 +- gcc/testsuite/gcc.dg/no-strict-overflow-5.c | 6 +- gcc/testsuite/gcc.dg/no-strict-overflow-6.c | 6 +- gcc/testsuite/gcc.dg/no-strict-overflow-7.c | 6 +- gcc/testsuite/gcc.dg/pr15784-4.c | 4 +- gcc/testsuite/gcc.dg/pr34263.c | 2 +- gcc/testsuite/gcc.dg/strict-overflow-1.c | 6 +- gcc/testsuite/gcc.dg/strict-overflow-2.c | 6 +- gcc/testsuite/gcc.dg/strict-overflow-3.c | 6 +- gcc/testsuite/gcc.dg/strict-overflow-4.c | 8 +- gcc/testsuite/gcc.dg/strict-overflow-6.c | 6 +- gcc/testsuite/gcc.dg/tree-prof/stringop-1.c | 3 +- gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c | 2 +- gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c | 2 +- gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c | 2 +- gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c | 6 +- gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/alias-11.c | 6 +- gcc/testsuite/gcc.dg/tree-ssa/alias-6.c | 6 +- gcc/testsuite/gcc.dg/tree-ssa/asm-3.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/divide-1.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/divide-3.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/divide-4.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c | 6 +- gcc/testsuite/gcc.dg/tree-ssa/inline-1.c | 6 +- gcc/testsuite/gcc.dg/tree-ssa/loop-15.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/loop-19.c | 8 +- gcc/testsuite/gcc.dg/tree-ssa/loop-21.c | 6 +- gcc/testsuite/gcc.dg/tree-ssa/loop-22.c | 6 +- gcc/testsuite/gcc.dg/tree-ssa/loop-28.c | 6 +- gcc/testsuite/gcc.dg/tree-ssa/loop-5.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/pr18134.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr19431.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/pr20139.c | 6 +- gcc/testsuite/gcc.dg/tree-ssa/pr22051-1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr22051-2.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr23294.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/pr30978.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/pr32044.c | 8 +- gcc/testsuite/gcc.dg/tree-ssa/prefetch-4.c | 6 +- gcc/testsuite/gcc.dg/tree-ssa/prefetch-7.c | 10 +- gcc/testsuite/gcc.dg/tree-ssa/reassoc-1.c | 3 +- gcc/testsuite/gcc.dg/tree-ssa/reassoc-13.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/scev-cast.c | 4 +- gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c | 6 +- gcc/testsuite/gcc.dg/tree-ssa/vector-2.c | 8 +- gcc/testsuite/gcc.dg/tree-ssa/vector-3.c | 8 +- gcc/testsuite/gcc.target/i386/pr37248-1.c | 3 +- gcc/testsuite/gcc.target/i386/pr37248-2.c | 3 +- gcc/testsuite/gcc.target/i386/pr37248-3.c | 3 +- gcc/testsuite/gfortran.dg/reassoc_1.f90 | 4 +- gcc/testsuite/gfortran.dg/reassoc_3.f90 | 3 +- gcc/testsuite/gfortran.dg/whole_file_5.f90 | 1 + gcc/testsuite/gfortran.dg/whole_file_6.f90 | 1 + gcc/testsuite/gnat.dg/aliasing1.adb | 6 +- gcc/testsuite/gnat.dg/aliasing2.adb | 6 +- gcc/testsuite/gnat.dg/pack9.adb | 6 +- gcc/tree-flow.h | 9 +- gcc/tree-mudflap.c | 16 +- gcc/tree-nrv.c | 16 +- gcc/tree-optimize.c | 12 +- gcc/tree-outof-ssa.c | 1104 ++++++---------------- gcc/tree-ssa-coalesce.c | 35 +- gcc/tree-ssa-copyrename.c | 2 +- gcc/tree-ssa-live.c | 75 +- gcc/tree-ssa-live.h | 37 +- gcc/tree-ssa.c | 3 +- 104 files changed, 1152 insertions(+), 1280 deletions(-) create mode 100644 gcc/ssaexpand.h diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fab18b1f99a..ade6bbf149b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,128 @@ 2009-04-26 Michael Matz + Expand from SSA. + * builtins.c (fold_builtin_next_arg): Handle SSA names. + * tree-ssa-copyrename.c (rename_ssa_copies): Use ssa_name() directly. + * tree-ssa-coalesce.c (create_outofssa_var_map): Mark only useful + SSA names. + (compare_pairs): Swap cost comparison. + (coalesce_ssa_name): Don't use change_partition_var. + * tree-nrv.c (struct nrv_data): Add modified member. + (finalize_nrv_r): Set it. + (tree_nrv): Use it to update statements. + (pass_nrv): Require PROP_ssa. + * tree-mudflap.c (mf_decl_cache_locals, + mf_build_check_statement_for): Use make_rename_temp. + (pass_mudflap_2): Require PROP_ssa, run ssa update at finish. + * alias.c (find_base_decl): Handle SSA names. + * emit-rtl (set_reg_attrs_for_parm): Make non-static. + (component_ref_for_mem_expr): Don't leak SSA names into RTL. + * rtl.h (set_reg_attrs_for_parm): Declare. + * tree-optimize.c (pass_cleanup_cfg_post_optimizing): Rename + to "optimized", remove unused locals at finish. + (execute_free_datastructures): Make global, call + delete_tree_cfg_annotations. + (execute_free_cfg_annotations): Don't call + delete_tree_cfg_annotations. + + * ssaexpand.h: New file. + * expr.c (toplevel): Include ssaexpand.h. + (expand_assignment): Handle SSA names the same as register + variables. + (expand_expr_real_1): Expand SSA names. + * cfgexpand.c (toplevel): Include ssaexpand.h. + (SA): New global variable. + (gimple_cond_pred_to_tree): Fold TERed comparisons into predicates. + (SSAVAR): New macro. + (set_rtl): New helper function. + (add_stack_var): Deal with SSA names, use set_rtl. + (expand_one_stack_var_at): Likewise. + (expand_one_stack_var): Deal with SSA names. + (stack_var_size_cmp): Use code (SSA_NAME / DECL) as tie breaker + before unique numbers. + (expand_stack_vars): Use set_rtl. + (expand_one_var): Accept SSA names, add asserts for them, feed them + to above subroutines. + (expand_used_vars): Expand all partitions (without default defs), + then only the local decls (ignoring those expanded already). + (expand_gimple_cond): Remove edges when jumpif() expands an + unconditional jump. + (expand_gimple_basic_block): Don't clear EDGE_EXECUTABLE here, + or remove abnormal edges. Ignore insns setting the LHS of a TERed + SSA name. + (gimple_expand_cfg): Call into rewrite_out_of_ssa, initialize + members of SA; deal with PARM_DECL partitions here; expand + all PHI nodes, free tree datastructures and SA. Commit instructions + on edges, clear EDGE_EXECUTABLE and remove abnormal edges here. + (pass_expand): Require and destroy PROP_ssa, verify SSA form, flow + info and statements at start, collect garbage at finish. + * tree-ssa-live.h (struct _var_map): Remove partition_to_var member. + (VAR_ANN_PARTITION) Remove. + (change_partition_var): Don't declare. + (partition_to_var): Always return SSA names. + (var_to_partition): Only accept SSA names. + (register_ssa_partition): Only check argument. + * tree-ssa-live.c (init_var_map): Don't allocate partition_to_var + member. + (delete_var_map): Don't free it. + (var_union): Only accept SSA names, simplify. + (partition_view_init): Mark only useful SSA names as used. + (partition_view_fini): Only deal with SSA names. + (change_partition_var): Remove. + (dump_var_map): Use ssa_name instead of partition_to_var member. + * tree-ssa.c (delete_tree_ssa): Don't remove PHI nodes on RTL + basic blocks. + * tree-outof-ssa.c (toplevel): Include ssaexpand.h and expr.h. + (struct _elim_graph): New member const_dests; nodes member vector of + ints. + (set_location_for_edge): New static helper. + (create_temp): Remove. + (insert_partition_copy_on_edge, insert_part_to_rtx_on_edge, + insert_value_copy_on_edge, insert_rtx_to_part_on_edge): New + functions. + (new_elim_graph): Allocate const_dests member. + (clean_elim_graph): Truncate const_dests member. + (delete_elim_graph): Free const_dests member. + (elim_graph_size): Adapt to new type of nodes member. + (elim_graph_add_node): Likewise. + (eliminate_name): Likewise. + (eliminate_build): Don't take basic block argument, deal only with + partition numbers, not variables. + (get_temp_reg): New static helper. + (elim_create): Use it, deal with RTL temporaries instead of trees. + (eliminate_phi): Adjust all calls to new signature. + (assign_vars, replace_use_variable, replace_def_variable): Remove. + (rewrite_trees): Only do checking. + (edge_leader, stmt_list, leader_has_match, leader_match): Remove. + (same_stmt_list_p, identical_copies_p, identical_stmt_lists_p, + init_analyze_edges_for_bb, fini_analyze_edges_for_bb, + contains_tree_r, MAX_STMTS_IN_LATCH, + process_single_block_loop_latch, analyze_edges_for_bb, + perform_edge_inserts): Remove. + (expand_phi_nodes): New global function. + (remove_ssa_form): Take ssaexpand parameter. Don't call removed + functions, initialize new parameter, remember partitions having a + default def. + (finish_out_of_ssa): New global function. + (rewrite_out_of_ssa): Make global. Adjust call to remove_ssa_form, + don't reset in_ssa_p here, don't disable TER when mudflap. + (pass_del_ssa): Remove. + * tree-flow.h (struct var_ann_d): Remove out_of_ssa_tag and + partition members. + (execute_free_datastructures): Declare. + * Makefile.in (SSAEXPAND_H): New variable. + (tree-outof-ssa.o, expr.o, cfgexpand.o): Depend on SSAEXPAND_H. + * basic-block.h (commit_one_edge_insertion): Declare. + * passes.c (init_optimization_passes): Move pass_nrv and + pass_mudflap2 before pass_cleanup_cfg_post_optimizing, remove + pass_del_ssa, pass_free_datastructures, pass_free_cfg_annotations. + * cfgrtl.c (commit_one_edge_insertion): Make global, don't declare. + (redirect_branch_edge): Deal with super block when expanding, split + out jump patching itself into ... + (patch_jump_insn): ... here, new static helper. + +2009-04-26 Michael Matz + * tree-ssa-copyrename.c (rename_ssa_copies): Don't iterate beyond num_ssa_names. * tree-ssa-ter.c (free_temp_expr_table): Likewise. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 8b97805917c..e01f0fba982 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -864,6 +864,7 @@ TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \ $(HASHTAB_H) $(CGRAPH_H) $(IPA_REFERENCE_H) \ tree-ssa-alias.h TREE_SSA_LIVE_H = tree-ssa-live.h $(PARTITION_H) vecprim.h +SSAEXPAND_H = ssaexpand.h $(TREE_SSA_LIVE_H) PRETTY_PRINT_H = pretty-print.h $(INPUT_H) $(OBSTACK_H) DIAGNOSTIC_H = diagnostic.h diagnostic.def $(PRETTY_PRINT_H) options.h C_PRETTY_PRINT_H = c-pretty-print.h $(PRETTY_PRINT_H) $(C_COMMON_H) $(TREE_H) @@ -2106,7 +2107,7 @@ tree-ssa-coalesce.o : tree-ssa-coalesce.c $(TREE_FLOW_H) $(CONFIG_H) \ tree-outof-ssa.o : tree-outof-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \ $(TREE_PASS_H) $(TREE_SSA_LIVE_H) $(BASIC_BLOCK_H) $(BITMAP_H) $(GGC_H) \ - $(TOPLEV_H) + $(TOPLEV_H) $(EXPR_H) $(SSAEXPAND_H) tree-ssa-dse.o : tree-ssa-dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \ $(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_DUMP_H) domwalk.h $(FLAGS_H) \ @@ -2532,7 +2533,7 @@ expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ typeclass.h hard-reg-set.h $(TOPLEV_H) hard-reg-set.h $(EXCEPT_H) reload.h \ $(GGC_H) langhooks.h intl.h $(TM_P_H) $(REAL_H) $(TARGET_H) \ tree-iterator.h gt-expr.h $(MACHMODE_H) $(TIMEVAR_H) $(TREE_FLOW_H) \ - $(TREE_PASS_H) $(DF_H) $(DIAGNOSTIC_H) vecprim.h + $(TREE_PASS_H) $(DF_H) $(DIAGNOSTIC_H) vecprim.h $(SSAEXPAND_H) dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) $(OPTABS_H) $(INSN_ATTR_H) insn-config.h \ langhooks.h $(GGC_H) gt-dojump.h vecprim.h $(BASIC_BLOCK_H) @@ -2804,7 +2805,7 @@ cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) \ coretypes.h $(TREE_DUMP_H) $(EXCEPT_H) langhooks.h $(TREE_PASS_H) $(RTL_H) \ $(DIAGNOSTIC_H) $(TOPLEV_H) $(BASIC_BLOCK_H) $(FLAGS_H) debug.h $(PARAMS_H) \ - value-prof.h $(TREE_INLINE_H) $(TARGET_H) + value-prof.h $(TREE_INLINE_H) $(TARGET_H) $(SSAEXPAND_H) cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \ output.h $(TOPLEV_H) $(FUNCTION_H) $(EXCEPT_H) $(TM_P_H) insn-config.h $(EXPR_H) \ diff --git a/gcc/alias.c b/gcc/alias.c index 8a20f467905..794df755040 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -435,6 +435,9 @@ find_base_decl (tree t) if (t == 0 || t == error_mark_node || ! POINTER_TYPE_P (TREE_TYPE (t))) return 0; + if (TREE_CODE (t) == SSA_NAME) + t = SSA_NAME_VAR (t); + /* If this is a declaration, return it. If T is based on a restrict qualified decl, return that decl. */ if (DECL_P (t)) diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 19ccd48edd6..3f7e872374c 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -502,6 +502,7 @@ extern void update_bb_for_insn (basic_block); extern void insert_insn_on_edge (rtx, edge); basic_block split_edge_and_insert (edge, rtx); +extern void commit_one_edge_insertion (edge e); extern void commit_edge_insertions (void); extern void remove_fake_edges (void); diff --git a/gcc/builtins.c b/gcc/builtins.c index 9f0f4ac4fba..8621e0db511 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -11801,6 +11801,9 @@ fold_builtin_next_arg (tree exp, bool va_start_p) arg = CALL_EXPR_ARG (exp, 0); } + if (TREE_CODE (arg) == SSA_NAME) + arg = SSA_NAME_VAR (arg); + /* We destructively modify the call to be __builtin_va_start (ap, 0) or __builtin_next_arg (0) the first time we see it, after checking the arguments and if needed issuing a warning. */ diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 695e4ef0ef9..a5765f81c47 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -42,8 +42,13 @@ along with GCC; see the file COPYING3. If not see #include "tree-inline.h" #include "value-prof.h" #include "target.h" +#include "ssaexpand.h" +/* This variable holds information helping the rewriting of SSA trees + into RTL. */ +struct ssaexpand SA; + /* Return an expression tree corresponding to the RHS of GIMPLE statement STMT. */ @@ -78,8 +83,22 @@ gimple_assign_rhs_to_tree (gimple stmt) static tree gimple_cond_pred_to_tree (gimple stmt) { + /* We're sometimes presented with such code: + D.123_1 = x < y; + if (D.123_1 != 0) + ... + This would expand to two comparisons which then later might + be cleaned up by combine. But some pattern matchers like if-conversion + work better when there's only one compare, so make up for this + here as special exception if TER would have made the same change. */ + tree lhs = gimple_cond_lhs (stmt); + if (SA.values + && TREE_CODE (lhs) == SSA_NAME + && SA.values[SSA_NAME_VERSION (lhs)]) + lhs = gimple_assign_rhs_to_tree (SA.values[SSA_NAME_VERSION (lhs)]); + return build2 (gimple_cond_code (stmt), boolean_type_node, - gimple_cond_lhs (stmt), gimple_cond_rhs (stmt)); + lhs, gimple_cond_rhs (stmt)); } /* Helper for gimple_to_tree. Set EXPR_LOCATION for every expression @@ -423,6 +442,23 @@ failed: #define STACK_ALIGNMENT_NEEDED 1 #endif +#define SSAVAR(x) (TREE_CODE (x) == SSA_NAME ? SSA_NAME_VAR (x) : x) + +/* Associate declaration T with storage space X. If T is no + SSA name this is exactly SET_DECL_RTL, otherwise make the + partition of T associated with X. */ +static inline void +set_rtl (tree t, rtx x) +{ + if (TREE_CODE (t) == SSA_NAME) + { + SA.partition_to_pseudo[var_to_partition (SA.map, t)] = x; + if (x && !MEM_P (x)) + set_reg_attrs_for_decl_rtl (SSA_NAME_VAR (t), x); + } + else + SET_DECL_RTL (t, x); +} /* This structure holds data relevant to one variable that will be placed in a stack slot. */ @@ -561,15 +597,15 @@ add_stack_var (tree decl) } stack_vars[stack_vars_num].decl = decl; stack_vars[stack_vars_num].offset = 0; - stack_vars[stack_vars_num].size = tree_low_cst (DECL_SIZE_UNIT (decl), 1); - stack_vars[stack_vars_num].alignb = get_decl_align_unit (decl); + stack_vars[stack_vars_num].size = tree_low_cst (DECL_SIZE_UNIT (SSAVAR (decl)), 1); + stack_vars[stack_vars_num].alignb = get_decl_align_unit (SSAVAR (decl)); /* All variables are initially in their own partition. */ stack_vars[stack_vars_num].representative = stack_vars_num; stack_vars[stack_vars_num].next = EOC; /* Ensure that this decl doesn't get put onto the list twice. */ - SET_DECL_RTL (decl, pc_rtx); + set_rtl (decl, pc_rtx); stack_vars_num++; } @@ -688,22 +724,37 @@ add_alias_set_conflicts (void) } /* A subroutine of partition_stack_vars. A comparison function for qsort, - sorting an array of indices by the size of the object. */ + sorting an array of indices by the size and type of the object. */ static int stack_var_size_cmp (const void *a, const void *b) { HOST_WIDE_INT sa = stack_vars[*(const size_t *)a].size; HOST_WIDE_INT sb = stack_vars[*(const size_t *)b].size; - unsigned int uida = DECL_UID (stack_vars[*(const size_t *)a].decl); - unsigned int uidb = DECL_UID (stack_vars[*(const size_t *)b].decl); + tree decla, declb; + unsigned int uida, uidb; if (sa < sb) return -1; if (sa > sb) return 1; - /* For stack variables of the same size use the uid of the decl - to make the sort stable. */ + decla = stack_vars[*(const size_t *)a].decl; + declb = stack_vars[*(const size_t *)b].decl; + /* For stack variables of the same size use and id of the decls + to make the sort stable. Two SSA names are compared by their + version, SSA names come before non-SSA names, and two normal + decls are compared by their DECL_UID. */ + if (TREE_CODE (decla) == SSA_NAME) + { + if (TREE_CODE (declb) == SSA_NAME) + uida = SSA_NAME_VERSION (decla), uidb = SSA_NAME_VERSION (declb); + else + return -1; + } + else if (TREE_CODE (declb) == SSA_NAME) + return 1; + else + uida = DECL_UID (decla), uidb = DECL_UID (declb); if (uida < uidb) return -1; if (uida > uidb) @@ -874,21 +925,27 @@ expand_one_stack_var_at (tree decl, HOST_WIDE_INT offset) gcc_assert (offset == trunc_int_for_mode (offset, Pmode)); x = plus_constant (virtual_stack_vars_rtx, offset); - x = gen_rtx_MEM (DECL_MODE (decl), x); - - /* Set alignment we actually gave this decl. */ - offset -= frame_phase; - align = offset & -offset; - align *= BITS_PER_UNIT; - if (align == 0) - align = STACK_BOUNDARY; - else if (align > MAX_SUPPORTED_STACK_ALIGNMENT) - align = MAX_SUPPORTED_STACK_ALIGNMENT; - DECL_ALIGN (decl) = align; - DECL_USER_ALIGN (decl) = 0; + x = gen_rtx_MEM (DECL_MODE (SSAVAR (decl)), x); - set_mem_attributes (x, decl, true); - SET_DECL_RTL (decl, x); + if (TREE_CODE (decl) != SSA_NAME) + { + /* Set alignment we actually gave this decl if it isn't an SSA name. + If it is we generate stack slots only accidentally so it isn't as + important, we'll simply use the alignment that is already set. */ + offset -= frame_phase; + align = offset & -offset; + align *= BITS_PER_UNIT; + if (align == 0) + align = STACK_BOUNDARY; + else if (align > MAX_SUPPORTED_STACK_ALIGNMENT) + align = MAX_SUPPORTED_STACK_ALIGNMENT; + + DECL_ALIGN (decl) = align; + DECL_USER_ALIGN (decl) = 0; + } + + set_mem_attributes (x, SSAVAR (decl), true); + set_rtl (decl, x); } /* A subroutine of expand_used_vars. Give each partition representative @@ -912,7 +969,9 @@ expand_stack_vars (bool (*pred) (tree)) /* Skip variables that have already had rtl assigned. See also add_stack_var where we perpetrate this pc_rtx hack. */ - if (DECL_RTL (stack_vars[i].decl) != pc_rtx) + if ((TREE_CODE (stack_vars[i].decl) == SSA_NAME + ? SA.partition_to_pseudo[var_to_partition (SA.map, stack_vars[i].decl)] + : DECL_RTL (stack_vars[i].decl)) != pc_rtx) continue; /* Check the predicate to see whether this variable should be @@ -951,7 +1010,7 @@ account_stack_vars (void) size += stack_vars[i].size; for (j = i; j != EOC; j = stack_vars[j].next) - SET_DECL_RTL (stack_vars[j].decl, NULL); + set_rtl (stack_vars[j].decl, NULL); } return size; } @@ -964,8 +1023,8 @@ expand_one_stack_var (tree var) { HOST_WIDE_INT size, offset, align; - size = tree_low_cst (DECL_SIZE_UNIT (var), 1); - align = get_decl_align_unit (var); + size = tree_low_cst (DECL_SIZE_UNIT (SSAVAR (var)), 1); + align = get_decl_align_unit (SSAVAR (var)); offset = alloc_stack_frame_space (size, align); expand_one_stack_var_at (var, offset); @@ -986,20 +1045,21 @@ expand_one_hard_reg_var (tree var) static void expand_one_register_var (tree var) { - tree type = TREE_TYPE (var); + tree decl = SSAVAR (var); + tree type = TREE_TYPE (decl); int unsignedp = TYPE_UNSIGNED (type); enum machine_mode reg_mode - = promote_mode (type, DECL_MODE (var), &unsignedp, 0); + = promote_mode (type, DECL_MODE (decl), &unsignedp, 0); rtx x = gen_reg_rtx (reg_mode); - SET_DECL_RTL (var, x); + set_rtl (var, x); /* Note if the object is a user variable. */ - if (!DECL_ARTIFICIAL (var)) - mark_user_reg (x); + if (!DECL_ARTIFICIAL (decl)) + mark_user_reg (x); if (POINTER_TYPE_P (type)) - mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (var)))); + mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (type))); } /* A subroutine of expand_one_var. Called to assign rtl to a VAR_DECL that @@ -1067,6 +1127,9 @@ defer_stack_allocation (tree var, bool toplevel) static HOST_WIDE_INT expand_one_var (tree var, bool toplevel, bool really_expand) { + tree origvar = var; + var = SSAVAR (var); + if (SUPPORTS_STACK_ALIGNMENT && TREE_TYPE (var) != error_mark_node && TREE_CODE (var) == VAR_DECL) @@ -1092,7 +1155,18 @@ expand_one_var (tree var, bool toplevel, bool really_expand) } } - if (TREE_CODE (var) != VAR_DECL) + if (TREE_CODE (origvar) == SSA_NAME) + { + gcc_assert (TREE_CODE (var) != VAR_DECL + || (!DECL_EXTERNAL (var) + && !DECL_HAS_VALUE_EXPR_P (var) + && !TREE_STATIC (var) + && !DECL_RTL_SET_P (var) + && TREE_TYPE (var) != error_mark_node + && !DECL_HARD_REGISTER (var) + && really_expand)); + } + if (TREE_CODE (var) != VAR_DECL && TREE_CODE (origvar) != SSA_NAME) ; else if (DECL_EXTERNAL (var)) ; @@ -1107,7 +1181,7 @@ expand_one_var (tree var, bool toplevel, bool really_expand) if (really_expand) expand_one_error_var (var); } - else if (DECL_HARD_REGISTER (var)) + else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var)) { if (really_expand) expand_one_hard_reg_var (var); @@ -1115,14 +1189,14 @@ expand_one_var (tree var, bool toplevel, bool really_expand) else if (use_register_for_decl (var)) { if (really_expand) - expand_one_register_var (var); + expand_one_register_var (origvar); } else if (defer_stack_allocation (var, toplevel)) - add_stack_var (var); + add_stack_var (origvar); else { if (really_expand) - expand_one_stack_var (var); + expand_one_stack_var (origvar); return tree_low_cst (DECL_SIZE_UNIT (var), 1); } return 0; @@ -1441,6 +1515,7 @@ static void expand_used_vars (void) { tree t, next, outer_block = DECL_INITIAL (current_function_decl); + unsigned i; /* Compute the phase of the stack frame for this function. */ { @@ -1451,6 +1526,28 @@ expand_used_vars (void) init_vars_expansion (); + for (i = 0; i < SA.map->num_partitions; i++) + { + tree var = partition_to_var (SA.map, i); + + gcc_assert (is_gimple_reg (var)); + if (TREE_CODE (SSA_NAME_VAR (var)) == VAR_DECL) + expand_one_var (var, true, true); + else + { + /* This is a PARM_DECL or RESULT_DECL. For those partitions that + contain the default def (representing the parm or result itself) + we don't do anything here. But those which don't contain the + default def (representing a temporary based on the parm/result) + we need to allocate space just like for normal VAR_DECLs. */ + if (!bitmap_bit_p (SA.partition_has_default_def, i)) + { + expand_one_var (var, true, true); + gcc_assert (SA.partition_to_pseudo[i]); + } + } + } + /* At this point all variables on the local_decls with TREE_USED set are not associated with any block scope. Lay them out. */ t = cfun->local_decls; @@ -1462,19 +1559,15 @@ expand_used_vars (void) next = TREE_CHAIN (t); + /* Expanded above already. */ + if (is_gimple_reg (var)) + ; /* We didn't set a block for static or extern because it's hard to tell the difference between a global variable (re)declared in a local scope, and one that's really declared there to begin with. And it doesn't really matter much, since we're not giving them stack space. Expand them now. */ - if (TREE_STATIC (var) || DECL_EXTERNAL (var)) - expand_now = true; - - /* Any variable that could have been hoisted into an SSA_NAME - will have been propagated anywhere the optimizers chose, - i.e. not confined to their original block. Allocate them - as if they were defined in the outermost scope. */ - else if (is_gimple_reg (var)) + else if (TREE_STATIC (var) || DECL_EXTERNAL (var)) expand_now = true; /* If the variable is not associated with any block, then it @@ -1674,6 +1767,19 @@ expand_gimple_cond (basic_block bb, gimple stmt) true_edge->goto_block = NULL; false_edge->flags |= EDGE_FALLTHRU; ggc_free (pred); + /* Special case: when jumpif decides that the condition is + trivial it emits an unconditional jump (and the necessary + barrier). But we still have two edges, the fallthru one is + wrong. purge_dead_edges would clean this up later. Unfortunately + we have to insert insns (and split edges) before + find_many_sub_basic_blocks and hence before purge_dead_edges. + But splitting edges might create new blocks which depend on the + fact that if there are two edges there's no barrier. So the + barrier would get lost and verify_flow_info would ICE. Instead + of auditing all edge splitters to care for the barrier (which + normally isn't there in a cleaned CFG), fix it here. */ + if (BARRIER_P (get_last_insn ())) + remove_edge (false_edge); return NULL; } if (true_edge->dest == bb->next_bb) @@ -1690,6 +1796,8 @@ expand_gimple_cond (basic_block bb, gimple stmt) false_edge->goto_block = NULL; true_edge->flags |= EDGE_FALLTHRU; ggc_free (pred); + if (BARRIER_P (get_last_insn ())) + remove_edge (true_edge); return NULL; } @@ -1932,20 +2040,6 @@ expand_gimple_basic_block (basic_block bb) NOTE_BASIC_BLOCK (note) = bb; - for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) - { - /* Clear EDGE_EXECUTABLE. This flag is never used in the backend. */ - e->flags &= ~EDGE_EXECUTABLE; - - /* At the moment not all abnormal edges match the RTL representation. - It is safe to remove them here as find_many_sub_basic_blocks will - rediscover them. In the future we should get this fixed properly. */ - if (e->flags & EDGE_ABNORMAL) - remove_edge (e); - else - ei_next (&ei); - } - for (; !gsi_end_p (gsi); gsi_next (&gsi)) { gimple stmt = gsi_stmt (gsi); @@ -1975,7 +2069,19 @@ expand_gimple_basic_block (basic_block bb) } else if (gimple_code (stmt) != GIMPLE_CHANGE_DYNAMIC_TYPE) { - tree stmt_tree = gimple_to_tree (stmt); + def_operand_p def_p; + tree stmt_tree; + def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF); + + if (def_p != NULL) + { + /* Ignore this stmt if it is in the list of + replaceable expressions. */ + if (SA.values + && SA.values[SSA_NAME_VERSION (DEF_FROM_PTR (def_p))]) + continue; + } + stmt_tree = gimple_to_tree (stmt); last = get_last_insn (); expand_expr_stmt (stmt_tree); maybe_dump_rtl_for_gimple_stmt (stmt, last); @@ -2286,6 +2392,11 @@ gimple_expand_cfg (void) sbitmap blocks; edge_iterator ei; edge e; + unsigned i; + + rewrite_out_of_ssa (&SA); + SA.partition_to_pseudo = (rtx *)xcalloc (SA.map->num_partitions, + sizeof (rtx)); /* Some backends want to know that we are expanding to RTL. */ currently_expanding_to_rtl = 1; @@ -2339,6 +2450,29 @@ gimple_expand_cfg (void) /* Set up parameters and prepare for return, for the function. */ expand_function_start (current_function_decl); + /* Now that we also have the parameter RTXs, copy them over to our + partitions. */ + for (i = 0; i < SA.map->num_partitions; i++) + { + tree var = SSA_NAME_VAR (partition_to_var (SA.map, i)); + + if (TREE_CODE (var) != VAR_DECL + && !SA.partition_to_pseudo[i]) + SA.partition_to_pseudo[i] = DECL_RTL_IF_SET (var); + gcc_assert (SA.partition_to_pseudo[i]); + /* Some RTL parts really want to look at DECL_RTL(x) when x + was a decl marked in REG_ATTR or MEM_ATTR. We could use + SET_DECL_RTL here making this available, but that would mean + to select one of the potentially many RTLs for one DECL. Instead + of doing that we simply reset the MEM_EXPR of the RTL in question, + then nobody can get at it and hence nobody can call DECL_RTL on it. */ + if (!DECL_RTL_SET_P (var)) + { + if (MEM_P (SA.partition_to_pseudo[i])) + set_mem_expr (SA.partition_to_pseudo[i], NULL); + } + } + /* If this function is `main', emit a call to `__main' to run global initializers, etc. */ if (DECL_NAME (current_function_decl) @@ -2368,13 +2502,15 @@ gimple_expand_cfg (void) gcc_assert (crtl->parm_stack_boundary <= INCOMING_STACK_BOUNDARY); } + expand_phi_nodes (&SA); + /* Register rtl specific functions for cfg. */ rtl_register_cfg_hooks (); init_block = construct_init_block (); /* Clear EDGE_EXECUTABLE on the entry edge(s). It is cleaned from the - remaining edges in expand_gimple_basic_block. */ + remaining edges later. */ FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs) e->flags &= ~EDGE_EXECUTABLE; @@ -2382,6 +2518,9 @@ gimple_expand_cfg (void) FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR, next_bb) bb = expand_gimple_basic_block (bb); + execute_free_datastructures (); + finish_out_of_ssa (&SA); + /* Expansion is used by optimization passes too, set maybe_hot_insn_p conservatively to true until they are all profile aware. */ pointer_map_destroy (lab_rtx_for_bb); @@ -2391,9 +2530,6 @@ gimple_expand_cfg (void) set_curr_insn_block (DECL_INITIAL (current_function_decl)); insn_locators_finalize (); - /* We're done expanding trees to RTL. */ - currently_expanding_to_rtl = 0; - /* Convert tree EH labels to RTL EH labels and zap the tree EH table. */ convert_from_eh_region_ranges (); set_eh_throw_stmt_table (cfun, NULL); @@ -2401,11 +2537,48 @@ gimple_expand_cfg (void) rebuild_jump_labels (get_insns ()); find_exception_handler_labels (); + FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb) + { + edge e; + edge_iterator ei; + for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) + { + if (e->insns.r) + commit_one_edge_insertion (e); + else + ei_next (&ei); + } + } + + /* We're done expanding trees to RTL. */ + currently_expanding_to_rtl = 0; + + FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR, next_bb) + { + edge e; + edge_iterator ei; + for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) + { + /* Clear EDGE_EXECUTABLE. This flag is never used in the backend. */ + e->flags &= ~EDGE_EXECUTABLE; + + /* At the moment not all abnormal edges match the RTL + representation. It is safe to remove them here as + find_many_sub_basic_blocks will rediscover them. + In the future we should get this fixed properly. */ + if ((e->flags & EDGE_ABNORMAL) + && !(e->flags & EDGE_SIBCALL)) + remove_edge (e); + else + ei_next (&ei); + } + } + blocks = sbitmap_alloc (last_basic_block); sbitmap_ones (blocks); find_many_sub_basic_blocks (blocks); - purge_all_dead_edges (); sbitmap_free (blocks); + purge_all_dead_edges (); compact_blocks (); @@ -2470,11 +2643,12 @@ struct rtl_opt_pass pass_expand = NULL, /* next */ 0, /* static_pass_number */ TV_EXPAND, /* tv_id */ - /* ??? If TER is enabled, we actually receive GENERIC. */ - PROP_gimple_leh | PROP_cfg, /* properties_required */ + PROP_ssa | PROP_gimple_leh | PROP_cfg,/* properties_required */ PROP_rtl, /* properties_provided */ - PROP_trees, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ + PROP_ssa | PROP_trees, /* properties_destroyed */ + TODO_verify_ssa | TODO_verify_flow + | TODO_verify_stmts, /* todo_flags_start */ + TODO_dump_func + | TODO_ggc_collect /* todo_flags_finish */ } }; diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index c6436bf4be7..36bc865916b 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -64,7 +64,6 @@ along with GCC; see the file COPYING3. If not see static int can_delete_note_p (const_rtx); static int can_delete_label_p (const_rtx); -static void commit_one_edge_insertion (edge); static basic_block rtl_split_edge (edge); static bool rtl_move_block_after (basic_block, basic_block); static int rtl_verify_flow_info (void); @@ -856,31 +855,25 @@ try_redirect_by_replacing_jump (edge e, basic_block target, bool in_cfglayout) return e; } -/* Redirect edge representing branch of (un)conditional jump or tablejump, - NULL on failure */ -static edge -redirect_branch_edge (edge e, basic_block target) +/* Subroutine of redirect_branch_edge that tries to patch the jump + instruction INSN so that it reaches block NEW. Do this + only when it originally reached block OLD. Return true if this + worked or the original target wasn't OLD, return false if redirection + doesn't work. */ + +static bool +patch_jump_insn (rtx insn, rtx old_label, basic_block new_bb) { rtx tmp; - rtx old_label = BB_HEAD (e->dest); - basic_block src = e->src; - rtx insn = BB_END (src); - - /* We can only redirect non-fallthru edges of jump insn. */ - if (e->flags & EDGE_FALLTHRU) - return NULL; - else if (!JUMP_P (insn)) - return NULL; - /* Recognize a tablejump and adjust all matching cases. */ if (tablejump_p (insn, NULL, &tmp)) { rtvec vec; int j; - rtx new_label = block_label (target); + rtx new_label = block_label (new_bb); - if (target == EXIT_BLOCK_PTR) - return NULL; + if (new_bb == EXIT_BLOCK_PTR) + return false; if (GET_CODE (PATTERN (tmp)) == ADDR_VEC) vec = XVEC (PATTERN (tmp), 0); else @@ -915,20 +908,55 @@ redirect_branch_edge (edge e, basic_block target) if (computed_jump_p (insn) /* A return instruction can't be redirected. */ || returnjump_p (insn)) - return NULL; - - /* If the insn doesn't go where we think, we're confused. */ - gcc_assert (JUMP_LABEL (insn) == old_label); + return false; - /* If the substitution doesn't succeed, die. This can happen - if the back end emitted unrecognizable instructions or if - target is exit block on some arches. */ - if (!redirect_jump (insn, block_label (target), 0)) + if (!currently_expanding_to_rtl || JUMP_LABEL (insn) == old_label) { - gcc_assert (target == EXIT_BLOCK_PTR); - return NULL; + /* If the insn doesn't go where we think, we're confused. */ + gcc_assert (JUMP_LABEL (insn) == old_label); + + /* If the substitution doesn't succeed, die. This can happen + if the back end emitted unrecognizable instructions or if + target is exit block on some arches. */ + if (!redirect_jump (insn, block_label (new_bb), 0)) + { + gcc_assert (new_bb == EXIT_BLOCK_PTR); + return false; + } } } + return true; +} + + +/* Redirect edge representing branch of (un)conditional jump or tablejump, + NULL on failure */ +static edge +redirect_branch_edge (edge e, basic_block target) +{ + rtx old_label = BB_HEAD (e->dest); + basic_block src = e->src; + rtx insn = BB_END (src); + + /* We can only redirect non-fallthru edges of jump insn. */ + if (e->flags & EDGE_FALLTHRU) + return NULL; + else if (!JUMP_P (insn) && !currently_expanding_to_rtl) + return NULL; + + if (!currently_expanding_to_rtl) + { + if (!patch_jump_insn (insn, old_label, target)) + return NULL; + } + else + /* When expanding this BB might actually contain multiple + jumps (i.e. not yet split by find_many_sub_basic_blocks). + Redirect all of those that match our label. */ + for (insn = BB_HEAD (src); insn != NEXT_INSN (BB_END (src)); + insn = NEXT_INSN (insn)) + if (JUMP_P (insn) && !patch_jump_insn (insn, old_label, target)) + return NULL; if (dump_file) fprintf (dump_file, "Edge %i->%i redirected to %i\n", @@ -1313,7 +1341,7 @@ insert_insn_on_edge (rtx pattern, edge e) /* Update the CFG for the instructions queued on edge E. */ -static void +void commit_one_edge_insertion (edge e) { rtx before = NULL_RTX, after = NULL_RTX, insns, tmp, last; diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index ffb658738d1..916774c659d 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1028,7 +1028,7 @@ set_reg_attrs_for_parm (rtx parm_rtx, rtx mem) /* Set the REG_ATTRS for registers in value X, given that X represents decl T. */ -static void +void set_reg_attrs_for_decl_rtl (tree t, rtx x) { if (GET_CODE (x) == SUBREG) @@ -1449,7 +1449,10 @@ component_ref_for_mem_expr (tree ref) inner = NULL_TREE; } - if (inner == TREE_OPERAND (ref, 0)) + if (inner == TREE_OPERAND (ref, 0) + /* Don't leak SSA-names in the third operand. */ + && (!TREE_OPERAND (ref, 2) + || TREE_CODE (TREE_OPERAND (ref, 2)) != SSA_NAME)) return ref; else return build3 (COMPONENT_REF, TREE_TYPE (ref), inner, diff --git a/gcc/expr.c b/gcc/expr.c index fd0c43776ef..cf818429ef1 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -54,6 +54,7 @@ along with GCC; see the file COPYING3. If not see #include "timevar.h" #include "df.h" #include "diagnostic.h" +#include "ssaexpand.h" /* Decide whether a function's arguments should be processed from first to last or from last to first. @@ -4284,12 +4285,13 @@ expand_assignment (tree to, tree from, bool nontemporal) Don't do this if TO is a VAR_DECL or PARM_DECL whose DECL_RTL is REG since it might be a promoted variable where the zero- or sign- extension needs to be done. Handling this in the normal way is safe because no - computation is done before the call. */ + computation is done before the call. The same is true for SSA names. */ if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from, from) && COMPLETE_TYPE_P (TREE_TYPE (from)) && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST - && ! ((TREE_CODE (to) == VAR_DECL || TREE_CODE (to) == PARM_DECL) - && REG_P (DECL_RTL (to)))) + && ! (((TREE_CODE (to) == VAR_DECL || TREE_CODE (to) == PARM_DECL) + && REG_P (DECL_RTL (to))) + || TREE_CODE (to) == SSA_NAME)) { rtx value; @@ -7223,8 +7225,21 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, } case SSA_NAME: - return expand_expr_real_1 (SSA_NAME_VAR (exp), target, tmode, modifier, - NULL); + /* ??? ivopts calls expander, without any preparation from + out-of-ssa. So fake instructions as if this was an access to the + base variable. This unnecessarily allocates a pseudo, see how we can + reuse it, if partition base vars have it set already. */ + if (!currently_expanding_to_rtl) + return expand_expr_real_1 (SSA_NAME_VAR (exp), target, tmode, modifier, NULL); + { + gimple g = get_gimple_for_ssa_name (exp); + if (g) + return expand_expr_real_1 (gimple_assign_rhs_to_tree (g), target, + tmode, modifier, NULL); + } + decl_rtl = get_rtx_for_ssa_name (exp); + exp = SSA_NAME_VAR (exp); + goto expand_decl_rtl; case PARM_DECL: case VAR_DECL: @@ -7250,6 +7265,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, case FUNCTION_DECL: case RESULT_DECL: decl_rtl = DECL_RTL (exp); + expand_decl_rtl: gcc_assert (decl_rtl); decl_rtl = copy_rtx (decl_rtl); diff --git a/gcc/passes.c b/gcc/passes.c index 1e7bab03983..fbcdc9e1b57 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -707,17 +707,17 @@ init_optimization_passes (void) NEXT_PASS (pass_local_pure_const); } NEXT_PASS (pass_cleanup_eh); - NEXT_PASS (pass_del_ssa); NEXT_PASS (pass_nrv); + NEXT_PASS (pass_mudflap_2); NEXT_PASS (pass_mark_used_blocks); NEXT_PASS (pass_cleanup_cfg_post_optimizing); - NEXT_PASS (pass_warn_function_noreturn); - NEXT_PASS (pass_free_datastructures); - NEXT_PASS (pass_mudflap_2); - NEXT_PASS (pass_free_cfg_annotations); +/* NEXT_PASS (pass_del_ssa); + NEXT_PASS (pass_free_datastructures); + NEXT_PASS (pass_free_cfg_annotations);*/ NEXT_PASS (pass_expand); + NEXT_PASS (pass_rest_of_compilation); { struct opt_pass **p = &pass_rest_of_compilation.pass.sub; diff --git a/gcc/rtl.h b/gcc/rtl.h index 98fb29068ef..9941a9736f6 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1491,6 +1491,7 @@ extern rtx gen_int_mode (HOST_WIDE_INT, enum machine_mode); extern rtx emit_copy_of_insn_after (rtx, rtx); extern void set_reg_attrs_from_value (rtx, rtx); extern void set_reg_attrs_for_parm (rtx, rtx); +extern void set_reg_attrs_for_decl_rtl (tree t, rtx x); extern void adjust_reg_mode (rtx, enum machine_mode); extern int mem_expr_equal_p (const_tree, const_tree); diff --git a/gcc/ssaexpand.h b/gcc/ssaexpand.h new file mode 100644 index 00000000000..a42282d582f --- /dev/null +++ b/gcc/ssaexpand.h @@ -0,0 +1,80 @@ +/* Routines for expanding from SSA form to RTL. + Copyright (C) 2009 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 3, or (at your option) +any later version. + +GCC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + + +#ifndef _SSAEXPAND_H +#define _SSAEXPAND_H 1 + +#include "tree-ssa-live.h" + +/* This structure (of which only a singleton SA exists) is used to + pass around information between the outof-SSA functions, cfgexpand + and expand itself. */ +struct ssaexpand +{ + /* The computed partitions of SSA names are stored here. */ + var_map map; + + /* For a SSA name version V values[V] contains the gimple statement + defining it iff TER decided that it should be forwarded, NULL + otherwise. */ + gimple *values; + + /* For a partition number I partition_to_pseudo[I] contains the + RTL expression of the allocated space of it (either a MEM or + a pseudos REG). */ + rtx *partition_to_pseudo; + + /* If partition I contains an SSA name that has a default def, + bit I will be set in this bitmap. */ + bitmap partition_has_default_def; +}; + +/* This is the singleton described above. */ +extern struct ssaexpand SA; + +/* Returns the RTX expression representing the storage of the outof-SSA + partition that the SSA name EXP is a member of. */ +static inline rtx +get_rtx_for_ssa_name (tree exp) +{ + int p = partition_find (SA.map->var_partition, SSA_NAME_VERSION (exp)); + if (SA.map->partition_to_view) + p = SA.map->partition_to_view[p]; + gcc_assert (p != NO_PARTITION); + return SA.partition_to_pseudo[p]; +} + +/* If TER decided to forward the definition of SSA name EXP this function + returns the defining statement, otherwise NULL. */ +static inline gimple +get_gimple_for_ssa_name (tree exp) +{ + int v = SSA_NAME_VERSION (exp); + if (SA.values) + return SA.values[v]; + return NULL; +} + +/* In tree-outof-ssa.c. */ +void finish_out_of_ssa (struct ssaexpand *sa); +unsigned int rewrite_out_of_ssa (struct ssaexpand *sa); +void expand_phi_nodes (struct ssaexpand *sa); + +#endif diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2c080fad8ee..4e1816a8ade 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,89 @@ +2009-04-26 Michael Matz + + Expand from SSA. + * gcc.dg/tree-ssa/20030728-1.c: Use -rtl-expand-details dump and + change regexps. + * gcc.target/i386/pr37248-1.c: Modified. + * gcc.target/i386/pr37248-3.c: Modified. + * gcc.target/i386/pr37248-2.c: Modified. + * gnat.dg/aliasing1.adb: Modified. + * gnat.dg/pack9.adb: Modified. + * gnat.dg/aliasing2.adb: Modified. + * gcc.dg/strict-overflow-2.c: Modified. + * gcc.dg/autopar/reduc-1char.c: Modified. + * gcc.dg/autopar/reduc-2char.c: Modified. + * gcc.dg/autopar/reduc-1.c: Modified. + * gcc.dg/autopar/reduc-2.c: Modified. + * gcc.dg/autopar/reduc-3.c: Modified. + * gcc.dg/autopar/reduc-6.c: Modified. + * gcc.dg/autopar/reduc-7.c: Modified. + * gcc.dg/autopar/reduc-8.c: Modified. + * gcc.dg/autopar/reduc-9.c: Modified. + * gcc.dg/autopar/reduc-1short.c: Modified. + * gcc.dg/autopar/reduc-2short.c: Modified. + * gcc.dg/autopar/parallelization-1.c: Modified. + * gcc.dg/strict-overflow-4.c: Modified. + * gcc.dg/strict-overflow-6.c: Modified. + * gcc.dg/gomp/combined-1.c: Modified. + * gcc.dg/no-strict-overflow-1.c: Modified. + * gcc.dg/no-strict-overflow-3.c: Modified. + * gcc.dg/no-strict-overflow-5.c: Modified. + * gcc.dg/tree-ssa/reassoc-13.c: Modified. + * gcc.dg/tree-ssa/pr18134.c: Modified. + * gcc.dg/tree-ssa/20030824-1.c: Modified. + * gcc.dg/tree-ssa/vector-2.c: Modified. + * gcc.dg/tree-ssa/forwprop-9.c: Modified. + * gcc.dg/tree-ssa/loop-21.c: Modified. + * gcc.dg/tree-ssa/20030824-2.c: Modified. + * gcc.dg/tree-ssa/vector-3.c: Modified. + * gcc.dg/tree-ssa/asm-3.c: Modified. + * gcc.dg/tree-ssa/pr23294.c: Modified. + * gcc.dg/tree-ssa/loop-22.c: Modified. + * gcc.dg/tree-ssa/loop-15.c: Modified. + * gcc.dg/tree-ssa/prefetch-4.c: Modified. + * gcc.dg/tree-ssa/pr22051-1.c: Modified. + * gcc.dg/tree-ssa/pr20139.c: Modified. + * gcc.dg/tree-ssa/scev-cast.c: Modified. + * gcc.dg/tree-ssa/pr22051-2.c: Modified. + * gcc.dg/tree-ssa/reassoc-1.c: Modified. + * gcc.dg/tree-ssa/loop-5.c: Modified. + * gcc.dg/tree-ssa/pr19431.c: Modified. + * gcc.dg/tree-ssa/pr32044.c: Modified. + * gcc.dg/tree-ssa/prefetch-7.c: Modified. + * gcc.dg/tree-ssa/loop-19.c: Modified. + * gcc.dg/tree-ssa/loop-28.c: Modified. + * gcc.dg/tree-ssa/ssa-pre-15.c: Modified. + * gcc.dg/tree-ssa/divide-1.c: Modified. + * gcc.dg/tree-ssa/inline-1.c: Modified. + * gcc.dg/tree-ssa/divide-3.c: Modified. + * gcc.dg/tree-ssa/pr30978.c: Modified. + * gcc.dg/tree-ssa/alias-6.c: Modified. + * gcc.dg/tree-ssa/divide-4.c: Modified. + * gcc.dg/tree-ssa/alias-11.c: Modified. + * gcc.dg/no-strict-overflow-7.c: Modified. + * gcc.dg/strict-overflow-1.c: Modified. + * gcc.dg/pr15784-4.c: Modified. + * gcc.dg/pr34263.c: Modified. + * gcc.dg/strict-overflow-3.c: Modified. + * gcc.dg/tree-prof/stringop-1.c: Modified. + * gcc.dg/tree-prof/val-prof-1.c: Modified. + * gcc.dg/tree-prof/val-prof-2.c: Modified. + * gcc.dg/tree-prof/val-prof-3.c: Modified. + * gcc.dg/tree-prof/val-prof-4.c: Modified. + * gcc.dg/no-strict-overflow-2.c: Modified. + * gcc.dg/no-strict-overflow-4.c: Modified. + * gcc.dg/no-strict-overflow-6.c: Modified. + * g++.dg/tree-ssa/pr27090.C: Modified. + * g++.dg/tree-ssa/tmmti-2.C: Modified. + * g++.dg/tree-ssa/ptrmemfield.C: Modified. + * g++.dg/tree-ssa/pr19807.C: Modified. + * g++.dg/opt/pr30965.C: Modified. + * g++.dg/init/new17.C: Modified. + * gfortran.dg/whole_file_6.f90: Modified. + * gfortran.dg/whole_file_5.f90: Modified. + * gfortran.dg/reassoc_1.f90: Modified. + * gfortran.dg/reassoc_3.f90: Modified. + 2009-04-26 Steven G. Kargl PR fortran/39893 diff --git a/gcc/testsuite/g++.dg/init/new17.C b/gcc/testsuite/g++.dg/init/new17.C index 58782ff5fba..42b9f077a1f 100644 --- a/gcc/testsuite/g++.dg/init/new17.C +++ b/gcc/testsuite/g++.dg/init/new17.C @@ -1,5 +1,5 @@ // { dg-do compile } -// { dg-options "-O2 -fstrict-aliasing -fdump-tree-final_cleanup" } +// { dg-options "-O2 -fstrict-aliasing -fdump-tree-optimized" } // Test that placement new does not introduce an unnecessary memory // barrier. @@ -33,5 +33,5 @@ void foo(Vector *m) *m = v; } -// { dg-final { scan-tree-dump-times "= 0\.0" 1 "final_cleanup" } } -// { dg-final { cleanup-tree-dump "final_cleanup" } } +// { dg-final { scan-tree-dump-times "= 0\.0" 1 "optimized" } } +// { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/g++.dg/opt/pr30965.C b/gcc/testsuite/g++.dg/opt/pr30965.C index c41cf914749..91bb55c05d8 100644 --- a/gcc/testsuite/g++.dg/opt/pr30965.C +++ b/gcc/testsuite/g++.dg/opt/pr30965.C @@ -16,5 +16,5 @@ extern void assign( long& variable, long v ) } /* { dg-final { scan-tree-dump-times ";; Function" 2 "optimized" } } */ -/* { dg-final { scan-tree-dump-times "variable = v" 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "variable_..D. = v_..D." 2 "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19807.C b/gcc/testsuite/g++.dg/tree-ssa/pr19807.C index d85b8ad8742..bba79a9d150 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr19807.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr19807.C @@ -19,6 +19,12 @@ void bar(int i) } /* { dg-final { scan-tree-dump-times "&a\\\[2\\\]" 3 "optimized" } } */ -/* { dg-final { scan-tree-dump-times "&a\\\[.* \\+ -1\\\]" 1 "optimized" } } */ -/* { dg-final { scan-tree-dump-times "&a\\\[.* \\+ 1\\\]" 1 "optimized" } } */ + +/* We want &a[D.bla + 1] and &a[D.foo - 1] in the final code, but + tuples mean that the offset is calculated in a separate instruction. + Simply test for the existence of +1 and -1 once, which also ensures + the above. If the addition/subtraction would be applied to the + pointer we would instead see +-4 (or 8, depending on sizeof(int)). */ +/* { dg-final { scan-tree-dump-times "\\\+ -1;" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\\\+ 1;" 1 "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr27090.C b/gcc/testsuite/g++.dg/tree-ssa/pr27090.C index a56357a1b52..0fb46f35db7 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/pr27090.C +++ b/gcc/testsuite/g++.dg/tree-ssa/pr27090.C @@ -17,5 +17,5 @@ int foo(Foo& f) return f.get(); } -/* { dg-final { scan-tree-dump "return f->x;" "optimized" } } */ +/* { dg-final { scan-tree-dump "f_..D.->x;" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C b/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C index 38189eb43af..c32ebba0002 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C +++ b/gcc/testsuite/g++.dg/tree-ssa/ptrmemfield.C @@ -1,5 +1,5 @@ /* { dg-do compile } */ -// { dg-options "-O2 -fdump-tree-final_cleanup" } +// { dg-options "-O2 -fdump-tree-optimized" } struct f @@ -20,8 +20,8 @@ int h(void) } /* We should have no cast to offset_type. */ -/* { dg-final { scan-tree-dump-times "offset_type" 0 "final_cleanup"} } */ +/* { dg-final { scan-tree-dump-times "offset_type" 0 "optimized"} } */ // And we should optimized this code to just return 0 -/* { dg-final { scan-tree-dump-times "return 0" 1 "final_cleanup"} } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C b/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C index fc5899465af..808b5ab275d 100644 --- a/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C +++ b/gcc/testsuite/g++.dg/tree-ssa/tmmti-2.C @@ -3,7 +3,7 @@ int a[4][8]; -int foo(int i) +int foo(long i) { return *(&a[0][0] + i*8); // a[i][0] } @@ -12,7 +12,7 @@ struct Foo { double x, y; }; Foo b[4]; -double bar(int i) +double bar(long i) { return *(&b[0].x + i*2); // b[i].x } diff --git a/gcc/testsuite/gcc.dg/autopar/parallelization-1.c b/gcc/testsuite/gcc.dg/autopar/parallelization-1.c index ee62ff666b8..f71d6d53343 100644 --- a/gcc/testsuite/gcc.dg/autopar/parallelization-1.c +++ b/gcc/testsuite/gcc.dg/autopar/parallelization-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ void abort (void); @@ -28,6 +28,6 @@ int main(void) /* Check that the first loop in parloop got parallelized. */ /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 1 "parloops" } } */ -/* { dg-final { scan-tree-dump-times "loopfn" 5 "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "loopfn" 5 "optimized" } } */ /* { dg-final { cleanup-tree-dump "parloops" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/autopar/reduc-1.c b/gcc/testsuite/gcc.dg/autopar/reduc-1.c index ac08d3d2e47..c8b624c8c5b 100644 --- a/gcc/testsuite/gcc.dg/autopar/reduc-1.c +++ b/gcc/testsuite/gcc.dg/autopar/reduc-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ #include #include @@ -54,5 +54,5 @@ int main (void) /* { dg-final { scan-tree-dump-times "Detected reduction" 3 "parloops" } } */ /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 3 "parloops" } } */ /* { dg-final { cleanup-tree-dump "parloops" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/autopar/reduc-1char.c b/gcc/testsuite/gcc.dg/autopar/reduc-1char.c index 228e97995a7..e3c73ba0d57 100644 --- a/gcc/testsuite/gcc.dg/autopar/reduc-1char.c +++ b/gcc/testsuite/gcc.dg/autopar/reduc-1char.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ #include #include @@ -49,5 +49,5 @@ int main (void) /* { dg-final { scan-tree-dump-times "Detected reduction" 3 "parloops" } } */ /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 3 "parloops" } } */ /* { dg-final { cleanup-tree-dump "parloops" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/autopar/reduc-1short.c b/gcc/testsuite/gcc.dg/autopar/reduc-1short.c index 45d96fdc926..10f1401d5c9 100644 --- a/gcc/testsuite/gcc.dg/autopar/reduc-1short.c +++ b/gcc/testsuite/gcc.dg/autopar/reduc-1short.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ #include #include @@ -49,5 +49,5 @@ int main (void) /* { dg-final { scan-tree-dump-times "Detected reduction" 3 "parloops" } } */ /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 3 "parloops" } } */ /* { dg-final { cleanup-tree-dump "parloops" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/autopar/reduc-2.c b/gcc/testsuite/gcc.dg/autopar/reduc-2.c index 684094d6319..8a0338f1c6a 100644 --- a/gcc/testsuite/gcc.dg/autopar/reduc-2.c +++ b/gcc/testsuite/gcc.dg/autopar/reduc-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ #include #include @@ -51,5 +51,5 @@ int main (void) /* { dg-final { scan-tree-dump-times "Detected reduction" 3 "parloops" } } */ /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 3 "parloops" } } */ /* { dg-final { cleanup-tree-dump "parloops" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/autopar/reduc-2char.c b/gcc/testsuite/gcc.dg/autopar/reduc-2char.c index 78e5b13aca2..0372dc6a2b2 100644 --- a/gcc/testsuite/gcc.dg/autopar/reduc-2char.c +++ b/gcc/testsuite/gcc.dg/autopar/reduc-2char.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ #include #include @@ -49,6 +49,6 @@ int main (void) /* { dg-final { scan-tree-dump-times "Detected reduction" 2 "parloops" } } */ /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 2 "parloops" } } */ /* { dg-final { cleanup-tree-dump "parloops" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/autopar/reduc-2short.c b/gcc/testsuite/gcc.dg/autopar/reduc-2short.c index cef179b7f53..4f37e864192 100644 --- a/gcc/testsuite/gcc.dg/autopar/reduc-2short.c +++ b/gcc/testsuite/gcc.dg/autopar/reduc-2short.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ #include #include @@ -48,5 +48,5 @@ int main (void) /* { dg-final { scan-tree-dump-times "Detected reduction" 2 "parloops" } } */ /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 2 "parloops" } } */ /* { dg-final { cleanup-tree-dump "parloops" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/autopar/reduc-3.c b/gcc/testsuite/gcc.dg/autopar/reduc-3.c index 97501c61584..0ec3aaa8102 100644 --- a/gcc/testsuite/gcc.dg/autopar/reduc-3.c +++ b/gcc/testsuite/gcc.dg/autopar/reduc-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ #include #include @@ -39,5 +39,5 @@ int main (void) /* { dg-final { scan-tree-dump-times "Detected reduction" 1 "parloops" } } */ /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 1 "parloops" } } */ /* { dg-final { cleanup-tree-dump "parloops" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/autopar/reduc-6.c b/gcc/testsuite/gcc.dg/autopar/reduc-6.c index b3a28a965b5..f6d503c9be4 100644 --- a/gcc/testsuite/gcc.dg/autopar/reduc-6.c +++ b/gcc/testsuite/gcc.dg/autopar/reduc-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ #include #include @@ -52,4 +52,4 @@ int main (void) /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 0 "parloops" } } */ /* { dg-final { scan-tree-dump-times "FAILED: it is not a part of reduction" 3 "parloops" } } */ /* { dg-final { cleanup-tree-dump "parloops" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/autopar/reduc-7.c b/gcc/testsuite/gcc.dg/autopar/reduc-7.c index 90bbc9806c7..f25b03abb6d 100644 --- a/gcc/testsuite/gcc.dg/autopar/reduc-7.c +++ b/gcc/testsuite/gcc.dg/autopar/reduc-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ #include @@ -78,5 +78,5 @@ int main (void) /* { dg-final { scan-tree-dump-times "Detected reduction" 2 "parloops" } } */ /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 2 "parloops" } } */ /* { dg-final { cleanup-tree-dump "parloops" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/autopar/reduc-8.c b/gcc/testsuite/gcc.dg/autopar/reduc-8.c index 4801dc782cc..801561da87d 100644 --- a/gcc/testsuite/gcc.dg/autopar/reduc-8.c +++ b/gcc/testsuite/gcc.dg/autopar/reduc-8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ #include @@ -77,4 +77,4 @@ int main (void) /* { dg-final { scan-tree-dump-times "Detected reduction" 2 "parloops" } } */ /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 2 "parloops" } } */ /* { dg-final { cleanup-tree-dump "parloops" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/autopar/reduc-9.c b/gcc/testsuite/gcc.dg/autopar/reduc-9.c index 68ed1de6175..2bc04ccfc74 100644 --- a/gcc/testsuite/gcc.dg/autopar/reduc-9.c +++ b/gcc/testsuite/gcc.dg/autopar/reduc-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */ #include @@ -77,4 +77,4 @@ int main (void) /* { dg-final { scan-tree-dump-times "Detected reduction" 2 "parloops" } } */ /* { dg-final { scan-tree-dump-times "SUCCESS: may be parallelized" 2 "parloops" } } */ /* { dg-final { cleanup-tree-dump "parloops" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/gomp/combined-1.c b/gcc/testsuite/gcc.dg/gomp/combined-1.c index fc86a9b0e32..7e2346572a2 100644 --- a/gcc/testsuite/gcc.dg/gomp/combined-1.c +++ b/gcc/testsuite/gcc.dg/gomp/combined-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -fopenmp -fdump-tree-final_cleanup" } */ +/* { dg-options "-O1 -fopenmp -fdump-tree-optimized" } */ int a[10]; int foo (void) @@ -20,5 +20,5 @@ int foo (void) } } -/* { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel_loop_runtime_start" 3 "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_GOMP_parallel_loop_runtime_start" 3 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-1.c b/gcc/testsuite/gcc.dg/no-strict-overflow-1.c index 6d449cac15e..b83b3ae80d3 100644 --- a/gcc/testsuite/gcc.dg/no-strict-overflow-1.c +++ b/gcc/testsuite/gcc.dg/no-strict-overflow-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-optimized" } */ /* Source: Ian Lance Taylor. Dual of strict-overflow-1.c. */ @@ -12,5 +12,5 @@ foo (int i) return i - 5 < 10; } -/* { dg-final { scan-tree-dump "-[ ]*5" "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump "-[ ]*5" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-2.c b/gcc/testsuite/gcc.dg/no-strict-overflow-2.c index cfe4bc16feb..aec8960ad52 100644 --- a/gcc/testsuite/gcc.dg/no-strict-overflow-2.c +++ b/gcc/testsuite/gcc.dg/no-strict-overflow-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-optimized" } */ /* Source: Ian Lance Taylor. Dual of strict-overflow-2.c. */ @@ -12,5 +12,5 @@ foo (int i) return (i * 100) / 10; } -/* { dg-final { scan-tree-dump "100" "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump "100" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-3.c b/gcc/testsuite/gcc.dg/no-strict-overflow-3.c index a98117981d5..e34e9183c0c 100644 --- a/gcc/testsuite/gcc.dg/no-strict-overflow-3.c +++ b/gcc/testsuite/gcc.dg/no-strict-overflow-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-optimized" } */ /* Source: Ian Lance Taylor. Dual of strict-overflow-3.c. */ @@ -12,5 +12,5 @@ foo (int i, int j) return i + 100 < j + 1000; } -/* { dg-final { scan-tree-dump "1000" "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump "1000" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-4.c b/gcc/testsuite/gcc.dg/no-strict-overflow-4.c index da6264a7289..32d35c4cb4b 100644 --- a/gcc/testsuite/gcc.dg/no-strict-overflow-4.c +++ b/gcc/testsuite/gcc.dg/no-strict-overflow-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-optimized" } */ /* Source: Ian Lance Taylor. Dual of strict-overflow-4.c. */ @@ -14,6 +14,6 @@ foo (int i) /* We expect to see ""; confirm that, so that we know to count it in the real test. */ -/* { dg-final { scan-tree-dump-times "\]*>" 1 "final_cleanup" } } */ -/* { dg-final { scan-tree-dump-times ">|<" 3 "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "\]*>" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times ">|<" 3 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-5.c b/gcc/testsuite/gcc.dg/no-strict-overflow-5.c index 7f82014c76e..a63bf342b56 100644 --- a/gcc/testsuite/gcc.dg/no-strict-overflow-5.c +++ b/gcc/testsuite/gcc.dg/no-strict-overflow-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-optimized" } */ /* Dual of strict-overflow-5.c. */ @@ -16,5 +16,5 @@ int foo (int i) return r; } -/* { dg-final { scan-tree-dump-times "r = 3" 0 "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "r = 3" 0 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-6.c b/gcc/testsuite/gcc.dg/no-strict-overflow-6.c index 664aa256af5..43200bb20bc 100644 --- a/gcc/testsuite/gcc.dg/no-strict-overflow-6.c +++ b/gcc/testsuite/gcc.dg/no-strict-overflow-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-optimized" } */ /* Source: Ian Lance Taylor. */ @@ -17,5 +17,5 @@ foo () return bits; } -/* { dg-final { scan-tree-dump "return bits" "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump "return bits" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-7.c b/gcc/testsuite/gcc.dg/no-strict-overflow-7.c index 07ad27b1f87..c237af98407 100644 --- a/gcc/testsuite/gcc.dg/no-strict-overflow-7.c +++ b/gcc/testsuite/gcc.dg/no-strict-overflow-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-fno-strict-overflow -O2 -fdump-tree-optimized" } */ /* Source: Ian Lance Taylor. Dual of strict-overflow-6.c. */ @@ -12,5 +12,5 @@ foo (char* p) return p + 1000 < p; } -/* { dg-final { scan-tree-dump "\[+\]\[ \]*1000" "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump "\[+\]\[ \]*1000" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr15784-4.c b/gcc/testsuite/gcc.dg/pr15784-4.c index 0d31697a9a3..6549c720555 100644 --- a/gcc/testsuite/gcc.dg/pr15784-4.c +++ b/gcc/testsuite/gcc.dg/pr15784-4.c @@ -8,6 +8,6 @@ int b (int x) { return -x -1; /* ~x */ } -/* { dg-final { scan-tree-dump "~x;" "optimized" } } */ -/* { dg-final { scan-tree-dump "-x;" "optimized" } } */ +/* { dg-final { scan-tree-dump "~x_..D.;" "optimized" } } */ +/* { dg-final { scan-tree-dump "-x_..D.;" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr34263.c b/gcc/testsuite/gcc.dg/pr34263.c index 10df9d81fc0..d389eade88e 100644 --- a/gcc/testsuite/gcc.dg/pr34263.c +++ b/gcc/testsuite/gcc.dg/pr34263.c @@ -54,6 +54,6 @@ int look( struct s *p, struct s **pp ) return( 1 ); } -/* { dg-final { scan-tree-dump "Cleaned-up latch block of loop with single BB" "optimized" } } */ +/* { dg-final { scan-tree-dump "Cleaned-up latch block of loop with single BB" "optimized" { xfail { *-*-* } } } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strict-overflow-1.c b/gcc/testsuite/gcc.dg/strict-overflow-1.c index 1ff96f4584f..f37dbd54f7f 100644 --- a/gcc/testsuite/gcc.dg/strict-overflow-1.c +++ b/gcc/testsuite/gcc.dg/strict-overflow-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fstrict-overflow -O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-fstrict-overflow -O2 -fdump-tree-optimized" } */ /* Source: Ian Lance Taylor. Dual of no-strict-overflow-1.c. */ @@ -12,5 +12,5 @@ foo (int i) return i - 5 < 10; } -/* { dg-final { scan-tree-dump-not "-[ ]*5" "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-not "-\[ \]*5" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strict-overflow-2.c b/gcc/testsuite/gcc.dg/strict-overflow-2.c index c1ec195e7ee..fd2dc69204d 100644 --- a/gcc/testsuite/gcc.dg/strict-overflow-2.c +++ b/gcc/testsuite/gcc.dg/strict-overflow-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fstrict-overflow -O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-fstrict-overflow -O2 -fdump-tree-optimized" } */ /* Source: Ian Lance Taylor. Dual of no-strict-overflow-2.c. */ @@ -12,5 +12,5 @@ foo (int i) return (i * 100) / 10; } -/* { dg-final { scan-tree-dump-not "100" "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-not "100" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strict-overflow-3.c b/gcc/testsuite/gcc.dg/strict-overflow-3.c index f179324a2fb..bdde003a14d 100644 --- a/gcc/testsuite/gcc.dg/strict-overflow-3.c +++ b/gcc/testsuite/gcc.dg/strict-overflow-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fstrict-overflow -O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-fstrict-overflow -O2 -fdump-tree-optimized" } */ /* Source: Ian Lance Taylor. Dual of no-strict-overflow-3.c. */ @@ -12,5 +12,5 @@ foo (int i, int j) return i + 100 < j + 1000; } -/* { dg-final { scan-tree-dump-not "1000" "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-not "1000" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strict-overflow-4.c b/gcc/testsuite/gcc.dg/strict-overflow-4.c index c89db2193ba..1a8c4ed4330 100644 --- a/gcc/testsuite/gcc.dg/strict-overflow-4.c +++ b/gcc/testsuite/gcc.dg/strict-overflow-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fstrict-overflow -O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-fstrict-overflow -O2 -fdump-tree-optimized" } */ /* Source: Ian Lance Taylor. Dual of no-strict-overflow-4.c. */ @@ -14,6 +14,6 @@ foo (int i) /* We expect to see ""; confirm that, so that we know to count it in the real test. */ -/* { dg-final { scan-tree-dump-times "\]*>" 1 "final_cleanup" } } */ -/* { dg-final { scan-tree-dump-times ">|<" 2 "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "\]*>" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times ">|<" 2 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strict-overflow-6.c b/gcc/testsuite/gcc.dg/strict-overflow-6.c index ec1266d1b49..d8251f4cf19 100644 --- a/gcc/testsuite/gcc.dg/strict-overflow-6.c +++ b/gcc/testsuite/gcc.dg/strict-overflow-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-fstrict-overflow -O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-fstrict-overflow -O2 -fdump-tree-optimized" } */ /* Source: Ian Lance Taylor. Dual of no-strict-overflow-7.c. */ @@ -12,5 +12,5 @@ foo (char* p) return p + 1000 < p; } -/* { dg-final { scan-tree-dump-not "\[+\]\[ \]*1000" "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-not "\[+\]\[ \]*1000" "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/stringop-1.c b/gcc/testsuite/gcc.dg/tree-prof/stringop-1.c index b57715efcb0..d32a6cedc7a 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/stringop-1.c +++ b/gcc/testsuite/gcc.dg/tree-prof/stringop-1.c @@ -16,6 +16,7 @@ main() /* { dg-final-use { scan-tree-dump "Single value 4 stringop" "tree_profile"} } */ /* Really this ought to simplify into assignment, but we are not there yet. */ /* a[0] = b[0] is what we fold the resulting memcpy into. */ -/* { dg-final-use { scan-tree-dump "a.0. = b.0." "optimized"} } */ +/* { dg-final-use { scan-tree-dump "a.0. = " "optimized"} } */ +/* { dg-final-use { scan-tree-dump "= b.0." "optimized"} } */ /* { dg-final-use { cleanup-tree-dump "optimized" } } */ /* { dg-final-use { cleanup-tree-dump "tree_profile" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c index dfe994ffef9..4d9cb1b9969 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c @@ -16,7 +16,7 @@ main () return 0; } /* { dg-final-use { scan-tree-dump "Div.mod by constant n=257 transformation on insn" "tree_profile"} } */ -/* { dg-final-use { scan-tree-dump "if \\(n != 257\\)" "optimized"} } */ +/* { dg-final-use { scan-tree-dump "if \\(n_\[0-9\]* != 257\\)" "optimized"} } */ /* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ /* { dg-final-use { cleanup-tree-dump "optimized" } } */ /* { dg-final-use { cleanup-tree-dump "tree_profile" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c index 66b0614c5ef..30a92c0157f 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c @@ -26,7 +26,7 @@ main () /* { dg-final-use { scan-tree-dump "Mod power of 2 transformation on insn" "tree_profile"} } */ /* This is part of code checking that n is power of 2, so we are sure that the transformation didn't get optimized out. */ -/* { dg-final-use { scan-tree-dump "n \\+ 0xffff" "optimized"} } */ +/* { dg-final-use { scan-tree-dump "n_\[0-9\]* \\+ 0xffff" "optimized"} } */ /* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ /* { dg-final-use { cleanup-tree-dump "optimized" } } */ /* { dg-final-use { cleanup-tree-dump "tree_profile" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c index f233d670cc2..ad32a44b32d 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c @@ -26,7 +26,7 @@ main () /* { dg-final-use { scan-tree-dump "Mod subtract transformation on insn" "tree_profile"} } */ /* This is part of code checking that n is greater than the divisor so we are sure that it didn't get optimized out. */ -/* { dg-final-use { scan-tree-dump "if \\(n \\>" "optimized"} } */ +/* { dg-final-use { scan-tree-dump "if \\(n_\[0-9\]* \\>" "optimized"} } */ /* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ /* { dg-final-use { cleanup-tree-dump "optimized" } } */ /* { dg-final-use { cleanup-tree-dump "tree_profile" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c index 86418e05e3a..fdc2b0c6d65 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c +++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c @@ -26,7 +26,7 @@ main () /* { dg-final-use { scan-tree-dump "Mod subtract transformation on insn" "tree_profile"} } */ /* This is part of code checking that n is greater than the divisor so we are sure that it didn't get optimized out. */ -/* { dg-final-use { scan-tree-dump "if \\(n \\>" "optimized"} } */ +/* { dg-final-use { scan-tree-dump "if \\(n_\[0-9\]* \\>" "optimized"} } */ /* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */ /* { dg-final-use { cleanup-tree-dump "optimized" } } */ /* { dg-final-use { cleanup-tree-dump "tree_profile" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c index 1ad2c63653c..f884736a1c9 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030728-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -fdump-rtl-expand-details" } */ union tree_node; @@ -42,6 +42,6 @@ objects_must_conflict_p (t1, t2) } /* There should be two assignments of variables to the value zero. */ -/* { dg-final { scan-tree-dump-times " = 0" 2 "final_cleanup"} } */ +/* { dg-final { scan-rtl-dump-times "PART.. = 0" 2 "expand"} } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-rtl-dump "expand" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c index da1389e916c..e5988bd7998 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030824-1.c @@ -19,5 +19,5 @@ int foo (int x, int y) } /* The addition should be optimized into 'y+x'. */ -/* { dg-final { scan-tree-dump-times "\[xy\] \\+ \[xy]" 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "\[xy\]_..D. \\+ \[xy]_..D." 1 "optimized"} } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c b/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c index 1b8bc48147f..1234aeb34d1 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20030824-2.c @@ -19,5 +19,5 @@ int foo (int x, int y) } /* This function should be optimized into 'return y+x'. */ -/* { dg-final { scan-tree-dump-times "return \[xy\] \\+ \[xy\]" 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "\[xy\]_..D. \\+ \[xy]_..D." 1 "optimized"} } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-11.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-11.c index cccc512cbe1..d4ce34bd8cb 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/alias-11.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-11.c @@ -14,6 +14,8 @@ int bar(void) return a[0] + *p.a; } -/* { dg-final { scan-tree-dump "return \\*p\\.a \\\+ a.0.;" "optimized" } } */ +/* We need to have both: a load from "a[0]" and a load from "*p.a", + the latter can be an ssa temporary. */ +/* { dg-final { scan-tree-dump "= a.0.;" "optimized" } } */ +/* { dg-final { scan-tree-dump "= \\*\[pD\]" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ - diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-6.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-6.c index 460dd11cd48..bcc011898fa 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/alias-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-6.c @@ -14,6 +14,8 @@ int bar(void) return a[0] + *p.a; } -/* { dg-final { scan-tree-dump "return \\*p\\.a \\\+ a.0.;" "optimized" } } */ +/* We need to have both: a load from "a[0]" and a load from "*p.a", + the latter can be an ssa temporary. */ +/* { dg-final { scan-tree-dump "= a.0.;" "optimized" } } */ +/* { dg-final { scan-tree-dump "= \\*\[pD\]" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ - diff --git a/gcc/testsuite/gcc.dg/tree-ssa/asm-3.c b/gcc/testsuite/gcc.dg/tree-ssa/asm-3.c index fdcddb7a5fa..e35d179c547 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/asm-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/asm-3.c @@ -27,6 +27,6 @@ void test(void) /* { dg-final { scan-tree-dump-times "hardreg" 3 "optimized" } } */ /* In particular, hardreg should *not* appear in the call to bar. */ -/* { dg-final { scan-tree-dump-times "bar \[(\]t\[)\]" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "bar \[(\]t_.\[)\]" 1 "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/divide-1.c b/gcc/testsuite/gcc.dg/tree-ssa/divide-1.c index fdd3f44e040..66bc3745bcc 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/divide-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/divide-1.c @@ -7,8 +7,8 @@ int f(int a) } -/* { dg-final { scan-tree-dump-times "-a / 10" 0 "optimized"} } */ -/* { dg-final { scan-tree-dump-times "a / -10" 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "-a" 0 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "a_..D. / -10" 1 "optimized"} } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/divide-3.c b/gcc/testsuite/gcc.dg/tree-ssa/divide-3.c index d305b549cbd..12fa09b9536 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/divide-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/divide-3.c @@ -6,8 +6,8 @@ int f(int a) return -(a/10); } -/* { dg-final { scan-tree-dump-times "a / 10" 0 "optimized"} } */ -/* { dg-final { scan-tree-dump-times "a / -10" 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "a_\[0-9()D\]* / 10" 0 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "a_..D. / -10" 1 "optimized"} } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/divide-4.c b/gcc/testsuite/gcc.dg/tree-ssa/divide-4.c index b1bb1efa9e1..734acad69a7 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/divide-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/divide-4.c @@ -6,8 +6,8 @@ int f(int a) return -(-a/10); } -/* { dg-final { scan-tree-dump-times "-a / 10" 0 "optimized"} } */ -/* { dg-final { scan-tree-dump-times "a / 10" 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "-a" 0 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "a_..D. / 10" 1 "optimized"} } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c index 4469fe7312e..cc583e293f8 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-9.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O1 -fdump-tree-final_cleanup -fdump-tree-fre -W -Wall -fno-early-inlining" } */ +/* { dg-options "-O1 -fdump-tree-optimized -fdump-tree-fre -W -Wall -fno-early-inlining" } */ int b; unsigned a; @@ -15,7 +15,7 @@ void f(void) /* We should have converted the assignments to two = 1. FRE does this. */ -/* { dg-final { scan-tree-dump-times " = 1" 2 "final_cleanup"} } */ +/* { dg-final { scan-tree-dump-times " = 1" 2 "optimized"} } */ /* { dg-final { scan-tree-dump-not " = a;" "fre"} } */ /* { dg-final { cleanup-tree-dump "fre" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/inline-1.c b/gcc/testsuite/gcc.dg/tree-ssa/inline-1.c index 7b9e3be499a..030181404d1 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/inline-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/inline-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ typedef struct { @@ -20,6 +20,6 @@ interval foo (interval a, interval b, interval c) } -/* { dg-final { scan-tree-dump-times "\\(struct interval\\)" 0 "final_cleanup"} } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "\\(struct interval\\)" 0 "optimized"} } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c index ad0995d262c..aa0747b6e7e 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-15.c @@ -20,7 +20,7 @@ int bla(void) /* Since the loop is removed, there should be no addition. */ /* { dg-final { scan-tree-dump-times "\\+" 0 "optimized" } } */ -/* { dg-final { scan-tree-dump-times "n \\* n" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "n_. \\* n_." 1 "optimized" } } */ /* The if from the loop header copying remains in the code. */ /* { dg-final { scan-tree-dump-times "if " 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-19.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-19.c index cae91bac4ba..9ec893298a1 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-19.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-19.c @@ -6,7 +6,7 @@ /* { dg-do compile { target { i?86-*-* || { x86_64-*-* || powerpc_hard_double } } } } */ /* { dg-require-effective-target nonpic } */ -/* { dg-options "-O3 -fdump-tree-final_cleanup" } */ +/* { dg-options "-O3 -fdump-tree-optimized" } */ # define N 2000000 static double a[N],c[N]; @@ -22,7 +22,7 @@ void tuned_STREAM_Copy() However, due to a bug in jump threading, we end up peeling one iteration from the loop, which creates an additional occurence. */ -/* { dg-final { scan-tree-dump-times "MEM.(base: &|symbol: )a," 2 "final_cleanup" } } */ -/* { dg-final { scan-tree-dump-times "MEM.(base: &|symbol: )c," 2 "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "MEM.(base: &|symbol: )a," 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "MEM.(base: &|symbol: )c," 2 "optimized" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-21.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-21.c index 59a17cb5e7f..f53407d9b02 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-21.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-21.c @@ -1,7 +1,7 @@ /* PR tree-optimization/30322 */ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ extern void op( int, int); void foo(int f0, int f1, int e0, int e1) @@ -13,5 +13,5 @@ void foo(int f0, int f1, int e0, int e1) op(i0, i1); } -/* { dg-final { scan-tree-dump-times "~" 0 "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "~" 0 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-22.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-22.c index be8cdcc77d4..fa7da712b6a 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-22.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-22.c @@ -1,4 +1,4 @@ -/* { dg-options "-O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ int a[100]; @@ -13,5 +13,5 @@ void test (int n) /* We used to replace the exit test "i < n" by "i != ((n-1)/3) * 3 + 1". Although correct, this transformation is obviously harmful. */ -/* { dg-final { scan-tree-dump-times "/" 0 "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "/" 0 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-28.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-28.c index 19f0ac5c184..77d0c47dc95 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-28.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-28.c @@ -1,6 +1,6 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ /* { dg-require-effective-target ilp32 } */ -/* { dg-options "-O2 -fprefetch-loop-arrays -march=athlon -fdump-tree-final_cleanup -fdump-tree-aprefetch --param max-unrolled-insns=1000" } */ +/* { dg-options "-O2 -fprefetch-loop-arrays -march=athlon -fdump-tree-optimized -fdump-tree-aprefetch --param max-unrolled-insns=1000" } */ char x[100000]; @@ -15,10 +15,10 @@ void foo(int n) /* There should be 64 MEMs in the unrolled loop and one more in the copy of the loop for the rest of the iterations. */ -/* { dg-final { scan-tree-dump-times "MEM" 65 "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "MEM" 65 "optimized" } } */ /* There should be no i_a = i_b assignments. */ /* { dg-final { scan-tree-dump-times "i_.*= i_\[0-9\]*;" 0 "aprefetch" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ /* { dg-final { cleanup-tree-dump "aprefetch" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-5.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-5.c index f0ba475c798..a8db74afe14 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-5.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-5.c @@ -19,7 +19,9 @@ void xxx(void) /* Only iter variable should remain. */ /* { dg-final { scan-tree-dump-times "int iter" 1 "optimized" } } */ -/* { dg-final { scan-tree-dump-times "jter" 0 "optimized" } } */ + +/* And jter shouldn't be an induction variable anymore (no PHI node). */ +/* { dg-final { scan-tree-dump-times "jter_\[0-9\]* = PHI" 0 "optimized" } } */ /* And the use of jter should be replaced by iter + 2 */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr18134.c b/gcc/testsuite/gcc.dg/tree-ssa/pr18134.c index d126313feed..783d598a0ed 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr18134.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr18134.c @@ -17,7 +17,7 @@ return 0; /* Everything should have been cleaned up leaving a simple return statement. */ -/* { dg-final { scan-tree-dump-times "return.*a != 0" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "= a_..D. != 0" 1 "optimized" } } */ /* There should not be any abnormal edges as DOM removed the computed gotos. */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr19431.c b/gcc/testsuite/gcc.dg/tree-ssa/pr19431.c index 4334648ce64..1c87acbddda 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr19431.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr19431.c @@ -24,6 +24,6 @@ int f(int k, int i1, int j1) return *f1; } -/* { dg-final { scan-tree-dump "i1 = j1" "optimized" } } */ -/* { dg-final { scan-tree-dump "return i1;" "optimized" } } */ +/* { dg-final { scan-tree-dump "i1_. = PHI \]*>" "optimized" } } */ +/* { dg-final { scan-tree-dump "return i1_.;" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr20139.c b/gcc/testsuite/gcc.dg/tree-ssa/pr20139.c index 054e4b2081c..016ad004ee8 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr20139.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr20139.c @@ -3,7 +3,7 @@ that the optimization happens at tree level. */ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ extern double fabs (double); extern void link_error (void); @@ -19,5 +19,5 @@ foo (double x) link_error (); } -/* { dg-final { scan-tree-dump-times "link_error" 0 "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "link_error" 0 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr22051-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr22051-1.c index 4815be0ac9e..73bda118fe5 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr22051-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr22051-1.c @@ -17,7 +17,7 @@ foo() /* The cast to a function pointer type must remain after all optimizations are complete so that function pointer canonicalization works on those targets which require it. */ -/* { dg-final { scan-tree-dump-times "if \\(\\(void \\(\\*<.*>\\) \\(void\\)\\) p" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "= \\(void \\(\\*<.*>\\) \\(void\\)\\) p_" 1 "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr22051-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr22051-2.c index a6b7099d634..bcbbb73c659 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr22051-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr22051-2.c @@ -20,6 +20,6 @@ foo() /* The cast to an int type must remain after all optimizations are complete so that we do not try to canonicalize a function pointer for the comparison when no such canonicalization is wanted. */ -/* { dg-final { scan-tree-dump-times "if \\(\\(int\\).*q" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "r_. = \\(int\\) q" 1 "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23294.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23294.c index d73512d7af5..ed890fa5514 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr23294.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23294.c @@ -31,7 +31,7 @@ int f6(int a, int b) return 6*a - 2*b; } -/* { dg-final { scan-tree-dump-times "a \\\* 5" 3 "optimized" } } */ -/* { dg-final { scan-tree-dump-times "\\\) \\\* 2" 3 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "a_..D. \\\* 5" 3 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " \\\* 2" 3 "optimized" } } */ /* { dg-final { scan-tree-dump-not "\\\* 6" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr30978.c b/gcc/testsuite/gcc.dg/tree-ssa/pr30978.c index 5444e2d197c..3329383cbe8 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr30978.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr30978.c @@ -10,5 +10,5 @@ int foo(int a) return e; } -/* { dg-final { scan-tree-dump "return a > 0;" "optimized" } } */ +/* { dg-final { scan-tree-dump "e_. = a_..D. > 0;" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c b/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c index 0c1a58206f4..940a0362943 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr32044.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-empty -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -fdump-tree-empty -fdump-tree-optimized" } */ int foo (int n) { @@ -48,8 +48,8 @@ int baz (int n) /* There should be no division/modulo in the final dump (division and modulo by 64 are done using bit operations). */ -/* { dg-final { scan-tree-dump-times "/" 0 "final_cleanup" } } */ -/* { dg-final { scan-tree-dump-times "%" 0 "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "/" 0 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "%" 0 "optimized" } } */ /* { dg-final { cleanup-tree-dump "empty" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/prefetch-4.c b/gcc/testsuite/gcc.dg/tree-ssa/prefetch-4.c index 8a5230eedd3..bff4b9fbf12 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/prefetch-4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/prefetch-4.c @@ -2,7 +2,7 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ /* { dg-require-effective-target ilp32 } */ -/* { dg-options "-O2 -fprefetch-loop-arrays -march=athlon -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -fprefetch-loop-arrays -march=athlon -fdump-tree-optimized" } */ int xxx[20]; @@ -14,5 +14,5 @@ void foo (int n) xxx[i] = i; } -/* { dg-final { scan-tree-dump-times "prefetch" 0 "final_cleanup" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "prefetch" 0 "optimized" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/prefetch-7.c b/gcc/testsuite/gcc.dg/tree-ssa/prefetch-7.c index 510dee04598..3024bed1b71 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/prefetch-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/prefetch-7.c @@ -1,6 +1,6 @@ /* { dg-do compile { target i?86-*-* x86_64-*-* } } */ /* { dg-require-effective-target ilp32 } */ -/* { dg-options "-O2 -fprefetch-loop-arrays -march=athlon -msse2 -mfpmath=sse --param simultaneous-prefetches=100 --param max-unrolled-insns=1 -fdump-tree-aprefetch-details -fdump-tree-final_cleanup" } */ +/* { dg-options "-O2 -fprefetch-loop-arrays -march=athlon -msse2 -mfpmath=sse --param simultaneous-prefetches=100 --param max-unrolled-insns=1 -fdump-tree-aprefetch-details -fdump-tree-optimized" } */ #define K 1000000 int a[K], b[K]; @@ -45,9 +45,9 @@ void test(int *p) /* { dg-final { scan-tree-dump-times "Issued nontemporal prefetch" 3 "aprefetch" } } */ /* { dg-final { scan-tree-dump-times "nontemporal store" 2 "aprefetch" } } */ -/* { dg-final { scan-tree-dump-times "builtin_prefetch" 8 "final_cleanup" } } */ -/* { dg-final { scan-tree-dump-times "=\\{nt\\}" 2 "final_cleanup" } } */ -/* { dg-final { scan-tree-dump-times "__builtin_ia32_mfence" 2 "final_cleanup" } } */ +/* { dg-final { scan-tree-dump-times "builtin_prefetch" 8 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "=\\{nt\\}" 2 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "__builtin_ia32_mfence" 2 "optimized" } } */ /* { dg-final { scan-assembler-times "prefetchw" 5 } } */ /* { dg-final { scan-assembler-times "prefetcht" 1 } } */ @@ -56,4 +56,4 @@ void test(int *p) /* { dg-final { scan-assembler-times "mfence" 2 } } */ /* { dg-final { cleanup-tree-dump "aprefetch" } } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-1.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-1.c index 166780adf87..ea5e4a77b11 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-1.c @@ -14,5 +14,6 @@ int main(void) printf ("%d %d\n", e, f); } -/* { dg-final { scan-tree-dump-times "b \\\+ a" 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "b.._. \\\+ a.._." 1 "optimized"} } */ +/* { dg-final { scan-tree-dump-times " \\\+ " 2 "optimized"} } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-13.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-13.c index 4d4dfeb446b..f05401cba1f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-13.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-13.c @@ -10,6 +10,6 @@ double foo(double a) } /* { dg-final { scan-tree-dump-not "\\\+ 0.0" "reassoc1" } } */ -/* { dg-final { scan-tree-dump "return a;" "optimized" } } */ +/* { dg-final { scan-tree-dump "return a_..D.;" "optimized" } } */ /* { dg-final { cleanup-tree-dump "reassoc1" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/scev-cast.c b/gcc/testsuite/gcc.dg/tree-ssa/scev-cast.c index fe6dde4bb19..2cf245460ee 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/scev-cast.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/scev-cast.c @@ -20,7 +20,7 @@ void tst(void) blau ((unsigned char) i); /* This one is necessary. */ } -/* { dg-final { scan-tree-dump-times "\\(int\\) \\(unsigned char\\)" 1 "optimized" } } */ -/* { dg-final { scan-tree-dump-times "\\(int\\) \\(char\\)" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "= \\(unsigned char\\)" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "= \\(char\\)" 1 "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c index 518fda854e6..ed3b2f7840f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-options "-O2 -fdump-rtl-expand-details" } */ /* Verify we PRE the strlen call, as strlen("") folds to zero. */ @@ -12,5 +12,5 @@ __SIZE_TYPE__ mystrlen (const char *s) return strlen(s); } -/* { dg-final { scan-tree-dump "= 0;" "optimized" } } */ -/* { dg-final { cleanup-tree-dump "optimized" } } */ +/* { dg-final { scan-rtl-dump "PART.. = 0" "expand" } } */ +/* { dg-final { cleanup-rtl-dump "expand" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vector-2.c b/gcc/testsuite/gcc.dg/tree-ssa/vector-2.c index 2ce438899a5..cb680937a2f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vector-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vector-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-w -O1 -fdump-tree-final_cleanup" } */ +/* { dg-options "-w -O1 -fdump-tree-optimized" } */ #define vector __attribute__(( vector_size(16) )) @@ -16,7 +16,7 @@ float f(vector float a, int b, vector float c) } /* We should be able to optimize this to just "return 0.0;" */ -/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 0 "final_cleanup"} } */ -/* { dg-final { scan-tree-dump-times "0.0" 1 "final_cleanup"} } */ +/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 0 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "0.0" 1 "optimized"} } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vector-3.c b/gcc/testsuite/gcc.dg/tree-ssa/vector-3.c index 332e127ddcc..15a700c658e 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vector-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vector-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-w -O1 -fdump-tree-final_cleanup" } */ +/* { dg-options "-w -O1 -fdump-tree-optimized" } */ #define vector __attribute((vector_size(16) )) vector float a; @@ -13,8 +13,8 @@ float f(float b) } /* We should be able to optimize this to just "return 0.0;" */ -/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 0 "final_cleanup"} } */ -/* { dg-final { scan-tree-dump-times "0.0" 1 "final_cleanup"} } */ +/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 0 "optimized"} } */ +/* { dg-final { scan-tree-dump-times "0.0" 1 "optimized"} } */ -/* { dg-final { cleanup-tree-dump "final_cleanup" } } */ +/* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr37248-1.c b/gcc/testsuite/gcc.target/i386/pr37248-1.c index c8737950896..4107fd6e2cd 100644 --- a/gcc/testsuite/gcc.target/i386/pr37248-1.c +++ b/gcc/testsuite/gcc.target/i386/pr37248-1.c @@ -15,5 +15,6 @@ foo (struct S x) return x.a && x.b && x.c; } -/* { dg-final { scan-tree-dump "& 7\[^\n\t\]*== 7" "optimized" } } */ +/* { dg-final { scan-tree-dump "& 7;" "optimized" } } */ +/* { dg-final { scan-tree-dump "== 7;" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr37248-2.c b/gcc/testsuite/gcc.target/i386/pr37248-2.c index ed483831a5e..0265a8ac64f 100644 --- a/gcc/testsuite/gcc.target/i386/pr37248-2.c +++ b/gcc/testsuite/gcc.target/i386/pr37248-2.c @@ -19,5 +19,6 @@ foo (struct S x) return x.a && x.g && x.b && x.f && x.c && x.e; } -/* { dg-final { scan-tree-dump "& (3758096391|0x0e0000007)\[^\n\t\]*== (3758096391|0x0e0000007)" "optimized" } } */ +/* { dg-final { scan-tree-dump "& (3758096391|0x0e0000007);" "optimized" } } */ +/* { dg-final { scan-tree-dump "== (3758096391|0x0e0000007);" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr37248-3.c b/gcc/testsuite/gcc.target/i386/pr37248-3.c index 3b320d7055d..309184ba045 100644 --- a/gcc/testsuite/gcc.target/i386/pr37248-3.c +++ b/gcc/testsuite/gcc.target/i386/pr37248-3.c @@ -21,5 +21,6 @@ foo (struct S x) return x.a && x.i && x.b && x.h && x.c && x.g && x.e == 131; } -/* { dg-final { scan-tree-dump "& (3766484487|0x0e07ffe07)\[^\n\t\]*== (3758163463|0x0e0010607)" "optimized" } } */ +/* { dg-final { scan-tree-dump "& (3766484487|0x0e07ffe07);" "optimized" } } */ +/* { dg-final { scan-tree-dump "== (3758163463|0x0e0010607);" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gfortran.dg/reassoc_1.f90 b/gcc/testsuite/gfortran.dg/reassoc_1.f90 index 71a9bc9286e..3857dedf71e 100644 --- a/gcc/testsuite/gfortran.dg/reassoc_1.f90 +++ b/gcc/testsuite/gfortran.dg/reassoc_1.f90 @@ -7,5 +7,7 @@ function test(b) test = a end -! { dg-final { scan-tree-dump "\\\+ 5.*\\\)\\\) - 5" "optimized" } } +! We need an explicit +5 and -5, and an intermediate ((bla)) expression +! (the reassoc barrier). Make use of "." matching lineends. +! { dg-final { scan-tree-dump "\\\+ 5.*\\\)\\\).* - 5" "optimized" } } ! { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gfortran.dg/reassoc_3.f90 b/gcc/testsuite/gfortran.dg/reassoc_3.f90 index 20fd925f563..84a33972270 100644 --- a/gcc/testsuite/gfortran.dg/reassoc_3.f90 +++ b/gcc/testsuite/gfortran.dg/reassoc_3.f90 @@ -14,6 +14,7 @@ function test(a) end ! { dg-final { scan-tree-dump "b = 5" "original" } } -! { dg-final { scan-tree-dump "return .a" "optimized" } } +! { dg-final { scan-tree-dump "c_. = .a" "optimized" } } +! { dg-final { scan-tree-dump "return c_.;" "optimized" } } ! { dg-final { cleanup-tree-dump "original" } } ! { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gfortran.dg/whole_file_5.f90 b/gcc/testsuite/gfortran.dg/whole_file_5.f90 index a0350466373..898b4e6848e 100644 --- a/gcc/testsuite/gfortran.dg/whole_file_5.f90 +++ b/gcc/testsuite/gfortran.dg/whole_file_5.f90 @@ -16,3 +16,4 @@ PROGRAM main END PROGRAM ! { dg-final { scan-tree-dump-times "= f\(\)" 0 "optimized" } } +! { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gfortran.dg/whole_file_6.f90 b/gcc/testsuite/gfortran.dg/whole_file_6.f90 index cb9e737104c..157cfa11526 100644 --- a/gcc/testsuite/gfortran.dg/whole_file_6.f90 +++ b/gcc/testsuite/gfortran.dg/whole_file_6.f90 @@ -16,3 +16,4 @@ INTEGER FUNCTION f() END FUNCTION ! { dg-final { scan-tree-dump-times "= f\(\)" 0 "optimized" } } +! { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gnat.dg/aliasing1.adb b/gcc/testsuite/gnat.dg/aliasing1.adb index 5d928bbc0c0..b2b7d123b1f 100644 --- a/gcc/testsuite/gnat.dg/aliasing1.adb +++ b/gcc/testsuite/gnat.dg/aliasing1.adb @@ -1,5 +1,5 @@ -- { dg-do compile } --- { dg-options "-O2 -gnatp -fdump-tree-final_cleanup" } +-- { dg-options "-O2 -gnatp -fdump-tree-optimized" } -- The raise statement must be optimized away by -- virtue of DECL_NONADDRESSABLE_P set on R.I. @@ -18,5 +18,5 @@ package body Aliasing1 is end Aliasing1; --- { dg-final { scan-tree-dump-not "__gnat_rcheck" "final_cleanup" } } --- { dg-final { cleanup-tree-dump "final_cleanup" } } +-- { dg-final { scan-tree-dump-not "__gnat_rcheck" "optimized" } } +-- { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gnat.dg/aliasing2.adb b/gcc/testsuite/gnat.dg/aliasing2.adb index abfc6e11a3f..065cee02f7d 100644 --- a/gcc/testsuite/gnat.dg/aliasing2.adb +++ b/gcc/testsuite/gnat.dg/aliasing2.adb @@ -1,5 +1,5 @@ -- { dg-do compile } --- { dg-options "-O2 -gnatp -fdump-tree-final_cleanup" } +-- { dg-options "-O2 -gnatp -fdump-tree-optimized" } -- The raise statement must be optimized away by -- virtue of TYPE_NONALIASED_COMPONENT set on A. @@ -18,5 +18,5 @@ package body Aliasing2 is end Aliasing2; --- { dg-final { scan-tree-dump-not "__gnat_rcheck" "final_cleanup" } } --- { dg-final { cleanup-tree-dump "final_cleanup" } } +-- { dg-final { scan-tree-dump-not "__gnat_rcheck" "optimized" } } +-- { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/testsuite/gnat.dg/pack9.adb b/gcc/testsuite/gnat.dg/pack9.adb index 894ecd6bb06..64d71b11cc9 100644 --- a/gcc/testsuite/gnat.dg/pack9.adb +++ b/gcc/testsuite/gnat.dg/pack9.adb @@ -1,5 +1,5 @@ -- { dg-do compile } --- { dg-options "-O2 -gnatp -cargs --param sra-max-structure-size=24 --param sra-max-structure-count=6 -fdump-tree-final_cleanup" } +-- { dg-options "-O2 -gnatp -cargs --param sra-max-structure-size=24 --param sra-max-structure-count=6 -fdump-tree-optimized" } package body Pack9 is @@ -14,5 +14,5 @@ package body Pack9 is end Pack9; --- { dg-final { scan-tree-dump-not "__gnat_rcheck" "final_cleanup" } } --- { dg-final { cleanup-tree-dump "final_cleanup" } } +-- { dg-final { scan-tree-dump-not "__gnat_rcheck" "optimized" } } +-- { dg-final { cleanup-tree-dump "optimized" } } diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 8cb69acfa56..d302cd2d5fc 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -199,10 +199,6 @@ enum noalias_state { struct GTY(()) var_ann_d { struct tree_ann_common_d common; - /* Used by the out of SSA pass to determine whether this variable has - been seen yet or not. */ - unsigned out_of_ssa_tag : 1; - /* Used when building base variable structures in a var_map. */ unsigned base_var_processed : 1; @@ -224,10 +220,6 @@ struct GTY(()) var_ann_d { information on each attribute. */ ENUM_BITFIELD (noalias_state) noalias_state : 2; - /* Used when going out of SSA form to indicate which partition this - variable represents storage for. */ - unsigned partition; - /* Used by var_map for the base index of ssa base variables. */ unsigned base_index; @@ -960,6 +952,7 @@ rtx addr_for_mem_ref (struct mem_address *, bool); void get_address_description (tree, struct mem_address *); tree maybe_fold_tmr (tree); +unsigned int execute_free_datastructures (void); unsigned int execute_fixup_cfg (void); #include "tree-flow-inline.h" diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c index 23cd169ae09..e2116e5a380 100644 --- a/gcc/tree-mudflap.c +++ b/gcc/tree-mudflap.c @@ -459,11 +459,11 @@ mf_decl_cache_locals (void) /* Build the cache vars. */ mf_cache_shift_decl_l - = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_shift_decl), + = mf_mark (make_rename_temp (TREE_TYPE (mf_cache_shift_decl), "__mf_lookup_shift_l")); mf_cache_mask_decl_l - = mf_mark (create_tmp_var (TREE_TYPE (mf_cache_mask_decl), + = mf_mark (make_rename_temp (TREE_TYPE (mf_cache_mask_decl), "__mf_lookup_mask_l")); /* Build initialization nodes for the cache vars. We just load the @@ -546,9 +546,9 @@ mf_build_check_statement_for (tree base, tree limit, } /* Build our local variables. */ - mf_elem = create_tmp_var (mf_cache_structptr_type, "__mf_elem"); - mf_base = create_tmp_var (mf_uintptr_type, "__mf_base"); - mf_limit = create_tmp_var (mf_uintptr_type, "__mf_limit"); + mf_elem = make_rename_temp (mf_cache_structptr_type, "__mf_elem"); + mf_base = make_rename_temp (mf_uintptr_type, "__mf_base"); + mf_limit = make_rename_temp (mf_uintptr_type, "__mf_limit"); /* Build: __mf_base = (uintptr_t) . */ seq = gimple_seq_alloc (); @@ -627,7 +627,7 @@ mf_build_check_statement_for (tree base, tree limit, t = build2 (TRUTH_OR_EXPR, boolean_type_node, t, u); t = force_gimple_operand (t, &stmts, false, NULL_TREE); gimple_seq_add_seq (&seq, stmts); - cond = create_tmp_var (boolean_type_node, "__mf_unlikely_cond"); + cond = make_rename_temp (boolean_type_node, "__mf_unlikely_cond"); g = gimple_build_assign (cond, t); gimple_set_location (g, location); gimple_seq_add_stmt (&seq, g); @@ -1366,12 +1366,12 @@ struct gimple_opt_pass pass_mudflap_2 = NULL, /* next */ 0, /* static_pass_number */ TV_NONE, /* tv_id */ - PROP_gimple_leh, /* properties_required */ + PROP_ssa | PROP_cfg | PROP_gimple_leh,/* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_verify_flow | TODO_verify_stmts - | TODO_dump_func /* todo_flags_finish */ + | TODO_dump_func | TODO_update_ssa /* todo_flags_finish */ } }; diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c index a82a3b01c68..07245cd6d7b 100644 --- a/gcc/tree-nrv.c +++ b/gcc/tree-nrv.c @@ -56,6 +56,7 @@ struct nrv_data /* This is the function's RESULT_DECL. We will replace all occurrences of VAR with RESULT_DECL when we apply this optimization. */ tree result; + int modified; }; static tree finalize_nrv_r (tree *, int *, void *); @@ -83,7 +84,10 @@ finalize_nrv_r (tree *tp, int *walk_subtrees, void *data) /* Otherwise replace all occurrences of VAR with RESULT. */ else if (*tp == dp->var) - *tp = dp->result; + { + *tp = dp->result; + dp->modified = 1; + } /* Keep iterating. */ return NULL_TREE; @@ -229,13 +233,19 @@ tree_nrv (void) if (gimple_assign_copy_p (stmt) && gimple_assign_lhs (stmt) == result && gimple_assign_rhs1 (stmt) == found) - gsi_remove (&gsi, true); + { + unlink_stmt_vdef (stmt); + gsi_remove (&gsi, true); + } else { struct walk_stmt_info wi; memset (&wi, 0, sizeof (wi)); wi.info = &data; + data.modified = 0; walk_gimple_op (stmt, finalize_nrv_r, &wi); + if (data.modified) + update_stmt (stmt); gsi_next (&gsi); } } @@ -263,7 +273,7 @@ struct gimple_opt_pass pass_nrv = NULL, /* next */ 0, /* static_pass_number */ TV_TREE_NRV, /* tv_id */ - PROP_cfg, /* properties_required */ + PROP_ssa | PROP_cfg, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index 666b31bd844..7b4913c5bf7 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -201,7 +201,7 @@ struct gimple_opt_pass pass_cleanup_cfg_post_optimizing = { { GIMPLE_PASS, - "final_cleanup", /* name */ + "optimized", /* name */ NULL, /* gate */ execute_cleanup_cfg_post_optimizing, /* execute */ NULL, /* sub */ @@ -213,13 +213,14 @@ struct gimple_opt_pass pass_cleanup_cfg_post_optimizing = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_dump_func /* todo_flags_finish */ + | TODO_remove_unused_locals } }; /* Pass: do the actions required to finish with tree-ssa optimization passes. */ -static unsigned int +unsigned int execute_free_datastructures (void) { free_dominance_info (CDI_DOMINATORS); @@ -228,6 +229,10 @@ execute_free_datastructures (void) /* Remove the ssa structures. */ if (cfun->gimple_df) delete_tree_ssa (); + + /* And get rid of annotations we no longer need. */ + delete_tree_cfg_annotations (); + return 0; } @@ -254,9 +259,6 @@ struct gimple_opt_pass pass_free_datastructures = static unsigned int execute_free_cfg_annotations (void) { - /* And get rid of annotations we no longer need. */ - delete_tree_cfg_annotations (); - return 0; } diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 19e49d5dad0..59958f50fd1 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -30,9 +30,10 @@ along with GCC; see the file COPYING3. If not see #include "tree-flow.h" #include "timevar.h" #include "tree-dump.h" -#include "tree-ssa-live.h" #include "tree-pass.h" #include "toplev.h" +#include "expr.h" +#include "ssaexpand.h" /* Used to hold all the components required to do SSA PHI elimination. @@ -61,7 +62,7 @@ typedef struct _elim_graph { int size; /* List of nodes in the elimination graph. */ - VEC(tree,heap) *nodes; + VEC(int,heap) *nodes; /* The predecessor and successor edge list. */ VEC(int,heap) *edge_list; @@ -79,85 +80,176 @@ typedef struct _elim_graph { edge e; /* List of constant copies to emit. These are pushed on in pairs. */ + VEC(int,heap) *const_dests; VEC(tree,heap) *const_copies; } *elim_graph; -/* Create a temporary variable based on the type of variable T. Use T's name - as the prefix. */ +/* For an edge E find out a good source location to associate with + instructions inserted on edge E. If E has an implicit goto set, + use its location. Otherwise search instructions in predecessors + of E for a location, and use that one. That makes sense because + we insert on edges for PHI nodes, and effects of PHIs happen on + the end of the predecessor conceptually. */ -static tree -create_temp (tree t) +static void +set_location_for_edge (edge e) { - tree tmp; - const char *name = NULL; - tree type; - - if (TREE_CODE (t) == SSA_NAME) - t = SSA_NAME_VAR (t); - - gcc_assert (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == PARM_DECL); + if (e->goto_locus) + { + set_curr_insn_source_location (e->goto_locus); + set_curr_insn_block (e->goto_block); + } + else + { + basic_block bb = e->src; + gimple_stmt_iterator gsi; - type = TREE_TYPE (t); - tmp = DECL_NAME (t); - if (tmp) - name = IDENTIFIER_POINTER (tmp); + do + { + for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + if (gimple_has_location (stmt) || gimple_block (stmt)) + { + set_curr_insn_source_location (gimple_location (stmt)); + set_curr_insn_block (gimple_block (stmt)); + return; + } + } + /* Nothing found in this basic block. Make a half-assed attempt + to continue with another block. */ + if (single_pred_p (bb)) + bb = single_pred (bb); + else + bb = e->src; + } + while (bb != e->src); + } +} - if (name == NULL) - name = "temp"; - tmp = create_tmp_var (type, name); +/* Insert a copy instruction from partition SRC to DEST onto edge E. */ - if (DECL_DEBUG_EXPR_IS_FROM (t) && DECL_DEBUG_EXPR (t)) +static void +insert_partition_copy_on_edge (edge e, int dest, int src) +{ + rtx seq; + if (dump_file && (dump_flags & TDF_DETAILS)) { - SET_DECL_DEBUG_EXPR (tmp, DECL_DEBUG_EXPR (t)); - DECL_DEBUG_EXPR_IS_FROM (tmp) = 1; + fprintf (dump_file, + "Inserting a partition copy on edge BB%d->BB%d :" + "PART.%d = PART.%d", + e->src->index, + e->dest->index, dest, src); + fprintf (dump_file, "\n"); } - else if (!DECL_IGNORED_P (t)) + + gcc_assert (SA.partition_to_pseudo[dest]); + gcc_assert (SA.partition_to_pseudo[src]); + + set_location_for_edge (e); + + /* Partition copy between same base variables only, so it's the same mode, + hence we can use emit_move_insn. */ + start_sequence (); + emit_move_insn (SA.partition_to_pseudo[dest], SA.partition_to_pseudo[src]); + seq = get_insns (); + end_sequence (); + + insert_insn_on_edge (seq, e); +} + +/* Insert a copy instruction from expression SRC to partition DEST + onto edge E. */ + +static void +insert_value_copy_on_edge (edge e, int dest, tree src) +{ + rtx seq, x; + enum machine_mode mode; + if (dump_file && (dump_flags & TDF_DETAILS)) { - SET_DECL_DEBUG_EXPR (tmp, t); - DECL_DEBUG_EXPR_IS_FROM (tmp) = 1; + fprintf (dump_file, + "Inserting a value copy on edge BB%d->BB%d : PART.%d = ", + e->src->index, + e->dest->index, dest); + print_generic_expr (dump_file, src, TDF_SLIM); + fprintf (dump_file, "\n"); } - DECL_ARTIFICIAL (tmp) = DECL_ARTIFICIAL (t); - DECL_IGNORED_P (tmp) = DECL_IGNORED_P (t); - DECL_GIMPLE_REG_P (tmp) = DECL_GIMPLE_REG_P (t); - add_referenced_var (tmp); - /* We should never have copied variables in non-automatic storage - or variables that have their address taken. So it is pointless - to try to copy call-clobber state here. */ - gcc_assert (!may_be_aliased (t) && !is_global_var (t)); + gcc_assert (SA.partition_to_pseudo[dest]); - return tmp; -} + set_location_for_edge (e); + + start_sequence (); + mode = GET_MODE (SA.partition_to_pseudo[dest]); + x = expand_expr (src, SA.partition_to_pseudo[dest], mode, EXPAND_NORMAL); + if (GET_MODE (x) != mode) + x = convert_to_mode (mode, x, TYPE_UNSIGNED (TREE_TYPE (src))); + if (x != SA.partition_to_pseudo[dest]) + emit_move_insn (SA.partition_to_pseudo[dest], x); + seq = get_insns (); + end_sequence (); + insert_insn_on_edge (seq, e); +} -/* This helper function fill insert a copy from a constant or variable SRC to - variable DEST on edge E. */ +/* Insert a copy instruction from RTL expression SRC to partition DEST + onto edge E. */ static void -insert_copy_on_edge (edge e, tree dest, tree src) +insert_rtx_to_part_on_edge (edge e, int dest, rtx src) { - gimple copy; + rtx seq; + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, + "Inserting a temp copy on edge BB%d->BB%d : PART.%d = ", + e->src->index, + e->dest->index, dest); + print_simple_rtl (dump_file, src); + fprintf (dump_file, "\n"); + } - copy = gimple_build_assign (dest, src); - set_is_used (dest); + gcc_assert (SA.partition_to_pseudo[dest]); + set_location_for_edge (e); - if (TREE_CODE (src) == ADDR_EXPR) - src = TREE_OPERAND (src, 0); - if (TREE_CODE (src) == VAR_DECL || TREE_CODE (src) == PARM_DECL) - set_is_used (src); + start_sequence (); + gcc_assert (GET_MODE (src) == GET_MODE (SA.partition_to_pseudo[dest])); + emit_move_insn (SA.partition_to_pseudo[dest], src); + seq = get_insns (); + end_sequence (); + insert_insn_on_edge (seq, e); +} + +/* Insert a copy instruction from partition SRC to RTL lvalue DEST + onto edge E. */ + +static void +insert_part_to_rtx_on_edge (edge e, rtx dest, int src) +{ + rtx seq; if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, - "Inserting a copy on edge BB%d->BB%d :", + "Inserting a temp copy on edge BB%d->BB%d : ", e->src->index, e->dest->index); - print_gimple_stmt (dump_file, copy, 0, dump_flags); - fprintf (dump_file, "\n"); + print_simple_rtl (dump_file, dest); + fprintf (dump_file, "= PART.%d\n", src); } - gsi_insert_on_edge (e, copy); + gcc_assert (SA.partition_to_pseudo[src]); + set_location_for_edge (e); + + start_sequence (); + gcc_assert (GET_MODE (dest) == GET_MODE (SA.partition_to_pseudo[src])); + emit_move_insn (dest, SA.partition_to_pseudo[src]); + seq = get_insns (); + end_sequence (); + + insert_insn_on_edge (seq, e); } @@ -169,7 +261,8 @@ new_elim_graph (int size) { elim_graph g = (elim_graph) xmalloc (sizeof (struct _elim_graph)); - g->nodes = VEC_alloc (tree, heap, 30); + g->nodes = VEC_alloc (int, heap, 30); + g->const_dests = VEC_alloc (int, heap, 20); g->const_copies = VEC_alloc (tree, heap, 20); g->edge_list = VEC_alloc (int, heap, 20); g->stack = VEC_alloc (int, heap, 30); @@ -185,7 +278,7 @@ new_elim_graph (int size) static inline void clear_elim_graph (elim_graph g) { - VEC_truncate (tree, g->nodes, 0); + VEC_truncate (int, g->nodes, 0); VEC_truncate (int, g->edge_list, 0); } @@ -199,7 +292,8 @@ delete_elim_graph (elim_graph g) VEC_free (int, heap, g->stack); VEC_free (int, heap, g->edge_list); VEC_free (tree, heap, g->const_copies); - VEC_free (tree, heap, g->nodes); + VEC_free (int, heap, g->const_dests); + VEC_free (int, heap, g->nodes); free (g); } @@ -209,22 +303,22 @@ delete_elim_graph (elim_graph g) static inline int elim_graph_size (elim_graph g) { - return VEC_length (tree, g->nodes); + return VEC_length (int, g->nodes); } /* Add NODE to graph G, if it doesn't exist already. */ static inline void -elim_graph_add_node (elim_graph g, tree node) +elim_graph_add_node (elim_graph g, int node) { int x; - tree t; + int t; - for (x = 0; VEC_iterate (tree, g->nodes, x, t); x++) + for (x = 0; VEC_iterate (int, g->nodes, x, t); x++) if (t == node) return; - VEC_safe_push (tree, heap, g->nodes, node); + VEC_safe_push (int, heap, g->nodes, node); } @@ -299,7 +393,7 @@ do { \ /* Add T to elimination graph G. */ static inline void -eliminate_name (elim_graph g, tree T) +eliminate_name (elim_graph g, int T) { elim_graph_add_node (g, T); } @@ -309,22 +403,21 @@ eliminate_name (elim_graph g, tree T) G->e. */ static void -eliminate_build (elim_graph g, basic_block B) +eliminate_build (elim_graph g) { - tree T0, Ti; + tree Ti; int p0, pi; gimple_stmt_iterator gsi; clear_elim_graph (g); - for (gsi = gsi_start_phis (B); !gsi_end_p (gsi); gsi_next (&gsi)) + for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple phi = gsi_stmt (gsi); - T0 = var_to_partition_to_var (g->map, gimple_phi_result (phi)); - + p0 = var_to_partition (g->map, gimple_phi_result (phi)); /* Ignore results which are not in partitions. */ - if (T0 == NULL_TREE) + if (p0 == NO_PARTITION) continue; Ti = PHI_ARG_DEF (phi, g->e->dest_idx); @@ -338,18 +431,16 @@ eliminate_build (elim_graph g, basic_block B) { /* Save constant copies until all other copies have been emitted on this edge. */ - VEC_safe_push (tree, heap, g->const_copies, T0); + VEC_safe_push (int, heap, g->const_dests, p0); VEC_safe_push (tree, heap, g->const_copies, Ti); } else { - Ti = var_to_partition_to_var (g->map, Ti); - if (T0 != Ti) + pi = var_to_partition (g->map, Ti); + if (p0 != pi) { - eliminate_name (g, T0); - eliminate_name (g, Ti); - p0 = var_to_partition (g->map, T0); - pi = var_to_partition (g->map, Ti); + eliminate_name (g, p0); + eliminate_name (g, pi); elim_graph_add_edge (g, p0, pi); } } @@ -399,32 +490,46 @@ elim_backward (elim_graph g, int T) if (!TEST_BIT (g->visited, P)) { elim_backward (g, P); - insert_copy_on_edge (g->e, - partition_to_var (g->map, P), - partition_to_var (g->map, T)); + insert_partition_copy_on_edge (g->e, P, T); } }); } +/* Allocate a new pseudo register usable for storing values sitting + in NAME (a decl or SSA name), i.e. with matching mode and attributes. */ + +static rtx +get_temp_reg (tree name) +{ + tree var = TREE_CODE (name) == SSA_NAME ? SSA_NAME_VAR (name) : name; + tree type = TREE_TYPE (var); + int unsignedp = TYPE_UNSIGNED (type); + enum machine_mode reg_mode + = promote_mode (type, DECL_MODE (var), &unsignedp, 0); + rtx x = gen_reg_rtx (reg_mode); + if (POINTER_TYPE_P (type)) + mark_reg_pointer (x, TYPE_ALIGN (TREE_TYPE (TREE_TYPE (var)))); + return x; +} + /* Insert required copies for T in graph G. Check for a strongly connected region, and create a temporary to break the cycle if one is found. */ static void elim_create (elim_graph g, int T) { - tree U; int P, S; if (elim_unvisited_predecessor (g, T)) { - U = create_temp (partition_to_var (g->map, T)); - insert_copy_on_edge (g->e, U, partition_to_var (g->map, T)); + rtx U = get_temp_reg (partition_to_var (g->map, T)); + insert_part_to_rtx_on_edge (g->e, U, T); FOR_EACH_ELIM_GRAPH_PRED (g, T, P, { if (!TEST_BIT (g->visited, P)) { elim_backward (g, P); - insert_copy_on_edge (g->e, partition_to_var (g->map, P), U); + insert_rtx_to_part_on_edge (g->e, P, U); } }); } @@ -434,12 +539,9 @@ elim_create (elim_graph g, int T) if (S != -1) { SET_BIT (g->visited, T); - insert_copy_on_edge (g->e, - partition_to_var (g->map, T), - partition_to_var (g->map, S)); + insert_partition_copy_on_edge (g->e, T, S); } } - } @@ -449,7 +551,6 @@ static void eliminate_phi (edge e, elim_graph g) { int x; - basic_block B = e->dest; gcc_assert (VEC_length (tree, g->const_copies) == 0); @@ -459,20 +560,19 @@ eliminate_phi (edge e, elim_graph g) g->e = e; - eliminate_build (g, B); + eliminate_build (g); if (elim_graph_size (g) != 0) { - tree var; + int part; sbitmap_zero (g->visited); VEC_truncate (int, g->stack, 0); - for (x = 0; VEC_iterate (tree, g->nodes, x, var); x++) + for (x = 0; VEC_iterate (int, g->nodes, x, part); x++) { - int p = var_to_partition (g->map, var); - if (!TEST_BIT (g->visited, p)) - elim_forward (g, p); + if (!TEST_BIT (g->visited, part)) + elim_forward (g, part); } sbitmap_zero (g->visited); @@ -487,121 +587,15 @@ eliminate_phi (edge e, elim_graph g) /* If there are any pending constant copies, issue them now. */ while (VEC_length (tree, g->const_copies) > 0) { - tree src, dest; + int dest; + tree src; src = VEC_pop (tree, g->const_copies); - dest = VEC_pop (tree, g->const_copies); - insert_copy_on_edge (e, dest, src); + dest = VEC_pop (int, g->const_dests); + insert_value_copy_on_edge (e, dest, src); } } -/* Take the ssa-name var_map MAP, and assign real variables to each - partition. */ - -static void -assign_vars (var_map map) -{ - int x, num; - tree var, root; - var_ann_t ann; - - num = num_var_partitions (map); - for (x = 0; x < num; x++) - { - var = partition_to_var (map, x); - if (TREE_CODE (var) != SSA_NAME) - { - ann = var_ann (var); - /* It must already be coalesced. */ - gcc_assert (ann->out_of_ssa_tag == 1); - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "partition %d already has variable ", x); - print_generic_expr (dump_file, var, TDF_SLIM); - fprintf (dump_file, " assigned to it.\n"); - } - } - else - { - root = SSA_NAME_VAR (var); - ann = var_ann (root); - /* If ROOT is already associated, create a new one. */ - if (ann->out_of_ssa_tag) - { - root = create_temp (root); - ann = var_ann (root); - } - /* ROOT has not been coalesced yet, so use it. */ - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Partition %d is assigned to var ", x); - print_generic_stmt (dump_file, root, TDF_SLIM); - } - change_partition_var (map, root, x); - } - } -} - - -/* Replace use operand P with whatever variable it has been rewritten to based - on the partitions in MAP. EXPR is an optional expression vector over SSA - versions which is used to replace P with an expression instead of a variable. - If the stmt is changed, return true. */ - -static inline bool -replace_use_variable (var_map map, use_operand_p p, gimple *expr) -{ - tree new_var; - tree var = USE_FROM_PTR (p); - - /* Check if we are replacing this variable with an expression. */ - if (expr) - { - int version = SSA_NAME_VERSION (var); - if (expr[version]) - { - SET_USE (p, gimple_assign_rhs_to_tree (expr[version])); - return true; - } - } - - new_var = var_to_partition_to_var (map, var); - if (new_var) - { - SET_USE (p, new_var); - set_is_used (new_var); - return true; - } - return false; -} - - -/* Replace def operand DEF_P with whatever variable it has been rewritten to - based on the partitions in MAP. EXPR is an optional expression vector over - SSA versions which is used to replace DEF_P with an expression instead of a - variable. If the stmt is changed, return true. */ - -static inline bool -replace_def_variable (var_map map, def_operand_p def_p, tree *expr) -{ - tree new_var; - tree var = DEF_FROM_PTR (def_p); - - /* Do nothing if we are replacing this variable with an expression. */ - if (expr && expr[SSA_NAME_VERSION (var)]) - return true; - - new_var = var_to_partition_to_var (map, var); - if (new_var) - { - SET_DEF (def_p, new_var); - set_is_used (new_var); - return true; - } - return false; -} - - /* Remove each argument from PHI. If an arg was the last use of an SSA_NAME, check to see if this allows another PHI node to be removed. */ @@ -704,21 +698,16 @@ eliminate_useless_phis (void) variable. */ static void -rewrite_trees (var_map map, gimple *values) +rewrite_trees (var_map map) { - elim_graph g; - basic_block bb; - gimple_stmt_iterator gsi; - edge e; - gimple_seq phi; - bool changed; - #ifdef ENABLE_CHECKING + basic_block bb; /* Search for PHIs where the destination has no partition, but one or more arguments has a partition. This should not happen and can create incorrect code. */ FOR_EACH_BB (bb) { + gimple_stmt_iterator gsi; for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { gimple phi = gsi_stmt (gsi); @@ -744,593 +733,54 @@ rewrite_trees (var_map map, gimple *values) } } #endif - - /* Replace PHI nodes with any required copies. */ - g = new_elim_graph (map->num_partitions); - g->map = map; - FOR_EACH_BB (bb) - { - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ) - { - gimple stmt = gsi_stmt (gsi); - use_operand_p use_p, copy_use_p; - def_operand_p def_p; - bool remove = false, is_copy = false; - int num_uses = 0; - ssa_op_iter iter; - - changed = false; - - if (gimple_assign_copy_p (stmt)) - is_copy = true; - - copy_use_p = NULL_USE_OPERAND_P; - FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) - { - if (replace_use_variable (map, use_p, values)) - changed = true; - copy_use_p = use_p; - num_uses++; - } - - if (num_uses != 1) - is_copy = false; - - def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF); - - if (def_p != NULL) - { - /* Mark this stmt for removal if it is the list of replaceable - expressions. */ - if (values && values[SSA_NAME_VERSION (DEF_FROM_PTR (def_p))]) - remove = true; - else - { - if (replace_def_variable (map, def_p, NULL)) - changed = true; - /* If both SSA_NAMEs coalesce to the same variable, - mark the now redundant copy for removal. */ - if (is_copy) - { - gcc_assert (copy_use_p != NULL_USE_OPERAND_P); - if (DEF_FROM_PTR (def_p) == USE_FROM_PTR (copy_use_p)) - remove = true; - } - } - } - else - FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF) - if (replace_def_variable (map, def_p, NULL)) - changed = true; - - /* Remove any stmts marked for removal. */ - if (remove) - gsi_remove (&gsi, true); - else - { - if (changed) - if (maybe_clean_or_replace_eh_stmt (stmt, stmt)) - gimple_purge_dead_eh_edges (bb); - gsi_next (&gsi); - } - } - - phi = phi_nodes (bb); - if (phi) - { - edge_iterator ei; - FOR_EACH_EDGE (e, ei, bb->preds) - eliminate_phi (e, g); - } - } - - delete_elim_graph (g); -} - -/* These are the local work structures used to determine the best place to - insert the copies that were placed on edges by the SSA->normal pass.. */ -static VEC(edge,heap) *edge_leader; -static VEC(gimple_seq,heap) *stmt_list; -static bitmap leader_has_match = NULL; -static edge leader_match = NULL; - - -/* Pass this function to make_forwarder_block so that all the edges with - matching PENDING_STMT lists to 'curr_stmt_list' get redirected. E is the - edge to test for a match. */ - -static inline bool -same_stmt_list_p (edge e) -{ - return (e->aux == (PTR) leader_match) ? true : false; } +/* Given the out-of-ssa info object SA (with prepared partitions) + eliminate all phi nodes in all basic blocks. Afterwards no + basic block will have phi nodes anymore and there are possibly + some RTL instructions inserted on edges. */ -/* Return TRUE if S1 and S2 are equivalent copies. */ - -static inline bool -identical_copies_p (const_gimple s1, const_gimple s2) -{ -#ifdef ENABLE_CHECKING - gcc_assert (is_gimple_assign (s1)); - gcc_assert (is_gimple_assign (s2)); - gcc_assert (DECL_P (gimple_assign_lhs (s1))); - gcc_assert (DECL_P (gimple_assign_lhs (s2))); -#endif - - if (gimple_assign_lhs (s1) != gimple_assign_lhs (s2)) - return false; - - if (gimple_assign_rhs1 (s1) != gimple_assign_rhs1 (s2)) - return false; - - return true; -} - - -/* Compare the PENDING_STMT list for edges E1 and E2. Return true if the lists - contain the same sequence of copies. */ - -static inline bool -identical_stmt_lists_p (const_edge e1, const_edge e2) -{ - gimple_seq t1 = PENDING_STMT (e1); - gimple_seq t2 = PENDING_STMT (e2); - gimple_stmt_iterator gsi1, gsi2; - - for (gsi1 = gsi_start (t1), gsi2 = gsi_start (t2); - !gsi_end_p (gsi1) && !gsi_end_p (gsi2); - gsi_next (&gsi1), gsi_next (&gsi2)) - { - if (!identical_copies_p (gsi_stmt (gsi1), gsi_stmt (gsi2))) - break; - } - - if (!gsi_end_p (gsi1) || !gsi_end_p (gsi2)) - return false; - - return true; -} - - -/* Allocate data structures used in analyze_edges_for_bb. */ - -static void -init_analyze_edges_for_bb (void) -{ - edge_leader = VEC_alloc (edge, heap, 25); - stmt_list = VEC_alloc (gimple_seq, heap, 25); - leader_has_match = BITMAP_ALLOC (NULL); -} - - -/* Free data structures used in analyze_edges_for_bb. */ - -static void -fini_analyze_edges_for_bb (void) -{ - VEC_free (edge, heap, edge_leader); - VEC_free (gimple_seq, heap, stmt_list); - BITMAP_FREE (leader_has_match); -} - -/* A helper function to be called via walk_tree. Return DATA if it is - contained in subtree TP. */ - -static tree -contains_tree_r (tree * tp, int *walk_subtrees, void *data) -{ - if (*tp == data) - { - *walk_subtrees = 0; - return (tree) data; - } - else - return NULL_TREE; -} - -/* A threshold for the number of insns contained in the latch block. - It is used to prevent blowing the loop with too many copies from - the latch. */ -#define MAX_STMTS_IN_LATCH 2 - -/* Return TRUE if the stmts on SINGLE-EDGE can be moved to the - body of the loop. This should be permitted only if SINGLE-EDGE is a - single-basic-block latch edge and thus cleaning the latch will help - to create a single-basic-block loop. Otherwise return FALSE. */ - -static bool -process_single_block_loop_latch (edge single_edge) -{ - gimple_seq stmts; - basic_block b_exit, b_pheader, b_loop = single_edge->src; - edge_iterator ei; - edge e; - gimple_stmt_iterator gsi, gsi_exit; - gimple_stmt_iterator tsi; - tree expr; - gimple stmt; - unsigned int count = 0; - - if (single_edge == NULL || (single_edge->dest != single_edge->src) - || (EDGE_COUNT (b_loop->succs) != 2) - || (EDGE_COUNT (b_loop->preds) != 2)) - return false; - - /* Get the stmts on the latch edge. */ - stmts = PENDING_STMT (single_edge); - - /* Find the successor edge which is not the latch edge. */ - FOR_EACH_EDGE (e, ei, b_loop->succs) - if (e->dest != b_loop) - break; - - b_exit = e->dest; - - /* Check that the exit block has only the loop as a predecessor, - and that there are no pending stmts on that edge as well. */ - if (EDGE_COUNT (b_exit->preds) != 1 || PENDING_STMT (e)) - return false; - - /* Find the predecessor edge which is not the latch edge. */ - FOR_EACH_EDGE (e, ei, b_loop->preds) - if (e->src != b_loop) - break; - - b_pheader = e->src; - - if (b_exit == b_pheader || b_exit == b_loop || b_pheader == b_loop) - return false; - - gsi_exit = gsi_after_labels (b_exit); - - /* Get the last stmt in the loop body. */ - gsi = gsi_last_bb (single_edge->src); - stmt = gsi_stmt (gsi); - - if (gimple_code (stmt) != GIMPLE_COND) - return false; - - - expr = build2 (gimple_cond_code (stmt), boolean_type_node, - gimple_cond_lhs (stmt), gimple_cond_rhs (stmt)); - /* Iterate over the insns on the latch and count them. */ - for (tsi = gsi_start (stmts); !gsi_end_p (tsi); gsi_next (&tsi)) - { - gimple stmt1 = gsi_stmt (tsi); - tree var; - - count++; - /* Check that the condition does not contain any new definition - created in the latch as the stmts from the latch intended - to precede it. */ - if (gimple_code (stmt1) != GIMPLE_ASSIGN) - return false; - var = gimple_assign_lhs (stmt1); - if (TREE_THIS_VOLATILE (var) - || TYPE_VOLATILE (TREE_TYPE (var)) - || walk_tree (&expr, contains_tree_r, var, NULL)) - return false; - } - /* Check that the latch does not contain more than MAX_STMTS_IN_LATCH - insns. The purpose of this restriction is to prevent blowing the - loop with too many copies from the latch. */ - if (count > MAX_STMTS_IN_LATCH) - return false; - - /* Apply the transformation - clean up the latch block: - - var = something; - L1: - x1 = expr; - if (cond) goto L2 else goto L3; - L2: - var = x1; - goto L1 - L3: - ... - - ==> - - var = something; - L1: - x1 = expr; - tmp_var = var; - var = x1; - if (cond) goto L1 else goto L2; - L2: - var = tmp_var; - ... - */ - for (tsi = gsi_start (stmts); !gsi_end_p (tsi); gsi_next (&tsi)) - { - gimple stmt1 = gsi_stmt (tsi); - tree var, tmp_var; - gimple copy; - - /* Create a new variable to load back the value of var in case - we exit the loop. */ - var = gimple_assign_lhs (stmt1); - tmp_var = create_temp (var); - copy = gimple_build_assign (tmp_var, var); - set_is_used (tmp_var); - gsi_insert_before (&gsi, copy, GSI_SAME_STMT); - copy = gimple_build_assign (var, tmp_var); - gsi_insert_before (&gsi_exit, copy, GSI_SAME_STMT); - } - - PENDING_STMT (single_edge) = 0; - /* Insert the new stmts to the loop body. */ - gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); - - if (dump_file) - fprintf (dump_file, - "\nCleaned-up latch block of loop with single BB: %d\n\n", - single_edge->dest->index); - - return true; -} - -/* Look at all the incoming edges to block BB, and decide where the best place - to insert the stmts on each edge are, and perform those insertions. */ - -static void -analyze_edges_for_bb (basic_block bb) -{ - edge e; - edge_iterator ei; - int count; - unsigned int x; - bool have_opportunity; - gimple_stmt_iterator gsi; - gimple stmt; - edge single_edge = NULL; - bool is_label; - edge leader; - - count = 0; - - /* Blocks which contain at least one abnormal edge cannot use - make_forwarder_block. Look for these blocks, and commit any PENDING_STMTs - found on edges in these block. */ - have_opportunity = true; - FOR_EACH_EDGE (e, ei, bb->preds) - if (e->flags & EDGE_ABNORMAL) - { - have_opportunity = false; - break; - } - - if (!have_opportunity) - { - FOR_EACH_EDGE (e, ei, bb->preds) - if (PENDING_STMT (e)) - gsi_commit_one_edge_insert (e, NULL); - return; - } - - /* Find out how many edges there are with interesting pending stmts on them. - Commit the stmts on edges we are not interested in. */ - FOR_EACH_EDGE (e, ei, bb->preds) - { - if (PENDING_STMT (e)) - { - gcc_assert (!(e->flags & EDGE_ABNORMAL)); - if (e->flags & EDGE_FALLTHRU) - { - gsi = gsi_start_bb (e->src); - if (!gsi_end_p (gsi)) - { - stmt = gsi_stmt (gsi); - gsi_next (&gsi); - gcc_assert (stmt != NULL); - is_label = (gimple_code (stmt) == GIMPLE_LABEL); - /* Punt if it has non-label stmts, or isn't local. */ - if (!is_label - || DECL_NONLOCAL (gimple_label_label (stmt)) - || !gsi_end_p (gsi)) - { - gsi_commit_one_edge_insert (e, NULL); - continue; - } - } - } - single_edge = e; - count++; - } - } - - /* If there aren't at least 2 edges, no sharing will happen. */ - if (count < 2) - { - if (single_edge) - { - /* Add stmts to the edge unless processed specially as a - single-block loop latch edge. */ - if (!process_single_block_loop_latch (single_edge)) - gsi_commit_one_edge_insert (single_edge, NULL); - } - return; - } - - /* Ensure that we have empty worklists. */ -#ifdef ENABLE_CHECKING - gcc_assert (VEC_length (edge, edge_leader) == 0); - gcc_assert (VEC_length (gimple_seq, stmt_list) == 0); - gcc_assert (bitmap_empty_p (leader_has_match)); -#endif - - /* Find the "leader" block for each set of unique stmt lists. Preference is - given to FALLTHRU blocks since they would need a GOTO to arrive at another - block. The leader edge destination is the block which all the other edges - with the same stmt list will be redirected to. */ - have_opportunity = false; - FOR_EACH_EDGE (e, ei, bb->preds) - { - if (PENDING_STMT (e)) - { - bool found = false; - - /* Look for the same stmt list in edge leaders list. */ - for (x = 0; VEC_iterate (edge, edge_leader, x, leader); x++) - { - if (identical_stmt_lists_p (leader, e)) - { - /* Give this edge the same stmt list pointer. */ - PENDING_STMT (e) = NULL; - e->aux = leader; - bitmap_set_bit (leader_has_match, x); - have_opportunity = found = true; - break; - } - } - - /* If no similar stmt list, add this edge to the leader list. */ - if (!found) - { - VEC_safe_push (edge, heap, edge_leader, e); - VEC_safe_push (gimple_seq, heap, stmt_list, PENDING_STMT (e)); - } - } - } - - /* If there are no similar lists, just issue the stmts. */ - if (!have_opportunity) - { - for (x = 0; VEC_iterate (edge, edge_leader, x, leader); x++) - gsi_commit_one_edge_insert (leader, NULL); - VEC_truncate (edge, edge_leader, 0); - VEC_truncate (gimple_seq, stmt_list, 0); - bitmap_clear (leader_has_match); - return; - } - - if (dump_file) - fprintf (dump_file, "\nOpportunities in BB %d for stmt/block reduction:\n", - bb->index); - - /* For each common list, create a forwarding block and issue the stmt's - in that block. */ - for (x = 0; VEC_iterate (edge, edge_leader, x, leader); x++) - if (bitmap_bit_p (leader_has_match, x)) - { - edge new_edge; - gimple_stmt_iterator gsi; - gimple_seq curr_stmt_list; - - leader_match = leader; - - /* The tree_* cfg manipulation routines use the PENDING_EDGE field - for various PHI manipulations, so it gets cleared when calls are - made to make_forwarder_block(). So make sure the edge is clear, - and use the saved stmt list. */ - PENDING_STMT (leader) = NULL; - leader->aux = leader; - curr_stmt_list = VEC_index (gimple_seq, stmt_list, x); - - new_edge = make_forwarder_block (leader->dest, same_stmt_list_p, - NULL); - bb = new_edge->dest; - if (dump_file) - { - fprintf (dump_file, "Splitting BB %d for Common stmt list. ", - leader->dest->index); - fprintf (dump_file, "Original block is now BB%d.\n", bb->index); - print_gimple_seq (dump_file, curr_stmt_list, 0, TDF_VOPS); - } - - FOR_EACH_EDGE (e, ei, new_edge->src->preds) - { - e->aux = NULL; - if (dump_file) - fprintf (dump_file, " Edge (%d->%d) lands here.\n", - e->src->index, e->dest->index); - } - - gsi = gsi_last_bb (leader->dest); - gsi_insert_seq_after (&gsi, curr_stmt_list, GSI_NEW_STMT); - - leader_match = NULL; - /* We should never get a new block now. */ - } - else - { - PENDING_STMT (leader) = VEC_index (gimple_seq, stmt_list, x); - gsi_commit_one_edge_insert (leader, NULL); - } - - - /* Clear the working data structures. */ - VEC_truncate (edge, edge_leader, 0); - VEC_truncate (gimple_seq, stmt_list, 0); - bitmap_clear (leader_has_match); -} - - -/* This function will analyze the insertions which were performed on edges, - and decide whether they should be left on that edge, or whether it is more - efficient to emit some subset of them in a single block. All stmts are - inserted somewhere. */ - -static void -perform_edge_inserts (void) +void +expand_phi_nodes (struct ssaexpand *sa) { basic_block bb; + elim_graph g = new_elim_graph (sa->map->num_partitions); + g->map = sa->map; - if (dump_file) - fprintf(dump_file, "Analyzing Edge Insertions.\n"); - - /* analyze_edges_for_bb calls make_forwarder_block, which tries to - incrementally update the dominator information. Since we don't - need dominator information after this pass, go ahead and free the - dominator information. */ - free_dominance_info (CDI_DOMINATORS); - free_dominance_info (CDI_POST_DOMINATORS); - - /* Allocate data structures used in analyze_edges_for_bb. */ - init_analyze_edges_for_bb (); - - FOR_EACH_BB (bb) - analyze_edges_for_bb (bb); - - analyze_edges_for_bb (EXIT_BLOCK_PTR); - - /* Free data structures used in analyze_edges_for_bb. */ - fini_analyze_edges_for_bb (); - -#ifdef ENABLE_CHECKING - { - edge_iterator ei; - edge e; - FOR_EACH_BB (bb) + FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR->next_bb, EXIT_BLOCK_PTR, next_bb) + if (!gimple_seq_empty_p (phi_nodes (bb))) { + edge e; + edge_iterator ei; FOR_EACH_EDGE (e, ei, bb->preds) + eliminate_phi (e, g); + set_phi_nodes (bb, NULL); + /* We can't redirect EH edges in RTL land, so we need to do this + here. Redirection happens only when splitting is necessary, + which it is only for critical edges, normally. For EH edges + it might also be necessary when the successor has more than + one predecessor. In that case the edge is either required to + be fallthru (which EH edges aren't), or the predecessor needs + to end with a jump (which again, isn't the case with EH edges). + Hence, split all EH edges on which we inserted instructions + and whose successor has multiple predecessors. */ + for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); ) { - if (PENDING_STMT (e)) - error (" Pending stmts not issued on PRED edge (%d, %d)\n", - e->src->index, e->dest->index); + if (e->insns.r && (e->flags & EDGE_EH) + && !single_pred_p (e->dest)) + { + rtx insns = e->insns.r; + basic_block bb; + e->insns.r = NULL_RTX; + bb = split_edge (e); + single_pred_edge (bb)->insns.r = insns; + } + else + ei_next (&ei); } - FOR_EACH_EDGE (e, ei, bb->succs) - { - if (PENDING_STMT (e)) - error (" Pending stmts not issued on SUCC edge (%d, %d)\n", - e->src->index, e->dest->index); - } - } - FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs) - { - if (PENDING_STMT (e)) - error (" Pending stmts not issued on ENTRY edge (%d, %d)\n", - e->src->index, e->dest->index); - } - FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) - { - if (PENDING_STMT (e)) - error (" Pending stmts not issued on EXIT edge (%d, %d)\n", - e->src->index, e->dest->index); } - } -#endif + + delete_elim_graph (g); } @@ -1339,12 +789,11 @@ perform_edge_inserts (void) should also be used. */ static void -remove_ssa_form (bool perform_ter) +remove_ssa_form (bool perform_ter, struct ssaexpand *sa) { - basic_block bb; gimple *values = NULL; var_map map; - gimple_stmt_iterator gsi; + unsigned i; map = coalesce_ssa_name (); @@ -1365,29 +814,21 @@ remove_ssa_form (bool perform_ter) dump_replaceable_exprs (dump_file, values); } - /* Assign real variables to the partitions now. */ - assign_vars (map); + rewrite_trees (map); - if (dump_file && (dump_flags & TDF_DETAILS)) + sa->map = map; + sa->values = values; + sa->partition_has_default_def = BITMAP_ALLOC (NULL); + for (i = 1; i < num_ssa_names; i++) { - fprintf (dump_file, "After Base variable replacement:\n"); - dump_var_map (dump_file, map); + tree t = ssa_name (i); + if (t && SSA_NAME_IS_DEFAULT_DEF (t)) + { + int p = var_to_partition (map, t); + if (p != NO_PARTITION) + bitmap_set_bit (sa->partition_has_default_def, p); + } } - - rewrite_trees (map, values); - - if (values) - free (values); - - /* Remove PHI nodes which have been translated back to real variables. */ - FOR_EACH_BB (bb) - for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi);) - remove_phi_node (&gsi, true); - - /* If any copies were inserted on edges, analyze and insert them now. */ - perform_edge_inserts (); - - delete_var_map (map); } @@ -1477,12 +918,26 @@ insert_backedge_copies (void) } } +/* Free all memory associated with going out of SSA form. SA is + the outof-SSA info object. */ + +void +finish_out_of_ssa (struct ssaexpand *sa) +{ + free (sa->partition_to_pseudo); + if (sa->values) + free (sa->values); + delete_var_map (sa->map); + BITMAP_FREE (sa->partition_has_default_def); + memset (sa, 0, sizeof *sa); +} + /* Take the current function out of SSA form, translating PHIs as described in R. Morgan, ``Building an Optimizing Compiler'', Butterworth-Heinemann, Boston, MA, 1998. pp 176-186. */ -static unsigned int -rewrite_out_of_ssa (void) +unsigned int +rewrite_out_of_ssa (struct ssaexpand *sa) { /* If elimination of a PHI requires inserting a copy on a backedge, then we will have to split the backedge which has numerous @@ -1499,37 +954,10 @@ rewrite_out_of_ssa (void) if (dump_file && (dump_flags & TDF_DETAILS)) gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS); - remove_ssa_form (flag_tree_ter && !flag_mudflap); + remove_ssa_form (flag_tree_ter, sa); if (dump_file && (dump_flags & TDF_DETAILS)) gimple_dump_cfg (dump_file, dump_flags & ~TDF_DETAILS); - cfun->gimple_df->in_ssa_p = false; return 0; } - - -/* Define the parameters of the out of SSA pass. */ - -struct gimple_opt_pass pass_del_ssa = -{ - { - GIMPLE_PASS, - "optimized", /* name */ - NULL, /* gate */ - rewrite_out_of_ssa, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - TV_TREE_SSA_TO_NORMAL, /* tv_id */ - PROP_cfg | PROP_ssa, /* properties_required */ - 0, /* properties_provided */ - /* ??? If TER is enabled, we also kill gimple. */ - PROP_ssa, /* properties_destroyed */ - TODO_verify_ssa | TODO_verify_flow - | TODO_verify_stmts, /* todo_flags_start */ - TODO_dump_func - | TODO_ggc_collect - | TODO_remove_unused_locals /* todo_flags_finish */ - } -}; diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c index 9f7bafda46d..ab18bcad4b1 100644 --- a/gcc/tree-ssa-coalesce.c +++ b/gcc/tree-ssa-coalesce.c @@ -314,7 +314,7 @@ compare_pairs (const void *p1, const void *p2) const_coalesce_pair_p const *const pp2 = (const_coalesce_pair_p const *) p2; int result; - result = (* pp2)->cost - (* pp1)->cost; + result = (* pp1)->cost - (* pp2)->cost; /* Since qsort does not guarantee stability we use the elements as a secondary key. This provides us with independence from the host's implementation of the sorting algorithm. */ @@ -1126,8 +1126,8 @@ create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy) first = NULL_TREE; for (i = 1; i < num_ssa_names; i++) { - var = map->partition_to_var[i]; - if (var != NULL_TREE) + var = ssa_name (i); + if (var != NULL_TREE && is_gimple_reg (var)) { /* Add coalesces between all the result decls. */ if (TREE_CODE (SSA_NAME_VAR (var)) == RESULT_DECL) @@ -1148,7 +1148,8 @@ create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy) /* Mark any default_def variables as being in the coalesce list since they will have to be coalesced with the base variable. If not marked as present, they won't be in the coalesce view. */ - if (gimple_default_def (cfun, SSA_NAME_VAR (var)) == var) + if (gimple_default_def (cfun, SSA_NAME_VAR (var)) == var + && !has_zero_uses (var)) bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (var)); } } @@ -1329,7 +1330,6 @@ eq_ssa_name_by_var (const void *p1, const void *p2) extern var_map coalesce_ssa_name (void) { - unsigned num, x; tree_live_info_p liveinfo; ssa_conflicts_p graph; coalesce_list_p cl; @@ -1406,31 +1406,6 @@ coalesce_ssa_name (void) /* First, coalesce all live on entry variables to their base variable. This will ensure the first use is coming from the correct location. */ - num = num_var_partitions (map); - for (x = 0 ; x < num; x++) - { - tree var = partition_to_var (map, x); - tree root; - - if (TREE_CODE (var) != SSA_NAME) - continue; - - root = SSA_NAME_VAR (var); - if (gimple_default_def (cfun, root) == var) - { - /* This root variable should have not already been assigned - to another partition which is not coalesced with this one. */ - gcc_assert (!var_ann (root)->out_of_ssa_tag); - - if (dump_file && (dump_flags & TDF_DETAILS)) - { - print_exprs (dump_file, "Must coalesce ", var, - " with the root variable ", root, ".\n"); - } - change_partition_var (map, root, x); - } - } - if (dump_file && (dump_flags & TDF_DETAILS)) dump_var_map (dump_file, map); diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c index 38cd5493592..0ac02bab04c 100644 --- a/gcc/tree-ssa-copyrename.c +++ b/gcc/tree-ssa-copyrename.c @@ -344,7 +344,7 @@ rename_ssa_copies (void) part_var = partition_to_var (map, x); if (!part_var) continue; - var = map->partition_to_var[x]; + var = ssa_name (x); if (debug) { if (SSA_NAME_VAR (var) != SSA_NAME_VAR (part_var)) diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index 5f3b9d86cc5..0673fab851f 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -136,9 +136,6 @@ init_var_map (int size) map = (var_map) xmalloc (sizeof (struct _var_map)); map->var_partition = partition_new (size); - map->partition_to_var - = (tree *)xmalloc (size * sizeof (tree)); - memset (map->partition_to_var, 0, size * sizeof (tree)); map->partition_to_view = NULL; map->view_to_partition = NULL; @@ -157,7 +154,6 @@ void delete_var_map (var_map map) { var_map_base_fini (map); - free (map->partition_to_var); partition_delete (map->var_partition); if (map->partition_to_view) free (map->partition_to_view); @@ -175,41 +171,16 @@ int var_union (var_map map, tree var1, tree var2) { int p1, p2, p3; - tree root_var = NULL_TREE; - tree other_var = NULL_TREE; + + gcc_assert (TREE_CODE (var1) == SSA_NAME); + gcc_assert (TREE_CODE (var2) == SSA_NAME); /* This is independent of partition_to_view. If partition_to_view is on, then whichever one of these partitions is absorbed will never have a dereference into the partition_to_view array any more. */ - if (TREE_CODE (var1) == SSA_NAME) - p1 = partition_find (map->var_partition, SSA_NAME_VERSION (var1)); - else - { - p1 = var_to_partition (map, var1); - if (map->view_to_partition) - p1 = map->view_to_partition[p1]; - root_var = var1; - } - - if (TREE_CODE (var2) == SSA_NAME) - p2 = partition_find (map->var_partition, SSA_NAME_VERSION (var2)); - else - { - p2 = var_to_partition (map, var2); - if (map->view_to_partition) - p2 = map->view_to_partition[p2]; - - /* If there is no root_var set, or it's not a user variable, set the - root_var to this one. */ - if (!root_var || (DECL_P (root_var) && DECL_IGNORED_P (root_var))) - { - other_var = root_var; - root_var = var2; - } - else - other_var = var2; - } + p1 = partition_find (map->var_partition, SSA_NAME_VERSION (var1)); + p2 = partition_find (map->var_partition, SSA_NAME_VERSION (var2)); gcc_assert (p1 != NO_PARTITION); gcc_assert (p2 != NO_PARTITION); @@ -222,11 +193,6 @@ var_union (var_map map, tree var1, tree var2) if (map->partition_to_view) p3 = map->partition_to_view[p3]; - if (root_var) - change_partition_var (map, root_var, p3); - if (other_var) - change_partition_var (map, other_var, p3); - return p3; } @@ -278,7 +244,9 @@ partition_view_init (var_map map) for (x = 0; x < map->partition_size; x++) { tmp = partition_find (map->var_partition, x); - if (map->partition_to_var[tmp] != NULL_TREE && !bitmap_bit_p (used, tmp)) + if (ssa_name (tmp) != NULL_TREE && is_gimple_reg (ssa_name (tmp)) + && (!has_zero_uses (ssa_name (tmp)) + || !SSA_NAME_IS_DEFAULT_DEF (ssa_name (tmp)))) bitmap_set_bit (used, tmp); } @@ -297,7 +265,6 @@ partition_view_fini (var_map map, bitmap selected) { bitmap_iterator bi; unsigned count, i, x, limit; - tree var; gcc_assert (selected); @@ -317,11 +284,6 @@ partition_view_fini (var_map map, bitmap selected) { map->partition_to_view[x] = i; map->view_to_partition[i] = x; - var = map->partition_to_var[x]; - /* If any one of the members of a partition is not an SSA_NAME, make - sure it is the representative. */ - if (TREE_CODE (var) != SSA_NAME) - change_partition_var (map, var, i); i++; } gcc_assert (i == count); @@ -379,25 +341,6 @@ partition_view_bitmap (var_map map, bitmap only, bool want_bases) } -/* This function is used to change the representative variable in MAP for VAR's - partition to a regular non-ssa variable. This allows partitions to be - mapped back to real variables. */ - -void -change_partition_var (var_map map, tree var, int part) -{ - var_ann_t ann; - - gcc_assert (TREE_CODE (var) != SSA_NAME); - - ann = var_ann (var); - ann->out_of_ssa_tag = 1; - VAR_ANN_PARTITION (ann) = part; - if (map->view_to_partition) - map->partition_to_var[map->view_to_partition[part]] = var; -} - - static inline void mark_all_vars_used (tree *, void *data); /* Helper function for mark_all_vars_used, called via walk_tree. */ @@ -1105,7 +1048,7 @@ dump_var_map (FILE *f, var_map map) else p = x; - if (map->partition_to_var[p] == NULL_TREE) + if (ssa_name (p) == NULL_TREE) continue; t = 0; diff --git a/gcc/tree-ssa-live.h b/gcc/tree-ssa-live.h index de4726245f8..8cab755d9b8 100644 --- a/gcc/tree-ssa-live.h +++ b/gcc/tree-ssa-live.h @@ -60,9 +60,6 @@ typedef struct _var_map int *partition_to_view; int *view_to_partition; - /* Mapping of partition numbers to variables. */ - tree *partition_to_var; - /* Current number of partitions in var_map based on the current view. */ unsigned int num_partitions; @@ -80,8 +77,6 @@ typedef struct _var_map } *var_map; -/* Partition number of a non ssa-name variable. */ -#define VAR_ANN_PARTITION(ann) (ann->partition) /* Index to the basevar table of a non ssa-name variable. */ #define VAR_ANN_BASE_INDEX(ann) (ann->base_index) @@ -93,7 +88,6 @@ extern var_map init_var_map (int); extern void delete_var_map (var_map); extern void dump_var_map (FILE *, var_map); extern int var_union (var_map, tree, tree); -extern void change_partition_var (var_map, tree, int); extern void partition_view_normal (var_map, bool); extern void partition_view_bitmap (var_map, bitmap, bool); #ifdef ENABLE_CHECKING @@ -116,10 +110,12 @@ num_var_partitions (var_map map) static inline tree partition_to_var (var_map map, int i) { + tree name; if (map->view_to_partition) i = map->view_to_partition[i]; i = partition_find (map->var_partition, i); - return map->partition_to_var[i]; + name = ssa_name (i); + return name; } @@ -146,23 +142,12 @@ version_to_var (var_map map, int version) static inline int var_to_partition (var_map map, tree var) { - var_ann_t ann; int part; - if (TREE_CODE (var) == SSA_NAME) - { - part = partition_find (map->var_partition, SSA_NAME_VERSION (var)); - if (map->partition_to_view) - part = map->partition_to_view[part]; - } - else - { - ann = var_ann (var); - if (ann && ann->out_of_ssa_tag) - part = VAR_ANN_PARTITION (ann); - else - part = NO_PARTITION; - } + gcc_assert (TREE_CODE (var) == SSA_NAME); + part = partition_find (map->var_partition, SSA_NAME_VERSION (var)); + if (map->partition_to_view) + part = map->partition_to_view[part]; return part; } @@ -207,17 +192,11 @@ num_basevars (var_map map) partitions may be filtered out by a view later. */ static inline void -register_ssa_partition (var_map map, tree ssa_var) +register_ssa_partition (var_map map ATTRIBUTE_UNUSED, tree ssa_var) { - int version; - #if defined ENABLE_CHECKING register_ssa_partition_check (ssa_var); #endif - - version = SSA_NAME_VERSION (ssa_var); - if (map->partition_to_var[version] == NULL_TREE) - map->partition_to_var[version] = ssa_var; } diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index ca00e04f784..ddf52022b54 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -844,7 +844,8 @@ delete_tree_ssa (void) gimple_set_modified (stmt, true); } - set_phi_nodes (bb, NULL); + if (!(bb->flags & BB_RTL)) + set_phi_nodes (bb, NULL); } /* Remove annotations from every referenced local variable. */ -- 2.11.0