[PATCH] Fix PR46717

Richard Guenther rguenther@suse.de
Tue Nov 30 15:09:00 GMT 2010


With profiling done in SSA form we have to be more careful with
preserving EH information because of PHI nodes.  The following
patch makes sure to update them and retain the original EH edges
when present.

Profile-bootstrapped and tested on x86_64-unknown-linux-gnu, applied
to trunk.

Richard.

2010-11-30  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/46717
	* value-prof.c (gimple_ic): Preserve EH edges of the indirect
	call.  Manually create EH edges for the direct call and update
	target PHI nodes.

Index: gcc/value-prof.c
===================================================================
*** gcc/value-prof.c	(revision 167290)
--- gcc/value-prof.c	(working copy)
*************** gimple_ic (gimple icall_stmt, struct cgr
*** 1146,1152 ****
    icall_bb = e_di->dest;
    icall_bb->count = all - count;
  
!   e_ij = split_block (icall_bb, icall_stmt);
    join_bb = e_ij->dest;
    join_bb->count = all;
  
--- 1146,1156 ----
    icall_bb = e_di->dest;
    icall_bb->count = all - count;
  
!   /* Do not disturb existing EH edges from the indirect call.  */
!   if (last_stmt (icall_bb) != icall_stmt)
!     e_ij = split_block (icall_bb, icall_stmt);
!   else
!     e_ij = find_fallthru_edge (icall_bb->succs);
    join_bb = e_ij->dest;
    join_bb->count = all;
  
*************** gimple_ic (gimple icall_stmt, struct cgr
*** 1182,1202 ****
        add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION);
      }
  
!   /* Fix eh edges */
    lp_nr = lookup_stmt_eh_lp (icall_stmt);
!   if (lp_nr != 0)
      {
!       if (stmt_could_throw_p (dcall_stmt))
  	{
! 	  add_stmt_to_eh_lp (dcall_stmt, lp_nr);
! 	  make_eh_edges (dcall_stmt);
  	}
- 
-       gcc_assert (stmt_could_throw_p (icall_stmt));
-       make_eh_edges (icall_stmt);
- 
-       /* The old EH edges are sill on the join BB, purge them.  */
-       gimple_purge_dead_eh_edges (join_bb);
      }
  
    return dcall_stmt;
--- 1186,1212 ----
        add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION);
      }
  
!   /* Build an EH edge for the direct call if necessary.  */
    lp_nr = lookup_stmt_eh_lp (icall_stmt);
!   if (lp_nr != 0
!       && stmt_could_throw_p (dcall_stmt))
      {
!       edge e_eh, e;
!       edge_iterator ei;
!       gimple_stmt_iterator psi;
! 
!       add_stmt_to_eh_lp (dcall_stmt, lp_nr);
!       FOR_EACH_EDGE (e_eh, ei, icall_bb->succs)
! 	if (e_eh->flags & EDGE_EH)
! 	  break;
!       e = make_edge (dcall_bb, e_eh->dest, EDGE_EH);
!       for (psi = gsi_start_phis (e_eh->dest);
! 	   !gsi_end_p (psi); gsi_next (&psi))
  	{
! 	  gimple phi = gsi_stmt (psi);
! 	  SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e),
! 		   PHI_ARG_DEF_FROM_EDGE (phi, e_eh));
  	}
      }
  
    return dcall_stmt;



More information about the Gcc-patches mailing list