Commit 7faade0f by Jan Hubicka Committed by Jan Hubicka

re PR tree-optimization/1046 (gcc less efficient than jdk for recursion with -finline-functions)

	PR tree-optimization/1046
	* tree-tailcall.c (suitable_for_tail_call_opt_p): Use TREE_ADDRESSABLE
	when alias info is not ready.
	(pass_tail_recursion): Do not require aliasing.
	* tree-ssa-copyrename.c (pass_rename_ssa_cop): Likewise.
	* tree-ssa-ccp.c (pass_ccp, pass_fold_builtins): Likewise.
	* tree-ssa-copy.c (pass_copy_prop): Likewise.
	* tree-ssa-forwprop.c (pass_forwprop): Likewise.
	* tree-ssa-dce.c (pass_dce, pass_dce_loop, pass_cd_dce): Likewise.
	* passes.c (init_optimization_passes): Execute rename_ssa_copies,
	ccp, forwprop, copy_prop, merge_phi, copy_prop, dce and tail recursion
	before inlining.
	* tree-ssa-operands.c (add_virtual_operand, get_indirect_ref_operand):
	When aliasing is not build, mark statement as volatile.

	* gcc.dg/tree-ssa/tailrecursion-4.c: Update dump file.
	* gcc.dg/tree-ssa/tailrecursion-1.c: Update dump file.
	* gcc.dg/tree-ssa/tailrecursion-2.c: Update dump file.
	* gcc.dg/tree-ssa/tailrecursion-3.c: Update dump file.
	* gcc.dg/tree-ssa/pr21658.c: Likewise.
	* gcc.dg/tree-ssa/pr15349.c: Likewise.
	* gcc.dg/tree-ssa/pr25501.c: Likewise.
	* gcc.dg/tree-ssa/vrp11.c: Make more complex so it still test
	transformation in question.
	* gcc.dg/tree-ssa/vrp05.c: Likewise.
	* gcc.dg/tree-ssa/pr20701.c: Likewise.
	* gcc.dg/always_inline3.c: Likewise.

