attr-noinline.c: Avoid pure-const optimization.

* gcc.dg/attr-noinline.c: Avoid pure-const optimization.
	* gcc.dg/pr33826.c: Update dump files.
	* gcc.dg/ipa/ipa-3.c: Avoid pure-const optimization.
	* gcc.dg/ipa/ipa-5.c: Avoid pure-const optimization.

	Merge from pretty-ipa:

	2009-03-27  Jan Hubicka  <jh@suse.cz>
	* cgraph.c (dump_cgraph_node): Add replace output flag by process.
	* tree-pass.h (function_called_by_processed_nodes_p): Declare.
	* passes.c (function_called_by_processed_nodes_p): New.
	* ipa-pure-const.c (check_call): Fix handling of operands.
	(analyze_function): Dump debug output for skipped bodies.
	(local_pure_const): Use function_called_by_processed_nodes_p.
	* dwarf2out.c (reference_to_unused): Use output.
	* passes.c (do_per_function_toporder): Likewise.

	2008-11-12  Jan Hubicka  <jh@suse.cz>

	* tree-pass.h (pass_fixup_cfg, pass_local_pure_const): Declare.
	* ipa-pure-const.c (funct_state_d): Add can throw field; make
	state_set_in_source enum
	(check_decl): Ignore memory tags; do not set fake looping flags;
	dump diagnostics.
	(check_operand, check_tree, check_rhs_var, check_lhs_var,
	get_asm_expr_operands, scan_function_op, scan_function_stmt): Remove.
	(check_call, analyze_function): Rewrite.
	(check_stmt): New.
	(add_new_function): Update call of analyze_function.
	(generate_summary): Add call of analyze_function.
	(propagate): Propagate can_throw; handle state_set_in_source correctly.
	(local_pure_const): New function.
	(pass_local_pure_const): New pass.
	* ipa-inline.c (inline_transform): Set after_inlining.
	* tree-eh.c (stmt_can_throw_external): New.
	* tree-optimize.c (execute_fixup_cfg): Do not set after_inlining;
	work with aliasing built.
	* tree-flow.h (stmt_can_throw_external): New.
	* passes.c (init_optimization_passes): Schedule fixup_cfg pass early;
	and local pure/const pass in early and late optimization queue.

From-SVN: r145204
This commit is contained in:
Jan Hubicka 2009-03-28 20:29:35 +01:00 committed by Jan Hubicka
parent 617f389789
commit 33977f8162
12 changed files with 589 additions and 454 deletions

View File

@ -1,3 +1,40 @@
2009-03-28 Jan Hubicka <jh@suse.cz>
Merge from pretty-ipa:
2009-03-27 Jan Hubicka <jh@suse.cz>
* cgraph.c (dump_cgraph_node): Add replace output flag by process.
* tree-pass.h (function_called_by_processed_nodes_p): Declare.
* passes.c (function_called_by_processed_nodes_p): New.
* ipa-pure-const.c (check_call): Fix handling of operands.
(analyze_function): Dump debug output for skipped bodies.
(local_pure_const): Use function_called_by_processed_nodes_p.
* dwarf2out.c (reference_to_unused): Use output.
* passes.c (do_per_function_toporder): Likewise.
2008-11-12 Jan Hubicka <jh@suse.cz>
* tree-pass.h (pass_fixup_cfg, pass_local_pure_const): Declare.
* ipa-pure-const.c (funct_state_d): Add can throw field; make
state_set_in_source enum
(check_decl): Ignore memory tags; do not set fake looping flags;
dump diagnostics.
(check_operand, check_tree, check_rhs_var, check_lhs_var,
get_asm_expr_operands, scan_function_op, scan_function_stmt): Remove.
(check_call, analyze_function): Rewrite.
(check_stmt): New.
(add_new_function): Update call of analyze_function.
(generate_summary): Add call of analyze_function.
(propagate): Propagate can_throw; handle state_set_in_source correctly.
(local_pure_const): New function.
(pass_local_pure_const): New pass.
* ipa-inline.c (inline_transform): Set after_inlining.
* tree-eh.c (stmt_can_throw_external): New.
* tree-optimize.c (execute_fixup_cfg): Do not set after_inlining;
work with aliasing built.
* tree-flow.h (stmt_can_throw_external): New.
* passes.c (init_optimization_passes): Schedule fixup_cfg pass early;
and local pure/const pass in early and late optimization queue.
2009-03-28 Martin Jambor <mjambor@suse.cz>
* fold-const.c (get_pointer_modulus_and_residue): New parameter

File diff suppressed because it is too large Load Diff

View File

