On Tue, 4 Feb 2014, Jan Hubicka wrote: > Hi, > while playing around with devirtualization I tried to make it to always > produce > builtin_unreachable (). This makes early inliner to ICE, since the callgraph > edges > are not properly updated after folding. This is because > cgraph_update_edges_for_call_stmt > is called on a wrong statement. > > Does something like this look resonable?
Hmm, the code looks messy. Can you re-organize it like gimple prev = NULL; for (gsi = gsi_start_bb ....) { gimple old_stmt = gsi_stmt (gsi); if (fold_stmt (gsi)) { if (is_gimple_call (old_stmt)) { gimple_stmt_iterator i = gsi; do { new_stmt = gsi_stmt (i); if (is_gimple_call (new_stmt)) { ... do call stuff ... break; } gsi_prev (&i) } while (!gsi_end_p (i) && gsi_stmt (i) != prev); } new_stmt = gsi_stmt (gsi); if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt)) gimple_purge_dead_eh_edges (...) prev = new_stmt; } else prev = old_stmt; } thus merge the special builtin handling with the general call handling? Thanks, Richard. > Honza > > * tree-inline.c (fold_marked_statements): Correctly handle cases where > folding produes extra statement. > Index: tree-inline.c > =================================================================== > --- tree-inline.c (revision 207438) > +++ tree-inline.c (working copy) > @@ -4480,8 +4480,14 @@ fold_marked_statements (int first, struc > if (pointer_set_contains (statements, gsi_stmt (gsi))) > { > gimple old_stmt = gsi_stmt (gsi); > + gimple_stmt_iterator prev = gsi; > + gimple prev_stmt = NULL; > tree old_decl = is_gimple_call (old_stmt) ? gimple_call_fndecl > (old_stmt) : 0; > > + gsi_prev (&prev); > + if (!gsi_end_p (prev)) > + prev_stmt = gsi_stmt (prev); > + > if (old_decl && DECL_BUILT_IN (old_decl)) > { > /* Folding builtins can create multiple instructions, > @@ -4541,8 +4547,31 @@ fold_marked_statements (int first, struc > > if (is_gimple_call (old_stmt) > || is_gimple_call (new_stmt)) > - cgraph_update_edges_for_call_stmt (old_stmt, old_decl, > - new_stmt); > + { > + if (!is_gimple_call (new_stmt)) > + { > + prev = gsi; > + gsi_prev (&prev); > + > + /* Fold stmt may turn > + > + retval = call (); > + > + statement into > + > + __builtin_unreachable (); > + retval = dummy. > + > + Be sure to look up the call. */ > + > + if (!gsi_end_p (prev) > + && gsi_stmt (prev) != prev_stmt > + && is_gimple_call (gsi_stmt (prev))) > + new_stmt = gsi_stmt (prev); > + } > + cgraph_update_edges_for_call_stmt (old_stmt, old_decl, > + new_stmt); > + } > > if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt)) > gimple_purge_dead_eh_edges (BASIC_BLOCK_FOR_FN (cfun, > > -- Richard Biener <rguent...@suse.de> SUSE / SUSE Labs SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 GF: Jeff Hawn, Jennifer Guild, Felix Imend"orffer