On Thu, Oct 8, 2015 at 10:00 PM, Jeff Law <l...@redhat.com> wrote:
> On 09/24/2015 04:28 PM, Evgeny Stupachenko wrote:
>>
>> I've fixed ICE and review issues.
>> x86 make check and bootstrap passed.
>>
>> Thanks,
>> Evgeny
>>
>> ChangeLog
>>
>> 2015-09-25  Evgeny Stupachenko<evstu...@gmail.com>
>>
>> gcc/
>>          * Makefile.in (OBJS): Add multiple_target.o.
>>          * multiple_target.c (make_attribute): New.
>>          (create_dispatcher_calls): Ditto.
>>          (expand_target_clones): Ditto.
>>          (ipa_target_clone): Ditto.
>>          * passes.def (pass_target_clone): New ipa pass.
>>          * tree-pass.h (make_pass_target_clone): Ditto.
>>
>> gcc/c-family
>>          * c-common.c (handle_target_clones_attribute): New.
>>          * (c_common_attribute_table): Add handle_target_clones_attribute.
>>          * (handle_always_inline_attribute): Add check on target_clones
>>          attribute.
>>          * (handle_target_attribute): Ditto.
>>
>> gcc/testsuite
>>          * gcc.dg/mvc1.c: New test for multiple targets cloning.
>>          * gcc.dg/mvc2.c: Ditto.
>>          * gcc.dg/mvc3.c: Ditto.
>>          * gcc.dg/mvc4.c: Ditto.
>>          * gcc.dg/mvc5.c: Ditto.
>>          * gcc.dg/mvc6.c: Ditto.
>>          * gcc.dg/mvc7.c: Ditto.
>>          * g++.dg/ext/mvc1.C: Ditto.
>>          * g++.dg/ext/mvc2.C: Ditto.
>>          * g++.dg/ext/mvc3.C: Ditto.
>>
>> gcc/doc
>>          * doc/extend.texi (target_clones): New attribute description.
>>
>>
>
>>
>> target_clones.patch
>
> Sorry this has taken so long to come back to...  As I mentioned a couple
> months ago, I'd hoped Jan would chime in on the IPA/symtab requirements.
> But that didn't happen.
>
>
> SO I went back and reviewed the discussion between Jan, Ilya & myself WRT
> some of the rules around aliases, clones, etc.  I think the key question for
> this patch is whether or not the clones have the same assembler name or not.
> From looking at expand_target_clones, I'm confident the answer is the clones
> have different assembler names.  In fact, the assembler names are munged
> with the options used for that specific clone of the original function.
>
>
>>
>> +/* Makes a function attribute of the form NAME(ARG_NAME) and chains
>> +   it to CHAIN.  */
>> +
>> +static tree
>> +make_attribute (const char *name, const char *arg_name, tree chain)
>> +{
>> +  tree attr_name;
>> +  tree attr_arg_name;
>> +  tree attr_args;
>> +  tree attr;
>> +
>> +  attr_name = get_identifier (name);
>> +  attr_arg_name = build_string (strlen (arg_name), arg_name);
>> +  attr_args = tree_cons (NULL_TREE, attr_arg_name, NULL_TREE);
>> +  attr = tree_cons (attr_name, attr_args, chain);
>> +  return attr;
>> +}
>
> This seems generic enough that I'd prefer it in attribs.c.  I was rather
> surprised when I looked and didn't find an existing routine to do this.
>
>
>> +
>> +/* If the call in NODE has multiple target attribute with multiple
>> fields,
>> +   replace it with dispatcher call and create dispatcher (once).  */
>> +
>> +static void
>> +create_dispatcher_calls (struct cgraph_node *node)
>> +{
>> +  cgraph_edge *e;
>> +  cgraph_edge *e_next;
>> +  for (e = node->callers; e ;e = (e == NULL) ? e_next : e->next_caller)
>
> That's a rather strange way to write the loop increment.  If I follow the
> loop logic correctly, it seems that we always end up using e->next_caller,
> it's just obscured.
>
> For the test if we're calling a versioned function, we just "continue".  e
> will be non-null and thus we use e->next_caller to set e for the next
> iteration.
>
> If the test for calling a versioned function falls, we set e_next to
> e->next_caller, then later set e to NULL.  That results in using e_next to
> set e for the next iteration.  But e_next was initialized to e->next_caller.
>
> So why not just write the loop increment as e = e->next-caller?

Because of this:
      e->redirect_callee (inode);
It modifies next_caller field.
The other way is to remember all what we want to redirect and create
one more loop through the modifications to apply them.

>
>
>
>> +    {
>> +      tree resolver_decl;
>> +      tree idecl;
>> +      tree decl;
>> +      gimple *call = e->call_stmt;
>> +      struct cgraph_node *inode;
>> +
>> +      /* Checking if call of function is call of versioned function.
>> +        Versioned function are not inlined, so there is no need to
>> +        check for inline.  */
>
> This comment doesn't parse well.  Perhaps:
>
> /* Check if this is a call to a versioned function.  Verisoned
>    fucntions are not inlined, so there is no need to check for that.  */
>
>
>> +
>> +/* If the function in NODE has multiple target attribute with multiple
>> fields,
>> +   create the appropriate clone for each field.  */
>> +
>> +static bool
>> +expand_target_clones (struct cgraph_node *node)
>
> So this is probably getting a little large.  Can we look to refactor it a
> little?  It's not a huge deal and there's certainly code in GCC that is far
> worse, but it just feels like there's enough going on in this code that
> there ought to be 2-3 helpers for the larger chunks of work going on inside
> this code.
>
> The first is the attribute parsing.  The second is creation of the nodes,
> and the final would be munging the name and attributes on the clones.
>
> I'm slightly concerned with using the pretty printer to build up the new
> name.  Is there precedent for this anywhere else in GCC?
I don't remember where it exactly came from. However it's not a big
deal to simplify this to std functions.
>
> When creating the munged name, don't you also have to make sure that other
> symbols that aren't supported for names don't sneak through?  I see that you
> replace = and -, but you'd need to replace any symbol that could possibly be
> used in an option, but which isn't allowed in a function name at the
> assembler level.  I'd be worried about anything that might possibly be seen
> as an operator by the assembler, '.', and possibly others.
This restriction comes from "targetm.target_option.valid_attribute_p"
and it is the same for current implementation of function
multiversioning.
It exits with error: "attribute(target("...")) is unknown".
It looks reasonable to put the check before symtab changes.
>
> Also, please double check indentation of that function.  In particular the
> code after the if-then-else (node->definition) looks like it's indented too
> far.
>
> I think this is pretty close, but does need another iteration.  Now that
> we've moved past the interactions with IPA question and have fairly
> carefully looked at the rest of the patch, I don't think subsequent reviews
> will take much time at all.
>
> jeff

Thanks for the review,
Evgeny

Reply via email to