Commit f10ea640 by Jan Hubicka Committed by Jan Hubicka

cgraph.c (cgraph_edge_cannot_lead_to_return): Also check if caller is noreturn.

	* cgraph.c (cgraph_edge_cannot_lead_to_return): Also check
	if caller is noreturn.
	* ipa-reference.c (analyze_function): Use ipa_ref_cannot_lead_to_return
	* ipa-ref.h (ipa_ref_cannot_lead_to_return): New function.
	* ipa-ref.c (ipa_ref_cannot_lead_to_return): New function.
	* ipa-pure-const.c (check_decl): Add IPA parameter.
	(state_from_flags): New function.
	(better_state, worse_state): New functions.
	(check_call): When in IPA mode, do not care about callees.
	(check_load, check_store): Update.
	(check_ipa_load, check_ipa_store): New.
	(check_stmt): When in IPA mode, use IPA checkers.
	(analyze_function): Use state_from_flags.
	(propagate): Check indirect edges and references.

From-SVN: r160380
parent dba16b83
2010-06-07 Jan Hubicka <jh@suse.cz>
* cgraph.c (cgraph_edge_cannot_lead_to_return): Also check
if caller is noreturn.
* ipa-reference.c (analyze_function): Use ipa_ref_cannot_lead_to_return
* ipa-ref.h (ipa_ref_cannot_lead_to_return): New function.
* ipa-ref.c (ipa_ref_cannot_lead_to_return): New function.
* ipa-pure-const.c (check_decl): Add IPA parameter.
(state_from_flags): New function.
(better_state, worse_state): New functions.
(check_call): When in IPA mode, do not care about callees.
(check_load, check_store): Update.
(check_ipa_load, check_ipa_store): New.
(check_stmt): When in IPA mode, use IPA checkers.
(analyze_function): Use state_from_flags.
(propagate): Check indirect edges and references.
2010-06-07 Kazu Hirata <kazu@codesourcery.com> 2010-06-07 Kazu Hirata <kazu@codesourcery.com>
PR rtl-optimization/44404 PR rtl-optimization/44404
......
...@@ -2606,6 +2606,8 @@ cgraph_node_cannot_return (struct cgraph_node *node) ...@@ -2606,6 +2606,8 @@ cgraph_node_cannot_return (struct cgraph_node *node)
bool bool
cgraph_edge_cannot_lead_to_return (struct cgraph_edge *e) cgraph_edge_cannot_lead_to_return (struct cgraph_edge *e)
{ {
if (cgraph_node_cannot_return (e->caller))
return true;
if (e->indirect_unknown_callee) if (e->indirect_unknown_callee)
{ {
int flags = e->indirect_info->ecf_flags; int flags = e->indirect_info->ecf_flags;
......
...@@ -233,3 +233,11 @@ ipa_clone_refering (struct cgraph_node *dest_node, ...@@ -233,3 +233,11 @@ ipa_clone_refering (struct cgraph_node *dest_node,
dest_node, dest_varpool_node, dest_node, dest_varpool_node,
ref->use, ref->stmt); ref->use, ref->stmt);
} }
/* Return true when execution of REF can load to return from
function. */
bool
ipa_ref_cannot_lead_to_return (struct ipa_ref *ref)
{
return cgraph_node_cannot_return (ipa_ref_refering_node (ref));
}
...@@ -88,4 +88,5 @@ void ipa_dump_references (FILE *, struct ipa_ref_list *); ...@@ -88,4 +88,5 @@ void ipa_dump_references (FILE *, struct ipa_ref_list *);
void ipa_dump_refering (FILE *, struct ipa_ref_list *); void ipa_dump_refering (FILE *, struct ipa_ref_list *);
void ipa_clone_references (struct cgraph_node *, struct varpool_node *, struct ipa_ref_list *); void ipa_clone_references (struct cgraph_node *, struct varpool_node *, struct ipa_ref_list *);
void ipa_clone_refering (struct cgraph_node *, struct varpool_node *, struct ipa_ref_list *); void ipa_clone_refering (struct cgraph_node *, struct varpool_node *, struct ipa_ref_list *);
bool ipa_ref_cannot_lead_to_return (struct ipa_ref *);
...@@ -439,6 +439,8 @@ analyze_function (struct cgraph_node *fn) ...@@ -439,6 +439,8 @@ analyze_function (struct cgraph_node *fn)
bitmap_set_bit (local->statics_read, DECL_UID (var)); bitmap_set_bit (local->statics_read, DECL_UID (var));
break; break;
case IPA_REF_STORE: case IPA_REF_STORE:
if (ipa_ref_cannot_lead_to_return (ref))
break;
bitmap_set_bit (local->statics_written, DECL_UID (var)); bitmap_set_bit (local->statics_written, DECL_UID (var));
break; break;
case IPA_REF_ADDR: case IPA_REF_ADDR:
......
...@@ -512,8 +512,9 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file) ...@@ -512,8 +512,9 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
FIXME: This can not be done in between gimplify and omp_expand since FIXME: This can not be done in between gimplify and omp_expand since
readonly flag plays role on what is shared and what is not. Currently we do readonly flag plays role on what is shared and what is not. Currently we do
this transformation as part of ipa-reference pass, but it would make sense this transformation as part of whole program visibility and re-do at
to do it before early optimizations. */ ipa-reference pass (to take into account clonning), but it would
make sense to do it before early optimizations. */
void void
ipa_discover_readonly_nonaddressable_vars (void) ipa_discover_readonly_nonaddressable_vars (void)
...@@ -825,6 +826,8 @@ whole_program_function_and_variable_visibility (void) ...@@ -825,6 +826,8 @@ whole_program_function_and_variable_visibility (void)
fprintf (dump_file, " %s", varpool_node_name (vnode)); fprintf (dump_file, " %s", varpool_node_name (vnode));
fprintf (dump_file, "\n\n"); fprintf (dump_file, "\n\n");
} }
if (optimize)
ipa_discover_readonly_nonaddressable_vars ();
return 0; return 0;
} }
......
2010-06-07 Jan Hubicka <jh@suse.cz>
* gcc.dg/ipa/pure-const-1.c: New testcase.
2010-06-07 Kazu Hirata <kazu@codesourcery.com> 2010-06-07 Kazu Hirata <kazu@codesourcery.com>
PR rtl-optimization/44404 PR rtl-optimization/44404
......
/* { dg-do compile } */
/* { dg-options "-O3 -fdump-tree-local-pure-const1 -fdump-ipa-pure-const -fdump-tree-optimized -fno-early-inlining" } */
void abort (void);
int error_code;
static int val;
__attribute__ ((noinline, noclone))
static int
i_am_pure1 (int a)
{
if (a > 50)
abort ();
return a;
}
__attribute__ ((noinline, noclone))
static int
i_am_const2 (int a)
{
return a+val;
}
__attribute__ ((noinline, noclone))
int
call_me(int a)
{
return a;
}
inline int
call_callback(int (*fn)(int), int a)
{
return fn(a);
}
__attribute__ ((noinline, noclone))
i_am_const3(int a)
{
return call_callback (call_me, a);
}
__attribute__ ((noinline))
explode_badly()
{
error_code = 0xbad;
abort ();
}
__attribute__ ((noinline, noclone))
i_am_pure4(int a)
{
if (a > 50)
explode_badly ();
return a;
}
test()
{
int s;
s = i_am_pure1(5);
s += i_am_pure1(5);
s += i_am_const2(5);
s += i_am_const2(5);
s += i_am_const3(5);
s += i_am_const3(5);
s += i_am_pure4(5);
s += i_am_pure4(5);
return s;
}
/* { dg-final { scan-tree-dump-times "i_am_pure1 .5" 1 "optimized"} } */
/* { dg-final { scan-tree-dump-times "i_am_const2 .5" 1 "optimized"} } */
/* { dg-final { scan-tree-dump-times "i_am_const3 .5" 1 "optimized"} } */
/* { dg-final { scan-tree-dump-times "i_am_pure4 .5" 1 "optimized"} } */
/* { dg-final { scan-tree-dump "found to be looping pure: i_am_pure1" "local-pure-const1"} } */
/* { dg-final { scan-tree-dump "found to be looping pure: i_am_pure4" "local-pure-const1"} } */
/* { dg-final { scan-ipa-dump "found to be const: i_am_const2" "pure-const"} } */
/* { dg-final { scan-ipa-dump "found to be const: i_am_const3" "pure-const"} } */
/* { dg-final { cleanup-tree-dump "local-pure-const1" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-final { cleanup-ipa-dump "pure-const" } } */
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