On Mon, Oct 29, 2012 at 5:55 AM, Jan Hubicka <hubi...@ucw.cz> wrote: >> Index: gcc/cgraph.c >> =================================================================== >> --- gcc/cgraph.c (revision 192623) >> +++ gcc/cgraph.c (working copy) >> @@ -132,6 +132,74 @@ static GTY(()) struct cgraph_edge *free_edges; >> /* Did procss_same_body_aliases run? */ >> bool same_body_aliases_done; >> >> +/* Map a cgraph_node to cgraph_function_version_info using this htab. >> + The cgraph_function_version_info has a THIS_NODE field that is the >> + corresponding cgraph_node.. */ >> +htab_t GTY((param_is (struct cgraph_function_version_info *))) >> + cgraph_fnver_htab = NULL; > > I think you want declare the htab static and arrange it to be freed after > cgraph construction, so you don't need to take care of nodes being removed > via the hooks.
I will declare the htab static but I want this htab for later optimizations, like dispatch hoisting. Please see: http://gcc.gnu.org/ml/gcc-patches/2011-04/msg02285.html for a description of the optimization. IFUNC based dispatch blocks inlining of multi-versioned functions and dispatch hoisting will help with this. I will make the other changes asap. Thanks, -Sri. > > OK with this change. > > I have few other comments: >> + /* IFUNC resolvers have to be externally visible. */ >> + TREE_PUBLIC (decl) = 1; >> + DECL_UNINLINABLE (decl) = 1; > > Why the resolvers can not be inlined? >> + >> + DECL_EXTERNAL (decl) = 0; >> + DECL_EXTERNAL (dispatch_decl) = 0; >> + >> + DECL_CONTEXT (decl) = NULL_TREE; >> + DECL_INITIAL (decl) = make_node (BLOCK); >> + DECL_STATIC_CONSTRUCTOR (decl) = 0; >> + TREE_READONLY (decl) = 0; >> + DECL_PURE_P (decl) = 0; > > I think those can be copied from the functions you are resolving. (well as > well > as many attributes and properties) >> + >> + if (DECL_COMDAT_GROUP (default_decl)) >> + { >> + DECL_COMDAT (decl) = DECL_COMDAT (default_decl); >> + make_decl_one_only (decl, DECL_COMDAT_GROUP (default_decl)); >> + } >> + else if (TREE_PUBLIC (default_decl)) >> + { >> + /* In this case, each translation unit with a call to this >> + versioned function will put out a resolver. Ensure it >> + is comdat to keep just one copy. */ >> + DECL_COMDAT (decl) = 1; >> + make_decl_one_only (decl, DECL_ASSEMBLER_NAME (decl)); >> + } >> + /* Build result decl and add to function_decl. */ >> + t = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE, ptr_type_node); >> + DECL_ARTIFICIAL (t) = 1; >> + DECL_IGNORED_P (t) = 1; >> + DECL_RESULT (decl) = t; >> + >> + gimplify_function_tree (decl); >> + push_cfun (DECL_STRUCT_FUNCTION (decl)); >> + gimple_register_cfg_hooks (); >> + init_empty_tree_cfg_for_function (DECL_STRUCT_FUNCTION (decl)); >> + cfun->curr_properties |= >> + (PROP_gimple_lcf | PROP_gimple_leh | PROP_cfg | PROP_ssa >> + | PROP_gimple_any); >> + cfun->curr_properties = 15; >> + new_bb = create_empty_bb (ENTRY_BLOCK_PTR); >> + make_edge (ENTRY_BLOCK_PTR, new_bb, EDGE_FALLTHRU); >> + make_edge (new_bb, EXIT_BLOCK_PTR, 0); >> + *empty_bb = new_bb; > > You can simplify this by init_lowered_empty_function. > > Honza