> 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.

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

Reply via email to