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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Make IPA-CP work when there are SCCs of call graph nodes represented by a thunk


Hi,

until recently we did not have thunks with incoming edges in the call
graph.  However, speculative devirtualization can introduce them which
may lead to creation of new SCCs in the call graph.  What is more,
ipa_reduced_postorder called with reduce parameter set to true may
decide to represent the whole SCC with the thunk which will in turn
currently cause propagate_constants_topo from IPA-CP to ignore the
whole SCC and make ipcp_verify_propagated_values fail later.  This
happens for example when compiling Mozilla Firefox (I did it with LTO
but it failed even when creating a fat unit object file).  I believe
Honza has this check disabled for this reason.

The patch below fixes propagate_constants_topo by making it check each
node in the SCC rather than just the leading one.  I have also changed
it to use ipa_get_nodes_in_cycle rather than loop through dfs_infos
since that seems to be the documented way of iterating over SCCs.
(And I should probably move edge_within_scc to ipa-utils too.)

Bootstrapped and tested on x86_64-linux, I have also successfully
LTO-built Firefox with this patch.  OK for trunk?

Thanks,

Martin


2013-09-09  Martin Jambor  <mjambor@suse.cz>

	* ipa-cp.c (propagate_constants_topo): Do not ignore SCC
	represented by a thunk.

Index: src/gcc/ipa-cp.c
===================================================================
*** src.orig/gcc/ipa-cp.c
--- src/gcc/ipa-cp.c
*************** propagate_constants_topo (struct topo_in
*** 2113,2135 ****
  
    for (i = topo->nnodes - 1; i >= 0; i--)
      {
        struct cgraph_node *v, *node = topo->order[i];
!       struct ipa_dfs_info *node_dfs_info;
  
-       if (!cgraph_function_with_gimple_body_p (node))
- 	continue;
- 
-       node_dfs_info = (struct ipa_dfs_info *) node->symbol.aux;
        /* First, iteratively propagate within the strongly connected component
  	 until all lattices stabilize.  */
!       v = node_dfs_info->next_cycle;
!       while (v)
! 	{
  	  push_node_to_stack (topo, v);
- 	  v = ((struct ipa_dfs_info *) v->symbol.aux)->next_cycle;
- 	}
  
!       v = node;
        while (v)
  	{
  	  struct cgraph_edge *cs;
--- 2113,2129 ----
  
    for (i = topo->nnodes - 1; i >= 0; i--)
      {
+       unsigned j;
        struct cgraph_node *v, *node = topo->order[i];
!       vec<cgraph_node_ptr> cycle_nodes = ipa_get_nodes_in_cycle (node);
  
        /* First, iteratively propagate within the strongly connected component
  	 until all lattices stabilize.  */
!       FOR_EACH_VEC_ELT (cycle_nodes, j, v)
! 	if (cgraph_function_with_gimple_body_p (v))
  	  push_node_to_stack (topo, v);
  
!       v = pop_node_from_stack (topo);
        while (v)
  	{
  	  struct cgraph_edge *cs;
*************** propagate_constants_topo (struct topo_in
*** 2144,2162 ****
        /* Afterwards, propagate along edges leading out of the SCC, calculates
  	 the local effects of the discovered constants and all valid values to
  	 their topological sort.  */
!       v = node;
!       while (v)
! 	{
! 	  struct cgraph_edge *cs;
! 
! 	  estimate_local_effects (v);
! 	  add_all_node_vals_to_toposort (v);
! 	  for (cs = v->callees; cs; cs = cs->next_callee)
! 	    if (!edge_within_scc (cs))
! 	      propagate_constants_accross_call (cs);
! 
! 	  v = ((struct ipa_dfs_info *) v->symbol.aux)->next_cycle;
! 	}
      }
  }
  
--- 2138,2155 ----
        /* Afterwards, propagate along edges leading out of the SCC, calculates
  	 the local effects of the discovered constants and all valid values to
  	 their topological sort.  */
!       FOR_EACH_VEC_ELT (cycle_nodes, j, v)
! 	if (cgraph_function_with_gimple_body_p (v))
! 	  {
! 	    struct cgraph_edge *cs;
! 
! 	    estimate_local_effects (v);
! 	    add_all_node_vals_to_toposort (v);
! 	    for (cs = v->callees; cs; cs = cs->next_callee)
! 	      if (!edge_within_scc (cs))
! 		propagate_constants_accross_call (cs);
! 	  }
!       cycle_nodes.release ();
      }
  }
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]