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:
Michael Matz 2009-04-26 19:35:04 +00:00 committed by Michael Matz
parent 5846213b87
commit 4e3825dba9
104 changed files with 1164 additions and 1292 deletions

View File

@ -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

View File

@ -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) \

View File

@ -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))

View File

@ -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);

View File

@ -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. */

View File

@ -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 */
}
};

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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
View 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

View File

@ -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

View File

@ -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" } }

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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
}

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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 */

View File

@ -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. */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } }

View File

@ -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" } }

View File

@ -16,3 +16,4 @@ PROGRAM main
END PROGRAM
! { dg-final { scan-tree-dump-times "= f\(\)" 0 "optimized" } }
! { dg-final { cleanup-tree-dump "optimized" } }

View File

@ -16,3 +16,4 @@ INTEGER FUNCTION f()
END FUNCTION
! { dg-final { scan-tree-dump-times "= f\(\)" 0 "optimized" } }
! { dg-final { cleanup-tree-dump "optimized" } }

View File

@ -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" } }

View File

@ -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" } }

View File

@ -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" } }

View File

@ -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"

View File

@ -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 */
}
};

View File

@ -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 */

View File

@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@ -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