From 1b64239d7044be7846e2fa8d43dca998e5ca4357 Mon Sep 17 00:00:00 2001 From: ebotcazou Date: Wed, 17 Sep 2003 07:11:01 +0000 Subject: [PATCH] PR optimization/11646 * cfgrtl.c (purge_dead_edges) [JUMP_INSN]: Rematerialize the EDGE_ABNORMAL flag for EH edges. * toplev.c (rest_of_handle_cse): Delete unreachable blocks if dead edges were purged. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@71455 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++ gcc/cfgrtl.c | 8 ++++-- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/g++.dg/opt/cfg3.C | 61 +++++++++++++++++++++++++++++++++++++++++ gcc/toplev.c | 3 +- 5 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/opt/cfg3.C diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9062d99..aa323e2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2003-09-17 Eric Botcazou + + PR optimization/11646 + * cfgrtl.c (purge_dead_edges) [JUMP_INSN]: Rematerialize the + EDGE_ABNORMAL flag for EH edges. + * toplev.c (rest_of_handle_cse): Delete unreachable blocks + if dead edges were purged. + 2003-09-16 Bernardo Innocenti * config/m68k/m68k.h (TARGET_CPU_CPP_BUILTINS): Add target predefines. diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 7441cd9..f383438 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -2255,8 +2255,12 @@ purge_dead_edges (basic_block bb) continue; else if ((e->flags & EDGE_EH) && can_throw_internal (insn)) /* Keep the edges that correspond to exceptions thrown by - this instruction. */ - continue; + this instruction and rematerialize the EDGE_ABNORMAL + flag we just cleared above. */ + { + e->flags |= EDGE_ABNORMAL; + continue; + } /* We do not need this edge. */ bb->flags |= BB_DIRTY; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e7cf798..fae6be7 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2003-09-17 Eric Botcazou + + * g++.dg/opt/cfg3.C: New test. + 2003-09-16 Kriang Lerdsuwanakij PR c++/7939 diff --git a/gcc/testsuite/g++.dg/opt/cfg3.C b/gcc/testsuite/g++.dg/opt/cfg3.C new file mode 100644 index 0000000..123c2f5 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/cfg3.C @@ -0,0 +1,61 @@ +// PR optimization/11646 +// Origin: + +// This used to fail because the compiler inadvertently cleared +// the EDGE_ABNORMAL flag on a EDGE_EH edge and didn't delete +// unreachable blocks after CSE. + +// { dg-do compile } +// { dg-options "-O -fgcse -fnon-call-exceptions" } + +struct C +{ + int i; +}; + +struct allocator +{ + ~allocator() throw() {} +}; + +struct _Vector_alloc_base +{ + _Vector_alloc_base(const allocator& __a) {} + allocator _M_data_allocator; + struct C *_M_start, *_M_end_of_storage; + void _M_deallocate(struct C* __p, unsigned int __n) {} +}; + +struct _Vector_base : _Vector_alloc_base +{ + _Vector_base(const allocator& __a) : _Vector_alloc_base(__a) { } + ~_Vector_base() { _M_deallocate(0, _M_end_of_storage - _M_start); } +}; + +struct vector : _Vector_base +{ + vector(const allocator& __a = allocator()) : _Vector_base(__a) {} + struct C& operator[](unsigned int __n) { return *_M_start; } +}; + +struct A +{ + float l() const; + A operator-(const A &) const; + const A& operator=(float) const; +}; + +struct B +{ + float d(); +}; + +float f(const A& a, B& b) +{ + vector vc; + int index = vc[0].i; + A aa; + float d = (aa - a).l(); + if (d > b.d()) aa = 0; + return b.d(); +} diff --git a/gcc/toplev.c b/gcc/toplev.c index bcc9c50..91409bf 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2846,7 +2846,8 @@ rest_of_handle_cse (tree decl, rtx insns) tem = cse_main (insns, max_reg_num (), 0, rtl_dump_file); if (tem) rebuild_jump_labels (insns); - purge_all_dead_edges (0); + if (purge_all_dead_edges (0)) + delete_unreachable_blocks (); delete_trivially_dead_insns (insns, max_reg_num ()); -- 2.7.4