@ -563,6 +563,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_tail_recursion);
NEXT_PASS (pass_convert_switch);
NEXT_PASS (pass_profile);
NEXT_PASS (pass_local_pure_const);
}
NEXT_PASS (pass_release_ssa_names);
NEXT_PASS (pass_rebuild_cgraph_edges);
@ -702,6 +703,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_tail_calls);
NEXT_PASS (pass_rename_ssa_copies);
NEXT_PASS (pass_uncprop);
NEXT_PASS (pass_local_pure_const);
}
NEXT_PASS (pass_del_ssa);
NEXT_PASS (pass_nrv);
@ -1373,4 +1375,30 @@ execute_ipa_pass_list (struct opt_pass *pass)
while (pass);
}
/* Called by local passes to see if function is called by already processed nodes.
Because we process nodes in topological order, this means that function is
in recursive cycle or we introduced new direct calls. */
bool
function_called_by_processed_nodes_p (void)
{
struct cgraph_edge *e;
for (e = cgraph_node (current_function_decl)->callers; e; e = e->next_caller)
{
if (e->caller->decl == current_function_decl)
continue;
if (!e->caller->analyzed || (!e->caller->needed && !e->caller->reachable))
continue;
if (TREE_ASM_WRITTEN (e->caller->decl))
continue;
if (!e->caller->process && !e->caller->global.inlined_to)
break;
}
if (dump_file && e)
{
fprintf (dump_file, "Already processed call to:\n");
dump_cgraph_node (dump_file, e->caller);
}
return e != NULL;
}
#include "gt-passes.h"

View File

@ -1,3 +1,10 @@
2009-03-28 Jan Hubicka <jh@suse.cz>
* gcc.dg/attr-noinline.c: Avoid pure-const optimization.
* gcc.dg/pr33826.c: Update dump files.
* gcc.dg/ipa/ipa-3.c: Avoid pure-const optimization.
* gcc.dg/ipa/ipa-5.c: Avoid pure-const optimization.
2009-03-28 Martin Jambor <mjambor@suse.cz>
* g++.dg/tree-ssa/fwprop-align.C: New test.

View File

