re PR ipa/63838 (ipa-pure-const miscomputes can_throw)

PR ipa/63838
	* ipa-pure-const.c (propagate_nothrow): Walk w->indirect_calls
	chain instead of node->indirect_calls.  Put !can_throw into
	conditions of all the loops.

	* g++.dg/ipa/pr63838.C: New test.

From-SVN: r217449
This commit is contained in:
Jakub Jelinek 2014-11-13 00:09:15 +01:00 committed by Jakub Jelinek
parent f03cee1186
commit abb5020711
4 changed files with 72 additions and 14 deletions

View File

@ -1,3 +1,10 @@
2014-11-12 Jakub Jelinek <jakub@redhat.com>
PR ipa/63838
* ipa-pure-const.c (propagate_nothrow): Walk w->indirect_calls
chain instead of node->indirect_calls. Put !can_throw into
conditions of all the loops.
2014-11-12 H.J. Lu <hongjiu.lu@intel.com> 2014-11-12 H.J. Lu <hongjiu.lu@intel.com>
* config/i386/i386.c (x86_output_mi_thunk): Use gen_rtx_REG to * config/i386/i386.c (x86_output_mi_thunk): Use gen_rtx_REG to

View File

@ -1448,7 +1448,7 @@ propagate_nothrow (void)
/* Find the worst state for any node in the cycle. */ /* Find the worst state for any node in the cycle. */
w = node; w = node;
while (w) while (w && !can_throw)
{ {
struct cgraph_edge *e, *ie; struct cgraph_edge *e, *ie;
funct_state w_l = get_function_state (w); funct_state w_l = get_function_state (w);
@ -1457,10 +1457,7 @@ propagate_nothrow (void)
|| w->get_availability () == AVAIL_INTERPOSABLE) || w->get_availability () == AVAIL_INTERPOSABLE)
can_throw = true; can_throw = true;
if (can_throw) for (e = w->callees; e && !can_throw; e = e->next_callee)
break;
for (e = w->callees; e; e = e->next_callee)
{ {
enum availability avail; enum availability avail;
struct cgraph_node *y = e->callee->function_symbol (&avail); struct cgraph_node *y = e->callee->function_symbol (&avail);
@ -1469,8 +1466,6 @@ propagate_nothrow (void)
{ {
funct_state y_l = get_function_state (y); funct_state y_l = get_function_state (y);
if (can_throw)
break;
if (y_l->can_throw && !TREE_NOTHROW (w->decl) if (y_l->can_throw && !TREE_NOTHROW (w->decl)
&& e->can_throw_external) && e->can_throw_external)
can_throw = true; can_throw = true;
@ -1478,12 +1473,9 @@ propagate_nothrow (void)
else if (e->can_throw_external && !TREE_NOTHROW (y->decl)) else if (e->can_throw_external && !TREE_NOTHROW (y->decl))
can_throw = true; can_throw = true;
} }
for (ie = node->indirect_calls; ie; ie = ie->next_callee) for (ie = w->indirect_calls; ie && !can_throw; ie = ie->next_callee)
if (ie->can_throw_external) if (ie->can_throw_external)
{ can_throw = true;
can_throw = true;
break;
}
w_info = (struct ipa_dfs_info *) w->aux; w_info = (struct ipa_dfs_info *) w->aux;
w = w_info->next_cycle; w = w_info->next_cycle;
} }
@ -1794,5 +1786,3 @@ make_pass_warn_function_noreturn (gcc::context *ctxt)
{ {
return new pass_warn_function_noreturn (ctxt); return new pass_warn_function_noreturn (ctxt);
} }

View File

@ -1,3 +1,8 @@
2014-11-12 Jakub Jelinek <jakub@redhat.com>
PR ipa/63838
* g++.dg/ipa/pr63838.C: New test.
2014-11-12 Matthew Fortune <matthew.fortune@imgtec.com> 2014-11-12 Matthew Fortune <matthew.fortune@imgtec.com>
* gcc.target/mips/args-1.c: Handle __mips_fpr == 0. * gcc.target/mips/args-1.c: Handle __mips_fpr == 0.

View File

@ -0,0 +1,56 @@
// PR ipa/63838
// { dg-do run }
// { dg-options "-O2 -fdump-ipa-pure-const" }
// { dg-final { scan-ipa-dump-not "Function found to be nothrow: void foo" "pure-const" } }
// { dg-final { scan-ipa-dump-not "Function found to be nothrow: void bar" "pure-const" } }
// { dg-final { cleanup-ipa-dump "pure-const" } }
__attribute__((noinline, noclone)) static void bar (int);
volatile int v;
void (*fn) ();
struct S { S () { v++; } ~S () { v++; } };
__attribute__((noinline, noclone)) static void
foo (int x)
{
v++;
if (x == 5)
bar (x);
}
__attribute__((noinline, noclone)) static void
bar (int x)
{
v++;
if (x == 6)
foo (x);
else if (x == 5)
fn ();
}
__attribute__((noinline, noclone)) int
baz (int x)
{
S s;
foo (x);
}
void
throw0 ()
{
throw 0;
}
int
main ()
{
fn = throw0;
asm volatile ("" : : : "memory");
try
{
baz (5);
}
catch (int)
{
}
}