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:
parent
617f389789
commit
33977f8162
@ -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
28
gcc/passes.c
28
gcc/passes.c
@ -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"
|
||||
|
@ -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.
|
||||
|
@ -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 ();
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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" } } */
|
||||
|
@ -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). */
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user