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

Reply via email to