mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-22 13:39:35 +08:00
Expand from SSA.
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. From-SVN: r146817
This commit is contained in:
parent
5846213b87
commit
4e3825dba9
123
gcc/ChangeLog
123
gcc/ChangeLog
@ -1,3 +1,126 @@
|
||||
2009-04-26 Michael Matz <matz@suse.de>
|
||||
|
||||
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 <matz@suse.de>
|
||||
|
||||
* tree-ssa-copyrename.c (rename_ssa_copies): Don't iterate
|
||||
|
@ -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) \
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
|
@ -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. */
|
||||
|
314
gcc/cfgexpand.c
314
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);
|
||||
x = gen_rtx_MEM (DECL_MODE (SSAVAR (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;
|
||||
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;
|
||||
|
||||
set_mem_attributes (x, decl, true);
|
||||
SET_DECL_RTL (decl, x);
|
||||
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 */
|
||||
}
|
||||
};
|
||||
|
86
gcc/cfgrtl.c
86
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;
|
||||
return false;
|
||||
|
||||
/* 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 (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;
|
||||
|
@ -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,
|
||||
|
26
gcc/expr.c
26
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);
|
||||
|
||||
|
10
gcc/passes.c
10
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;
|
||||
|
@ -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);
|
||||
|
||||
|
80
gcc/ssaexpand.h
Normal file
80
gcc/ssaexpand.h
Normal file
@ -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
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
|
||||
#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
|
@ -1,3 +1,89 @@
|
||||
2009-04-26 Michael Matz <matz@suse.de>
|
||||
|
||||
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 <kargl@gcc.gnu.org>
|
||||
|
||||
PR fortran/39893
|
||||
|
@ -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<float, 3> *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" } }
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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" } } */
|
||||
|
@ -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 <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
@ -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" } } */
|
||||
|
||||
|
@ -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 <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
@ -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" } } */
|
||||
|
||||
|
@ -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 <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
@ -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" } } */
|
||||
|
||||
|
@ -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 <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
@ -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" } } */
|
||||
|
||||
|
@ -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 <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
@ -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" } } */
|
||||
|
||||
|
||||
|
@ -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 <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
@ -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" } } */
|
||||
|
||||
|
@ -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 <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
@ -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" } } */
|
||||
|
||||
|
@ -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 <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
@ -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" } } */
|
||||
|
@ -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 <stdlib.h>
|
||||
|
||||
@ -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" } } */
|
||||
|
||||
|
@ -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 <stdlib.h>
|
||||
|
||||
@ -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" } } */
|
||||
|
@ -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 <stdlib.h>
|
||||
|
||||
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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 "<bb N>"; confirm that, so that we know to count
|
||||
it in the real test. */
|
||||
/* { dg-final { scan-tree-dump-times "<bb\[^>\]*>" 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 "<bb\[^>\]*>" 1 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times ">|<" 3 "optimized" } } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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 "<bb N>"; confirm that, so that we know to count
|
||||
it in the real test. */
|
||||
/* { dg-final { scan-tree-dump-times "<bb\[^>\]*>" 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 "<bb\[^>\]*>" 1 "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump-times ">|<" 2 "optimized" } } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
||||
|
@ -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" } } */
|
||||
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
||||
|
@ -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" } } */
|
||||
|
||||
|
@ -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" } } */
|
||||
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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 <i1_\[^,\]*, j1_\[^>\]*>" "optimized" } } */
|
||||
/* { dg-final { scan-tree-dump "return i1_.;" "optimized" } } */
|
||||
/* { dg-final { cleanup-tree-dump "optimized" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
||||
|
||||
|
@ -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" } } */
|
||||
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } } */
|
||||
|
@ -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" } }
|
||||
|
@ -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" } }
|
||||
|
@ -16,3 +16,4 @@ PROGRAM main
|
||||
END PROGRAM
|
||||
|
||||
! { dg-final { scan-tree-dump-times "= f\(\)" 0 "optimized" } }
|
||||
! { dg-final { cleanup-tree-dump "optimized" } }
|
||||
|
@ -16,3 +16,4 @@ INTEGER FUNCTION f()
|
||||
END FUNCTION
|
||||
|
||||
! { dg-final { scan-tree-dump-times "= f\(\)" 0 "optimized" } }
|
||||
! { dg-final { cleanup-tree-dump "optimized" } }
|
||||
|
@ -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" } }
|
||||
|
@ -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" } }
|
||||
|
@ -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" } }
|
||||
|
@ -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"
|
||||
|
@ -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) <base address expression>. */
|
||||
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 */
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
1130
gcc/tree-outof-ssa.c
1130
gcc/tree-outof-ssa.c
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user