@ -1,39 +1,41 @@
/* { dg-do compile } */
/* { dg-options "-O2 -finline-functions" } */
static inline void __attribute__((__noinline__)) function_definition(void) {} /* { dg-warning "inline function \[^\n\]* given attribute noinline" "" } */
extern int t();
static inline void __attribute__((__noinline__)) function_definition(void) {t();} /* { dg-warning "inline function \[^\n\]* given attribute noinline" "" } */
static inline void __attribute__((__noinline__)) function_declaration_both_before(void); /* { dg-warning "inline function \[^\n\]* given attribute noinline" "" } */
static void function_declaration_both_before(void) {}
static void function_declaration_both_before(void) {t();}
static void function_declaration_both_after(void);
static inline void __attribute__((__noinline__)) function_declaration_both_after(void); /* { dg-warning "(inline function \[^\n\]* given attribute noinline|declared inline after its definition)" "" } */
static void function_declaration_both_after(void) {}
static void function_declaration_both_after(void) {t();}
static void function_declaration_noinline_before(void) __attribute__((__noinline__)); /* { dg-message "note: previous declaration" "" } */
static inline void function_declaration_noinline_before(void) {} /* { dg-warning "follows declaration with attribute noinline" "" } */
static inline void function_declaration_noinline_before(void) {t();} /* { dg-warning "follows declaration with attribute noinline" "" } */
static inline void function_declaration_noinline_after(void) {} /* { dg-message "note: previous definition" "" } */
static inline void function_declaration_noinline_after(void) {t();} /* { dg-message "note: previous definition" "" } */
static void function_declaration_noinline_after(void) __attribute__((__noinline__)); /* { dg-warning "follows inline declaration" "" } */
static inline void function_declaration_inline_before(void); /* { dg-message "note: previous declaration" "" } */
static void __attribute__((__noinline__)) function_declaration_inline_before(void) {} /* { dg-warning "follows inline declaration" "" } */
static void __attribute__((__noinline__)) function_declaration_inline_before(void) {t();} /* { dg-warning "follows inline declaration" "" } */
static inline void function_declaration_inline_noinline_before(void); /* { dg-message "note: previous declaration" "" } */
static void function_declaration_inline_noinline_before(void) __attribute__((__noinline__)); /* { dg-warning "follows inline declaration" "" } */
static void function_declaration_inline_noinline_before(void) {}
static void function_declaration_inline_noinline_before(void) {t();}
static inline void function_declaration_inline_noinline_after(void);
static void function_declaration_inline_noinline_after(void) {} /* { dg-message "note: previous definition" "" } */
static void function_declaration_inline_noinline_after(void) {t();} /* { dg-message "note: previous definition" "" } */
static void function_declaration_inline_noinline_after(void) __attribute__((__noinline__)); /* { dg-warning "follows inline declaration" "" } */
@ -41,7 +43,7 @@ static void function_declaration_noinline_inline_before(void) __attribute__((__n
static inline void function_declaration_noinline_inline_before(void); /* { dg-warning "follows declaration with attribute noinline" "" } */
static void function_declaration_noinline_inline_before(void) {}
static void function_declaration_noinline_inline_before(void) {t();}
void f () {
function_definition ();

View File

@ -6,8 +6,10 @@
/* Double constants. */
#include <stdio.h>
void t(void);
int g (double b, double c)
{
t();
return (int)(b+c);
}
int f (double a)

View File

@ -5,12 +5,15 @@
/* Float & short constants. */
#include <stdio.h>
void t(void);
int g (float b, short c)
{
t();
return c + (int)b;
}
int f (float a)
{
t();
/* a is modified. */
if (a++ > 0)
g (a, 3);

View File

@ -3,7 +3,7 @@
/* { dg-do compile } */
/* { dg-require-effective-target nonpic } */
/* { dg-options "-O1 -fdump-ipa-pure-const" } */
/* { dg-options "-O1 -fdump-tree-local-pure-const1 -fdump-ipa-pure-const" } */
int recurese1 (int i)
{
@ -30,8 +30,14 @@ int norecurse1b (int i)
return i+1;
}
/* { dg-final { scan-ipa-dump "found to be const: norecurse1a" "pure-const" } } */
/* { dg-final { scan-ipa-dump "found to be const: norecurse1b" "pure-const" } } */
/* { dg-final { scan-tree-dump "found to be const: norecurse1a" "local-pure-const1" } } */
/* { dg-final { scan-tree-dump "found to be const: norecurse1b" "local-pure-const1" } } */
/* { dg-final { scan-tree-dump-not "found to be pure: recurse1" "local-pure-const1" } } */
/* { dg-final { scan-tree-dump-not "found to be pure: recurse2a" "local-pure-const1" } } */
/* { dg-final { scan-tree-dump-not "found to be pure: recurse2b" "local-pure-const1" } } */
/* { dg-final { scan-tree-dump-not "found to be const: recurse1" "local-pure-const1" } } */
/* { dg-final { scan-tree-dump-not "found to be const: recurse2a" "local-pure-const1" } } */
/* { dg-final { scan-tree-dump-not "found to be const: recurse2b" "local-pure-const1" } } */
/* { dg-final { scan-ipa-dump-not "found to be pure: recurse1" "pure-const" } } */
/* { dg-final { scan-ipa-dump-not "found to be pure: recurse2a" "pure-const" } } */
/* { dg-final { scan-ipa-dump-not "found to be pure: recurse2b" "pure-const" } } */
@ -39,3 +45,4 @@ int norecurse1b (int i)
/* { dg-final { scan-ipa-dump-not "found to be const: recurse2a" "pure-const" } } */
/* { dg-final { scan-ipa-dump-not "found to be const: recurse2b" "pure-const" } } */
/* { dg-final { cleanup-ipa-dump "pure-const" } } */
/* { dg-final { cleanup-tree-dump "local-pure-const1" } } */

View File

@ -2402,6 +2402,32 @@ tree_could_throw_p (tree t)
return false;
}
/* Return true if STMT can throw an exception that is not caught within
the current function (CFUN). */
bool
stmt_can_throw_external (gimple stmt)
{
int region_nr;
bool is_resx = false;
bool inlinable_call = false;
if (!stmt_could_throw_p (stmt))
return false;
if (gimple_code (stmt) == GIMPLE_RESX)
{
region_nr = gimple_resx_region (stmt);
is_resx = true;
}
else
region_nr = lookup_stmt_eh_region (stmt);
if (region_nr < 0)
return true;
return can_throw_external_1 (region_nr, is_resx, inlinable_call);
}
/* Return true if STMT can throw an exception that is caught within
the current function (CFUN). */

View File

@ -1077,6 +1077,7 @@ extern bool operation_could_trap_p (enum tree_code, bool, bool, tree);
extern bool stmt_could_throw_p (gimple);
extern bool tree_could_throw_p (tree);
extern bool stmt_can_throw_internal (gimple);
extern bool stmt_can_throw_external (gimple);
extern void add_stmt_to_eh_region (gimple, int);
extern bool remove_stmt_from_eh_region (gimple);
extern bool maybe_clean_or_replace_eh_stmt (gimple, gimple);

View File

@ -311,6 +311,7 @@ execute_fixup_cfg (void)
if (gimple_in_ssa_p (cfun))
{
todo |= TODO_update_ssa | TODO_cleanup_cfg;
mark_symbols_for_renaming (stmt);
update_stmt (stmt);
}
}

View File

@ -389,6 +389,7 @@ extern struct gimple_opt_pass pass_reassoc;
extern struct gimple_opt_pass pass_rebuild_cgraph_edges;
extern struct gimple_opt_pass pass_build_cgraph_edges;
extern struct gimple_opt_pass pass_reset_cc_flags;
extern struct gimple_opt_pass pass_local_pure_const;
/* IPA Passes */
extern struct ipa_opt_pass pass_ipa_inline;
@ -524,6 +525,7 @@ extern void execute_pass_list (struct opt_pass *);
extern void execute_ipa_pass_list (struct opt_pass *);
extern void print_current_pass (FILE *);
extern void debug_pass (void);
extern bool function_called_by_processed_nodes_p (void);
/* Set to true if the pass is called the first time during compilation of the
current function. Note that using this information in the optimization