From-SVN: r120681
parent 18d5e416
2007-01-11 Jan Hubicka <jh@suse.cz>
PR tree-optimization/1046
* tree-tailcall.c (suitable_for_tail_call_opt_p): Use TREE_ADDRESSABLE
when alias info is not ready.
(pass_tail_recursion): Do not require aliasing.
* tree-ssa-copyrename.c (pass_rename_ssa_cop): Likewise.
* tree-ssa-ccp.c (pass_ccp, pass_fold_builtins): Likewise.
* tree-ssa-copy.c (pass_copy_prop): Likewise.
* tree-ssa-forwprop.c (pass_forwprop): Likewise.
* tree-ssa-dce.c (pass_dce, pass_dce_loop, pass_cd_dce): Likewise.
* passes.c (init_optimization_passes): Execute rename_ssa_copies,
ccp, forwprop, copy_prop, merge_phi, copy_prop, dce and tail recursion
before inlining.
* tree-ssa-operands.c (add_virtual_operand, get_indirect_ref_operand):
When aliasing is not build, mark statement as volatile.
2007-01-11 Tom Tromey <tromey@redhat.com> 2007-01-11 Tom Tromey <tromey@redhat.com>
PR preprocessor/15185, PR preprocessor/20989: PR preprocessor/15185, PR preprocessor/20989:
......
...@@ -481,6 +481,15 @@ init_optimization_passes (void) ...@@ -481,6 +481,15 @@ init_optimization_passes (void)
NEXT_PASS (pass_build_ssa); NEXT_PASS (pass_build_ssa);
NEXT_PASS (pass_early_warn_uninitialized); NEXT_PASS (pass_early_warn_uninitialized);
NEXT_PASS (pass_cleanup_cfg); NEXT_PASS (pass_cleanup_cfg);
NEXT_PASS (pass_rename_ssa_copies);
NEXT_PASS (pass_ccp);
NEXT_PASS (pass_forwprop);
NEXT_PASS (pass_copy_prop);
NEXT_PASS (pass_merge_phi);
NEXT_PASS (pass_dce);
NEXT_PASS (pass_tail_recursion);
NEXT_PASS (pass_release_ssa_names);
*p = NULL; *p = NULL;
...@@ -1003,6 +1012,11 @@ execute_ipa_pass_list (struct tree_opt_pass *pass) ...@@ -1003,6 +1012,11 @@ execute_ipa_pass_list (struct tree_opt_pass *pass)
{ {
gcc_assert (!current_function_decl); gcc_assert (!current_function_decl);
gcc_assert (!cfun); gcc_assert (!cfun);
if (!quiet_flag)
{
fprintf (stderr, " <%s>", pass->name ? pass->name : "");
fflush (stderr);
}
if (execute_one_pass (pass) && pass->sub) if (execute_one_pass (pass) && pass->sub)
do_per_function ((void (*)(void *))execute_pass_list, pass->sub); do_per_function ((void (*)(void *))execute_pass_list, pass->sub);
if (!current_function_decl) if (!current_function_decl)
......
...@@ -398,6 +398,7 @@ extern struct tree_opt_pass pass_shorten_branches; ...@@ -398,6 +398,7 @@ extern struct tree_opt_pass pass_shorten_branches;
extern struct tree_opt_pass pass_set_nothrow_function_flags; extern struct tree_opt_pass pass_set_nothrow_function_flags;
extern struct tree_opt_pass pass_final; extern struct tree_opt_pass pass_final;
extern struct tree_opt_pass pass_rtl_seqabstr; extern struct tree_opt_pass pass_rtl_seqabstr;
extern struct tree_opt_pass pass_release_ssa_names;
/* The root of the compilation pass tree, once constructed. */ /* The root of the compilation pass tree, once constructed. */
extern struct tree_opt_pass *all_passes, *all_ipa_passes, *all_lowering_passes; extern struct tree_opt_pass *all_passes, *all_ipa_passes, *all_lowering_passes;
......
...@@ -1431,7 +1431,7 @@ struct tree_opt_pass pass_ccp = ...@@ -1431,7 +1431,7 @@ struct tree_opt_pass pass_ccp =
NULL, /* next */ NULL, /* next */
0, /* static_pass_number */ 0, /* static_pass_number */
TV_TREE_CCP, /* tv_id */ TV_TREE_CCP, /* tv_id */
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */ PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
...@@ -2650,7 +2650,7 @@ struct tree_opt_pass pass_fold_builtins = ...@@ -2650,7 +2650,7 @@ struct tree_opt_pass pass_fold_builtins =
NULL, /* next */ NULL, /* next */
0, /* static_pass_number */ 0, /* static_pass_number */
0, /* tv_id */ 0, /* tv_id */
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */ PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
......
...@@ -1137,7 +1137,7 @@ struct tree_opt_pass pass_copy_prop = ...@@ -1137,7 +1137,7 @@ struct tree_opt_pass pass_copy_prop =
NULL, /* next */ NULL, /* next */
0, /* static_pass_number */ 0, /* static_pass_number */
TV_TREE_COPY_PROP, /* tv_id */ TV_TREE_COPY_PROP, /* tv_id */
PROP_ssa | PROP_alias | PROP_cfg, /* properties_required */ PROP_ssa | PROP_cfg, /* properties_required */
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
......
...@@ -394,7 +394,7 @@ struct tree_opt_pass pass_rename_ssa_copies = ...@@ -394,7 +394,7 @@ struct tree_opt_pass pass_rename_ssa_copies =
NULL, /* next */ NULL, /* next */
0, /* static_pass_number */ 0, /* static_pass_number */
TV_TREE_COPY_RENAME, /* tv_id */ TV_TREE_COPY_RENAME, /* tv_id */
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */ PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
......
...@@ -859,7 +859,7 @@ struct tree_opt_pass pass_dce = ...@@ -859,7 +859,7 @@ struct tree_opt_pass pass_dce =
NULL, /* next */ NULL, /* next */
0, /* static_pass_number */ 0, /* static_pass_number */
TV_TREE_DCE, /* tv_id */ TV_TREE_DCE, /* tv_id */
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */ PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
...@@ -881,7 +881,7 @@ struct tree_opt_pass pass_dce_loop = ...@@ -881,7 +881,7 @@ struct tree_opt_pass pass_dce_loop =
NULL, /* next */ NULL, /* next */
0, /* static_pass_number */ 0, /* static_pass_number */
TV_TREE_DCE, /* tv_id */ TV_TREE_DCE, /* tv_id */
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */ PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
...@@ -901,7 +901,7 @@ struct tree_opt_pass pass_cd_dce = ...@@ -901,7 +901,7 @@ struct tree_opt_pass pass_cd_dce =
NULL, /* next */ NULL, /* next */
0, /* static_pass_number */ 0, /* static_pass_number */
TV_TREE_CD_DCE, /* tv_id */ TV_TREE_CD_DCE, /* tv_id */
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */ PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
......
...@@ -1060,8 +1060,7 @@ struct tree_opt_pass pass_forwprop = { ...@@ -1060,8 +1060,7 @@ struct tree_opt_pass pass_forwprop = {
NULL, /* next */ NULL, /* next */
0, /* static_pass_number */ 0, /* static_pass_number */
TV_TREE_FORWPROP, /* tv_id */ TV_TREE_FORWPROP, /* tv_id */
PROP_cfg | PROP_ssa PROP_cfg | PROP_ssa, /* properties_required */
| PROP_alias, /* properties_required */
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
......
...@@ -1480,6 +1480,8 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags, ...@@ -1480,6 +1480,8 @@ add_virtual_operand (tree var, stmt_ann_t s_ann, int flags,
aliases = v_ann->may_aliases; aliases = v_ann->may_aliases;
if (aliases == NULL) if (aliases == NULL)
{ {
if (s_ann && !gimple_aliases_computed_p (cfun))
s_ann->has_volatile_ops = true;
/* The variable is not aliased or it is an alias tag. */ /* The variable is not aliased or it is an alias tag. */
if (flags & opf_def) if (flags & opf_def)
append_vdef (var); append_vdef (var);
...@@ -1610,6 +1612,8 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags, ...@@ -1610,6 +1612,8 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags,
stmt_ann_t s_ann = stmt_ann (stmt); stmt_ann_t s_ann = stmt_ann (stmt);
s_ann->references_memory = true; s_ann->references_memory = true;
if (s_ann && TREE_THIS_VOLATILE (expr))
s_ann->has_volatile_ops = true;
if (SSA_VAR_P (ptr)) if (SSA_VAR_P (ptr))
{ {
...@@ -1652,6 +1656,11 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags, ...@@ -1652,6 +1656,11 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags,
if (v_ann->symbol_mem_tag) if (v_ann->symbol_mem_tag)
add_virtual_operand (v_ann->symbol_mem_tag, s_ann, flags, add_virtual_operand (v_ann->symbol_mem_tag, s_ann, flags,
full_ref, offset, size, false); full_ref, offset, size, false);
/* Aliasing information is missing; mark statement as volatile so we
won't optimize it out too actively. */
else if (s_ann && !gimple_aliases_computed_p (cfun)
&& (flags & opf_def))
s_ann->has_volatile_ops = true;
} }
} }
else if (TREE_CODE (ptr) == INTEGER_CST) else if (TREE_CODE (ptr) == INTEGER_CST)
......
...@@ -26,6 +26,7 @@ Boston, MA 02110-1301, USA. */ ...@@ -26,6 +26,7 @@ Boston, MA 02110-1301, USA. */
#include "varray.h" #include "varray.h"
#include "ggc.h" #include "ggc.h"
#include "tree-flow.h" #include "tree-flow.h"
#include "tree-pass.h"
/* Rewriting a function into SSA form can create a huge number of SSA_NAMEs, /* Rewriting a function into SSA form can create a huge number of SSA_NAMEs,
many of which may be thrown away shortly after their creation if jumps many of which may be thrown away shortly after their creation if jumps
...@@ -304,3 +305,48 @@ replace_ssa_name_symbol (tree ssa_name, tree sym) ...@@ -304,3 +305,48 @@ replace_ssa_name_symbol (tree ssa_name, tree sym)
SSA_NAME_VAR (ssa_name) = sym; SSA_NAME_VAR (ssa_name) = sym;
TREE_TYPE (ssa_name) = TREE_TYPE (sym); TREE_TYPE (ssa_name) = TREE_TYPE (sym);
} }
/* Return SSA names that are unused to GGC memory. This is used to keep
footprint of compiler during interprocedural optimization.
As a side effect the SSA_NAME_VERSION number reuse is reduced
so this function should not be used too often. */
static unsigned int
release_dead_ssa_names (void)
{
tree t, next;
int n = 0;
referenced_var_iterator rvi;
/* Current defs point to various dead SSA names that in turn points to dead
statements so bunch of dead memory is holded from releasing. */
FOR_EACH_REFERENCED_VAR (t, rvi)
set_current_def (t, NULL);
/* Now release the freelist. */
for (t = FREE_SSANAMES (cfun); t; t = next)
{
next = TREE_CHAIN (t);
ggc_free (t);
n++;
}
FREE_SSANAMES (cfun) = NULL;
if (dump_file)
fprintf (dump_file, "Released %i names, %.2f%%\n", n, n * 100.0 / num_ssa_names);
return 0;
}
struct tree_opt_pass pass_release_ssa_names =
{
"release_ssa", /* name */
NULL, /* gate */
release_dead_ssa_names, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
0, /* tv_id */
PROP_ssa, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0, /* todo_flags_finish */
0 /* letter */
};
...@@ -143,10 +143,10 @@ suitable_for_tail_opt_p (void) ...@@ -143,10 +143,10 @@ suitable_for_tail_opt_p (void)
FOR_EACH_REFERENCED_VAR (var, rvi) FOR_EACH_REFERENCED_VAR (var, rvi)
{ {
if (!is_global_var (var) if (!is_global_var (var)
&& (!MTAG_P (var) || TREE_CODE (var) == STRUCT_FIELD_TAG) && (!MTAG_P (var) || TREE_CODE (var) == STRUCT_FIELD_TAG)
&& is_call_clobbered (var)) && (gimple_aliases_computed_p (cfun) ? is_call_clobbered (var)
: TREE_ADDRESSABLE (var)))
return false; return false;
} }
...@@ -1023,7 +1023,7 @@ struct tree_opt_pass pass_tail_recursion = ...@@ -1023,7 +1023,7 @@ struct tree_opt_pass pass_tail_recursion =
NULL, /* next */ NULL, /* next */
0, /* static_pass_number */ 0, /* static_pass_number */
0, /* tv_id */ 0, /* tv_id */
PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */ PROP_cfg | PROP_ssa, /* properties_required */
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment