Richard Guenther - Re: PR middle-end/30509 (original) (raw)

This is the mail archive of the gcc-patches@gcc.gnu.orgmailing list for the GCC project.

Hi, this patch fixes pretty ugly ICE in computing dominance info after function clonning for inlining. The problem is that IPA passes marks some functions as non-trapping and the clone function CFG has fewer edges in CFG than the original function rendering some blocks unreachable. THis makes dominance compulation to ICE, however we can't simply delete the blocks as we would get the cgraph of the clones out of sync, so instead I just propagate the EH info into the clones and deferring the removal of unnecesary edges to fixup_cfg where it is normally done without inlining.

Bootstrapped/regtested i686-linux, OK?

Honza

struct all{ }; struct g { g(const all& __a){ } }; template struct vector: protected g { vector(const all& __a = all()) : g(__a) { } }; void f() throw(); struct Logger { bool m_bUseFile; vector m_msgQueue; Logger(); }; Logger* getInstance() { return new Logger(); } void useVerboseLog( bool bUse ) { getInstance()->m_bUseFile = bUse; } Logger::Logger() { f(); } PR middle-end/30509 * tree-inline.c (copy_bb): Copy EH precisely when cloning for inlining Index: tree-inline.c

*** tree-inline.c (revision 122292) --- tree-inline.c (working copy) *************** copy_bb (copy_body_data *id, basic_block *** 873,879 **** gcc_assert (lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt) != 0);

! if (tree_could_throw_p (stmt)) { int region = lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt); /* Add an entry for the copied tree in the EH hashtable. --- 873,891 ---- gcc_assert (lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt) != 0);

! if (tree_could_throw_p (stmt) ! /* When we are cloning for inlining, we are supposed to ! construct a clone that calls precisely the same functions ! as original. However IPA optimizers might've proved ! earlier some function calls as non-trapping that might ! render some basic blocks dead. ! ! We can't update SSA with unreachable blocks in CFG and thus ! we prevent the scenario by preserving even the "dead" eh ! edges until the point they are later removed by ! fixup_cfg pass. / ! || (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES ! && lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt) > 0)) { int region = lookup_stmt_eh_region_fn (id->src_cfun, orig_stmt); / Add an entry for the copied tree in the EH hashtable.