At linktime, consider linkonces as ones that will go away

Michael Matz matz@suse.de
Thu Jul 8 14:43:00 GMT 2010


Hi,

On Thu, 8 Jul 2010, Jan Hubicka wrote:

> cgraph_only_called_directly_p when we know function is only called directly
> and we see all the calls.  I.e. it is not having address taken, not externally
> visible and not used in funnny way (alias, __attribute__ ((used)) etc.).
> Such functions go away when all direct calls disappear.
> 
> This is used for deciding when function is local and some other cases.

So this one is only a sub-predicate with many users, not all of them 
related to "will the function go away?" questions.

> Then we have cgraph_can_remove_if_no_direct_calls_p that in addition 
> knows that COMDAT functions can disappear even when they can be called 
> in hidden way from other unit if they are there.  This is used i.e. by 
> inliner to decide whether offline copy is needed after all calls are 
> inlined.
> 
> Then there is cgraph_can_remove_if_no_direct_calls_and_refs_p that is 
> stronger by not checking for addresses taken and is used by unreachable 
> function removal.
> 
> And finally we have new predicate that is somewhere in between these 
> two.

What differentiates the users of the first predicate from those of the 
second two?  The first case reads to me like "decide if offline copy is 
needed".  The second case reads the same to me.  And the third case too.  
Why do you need three predicates, aren't you always asking "do I need an 
offline copy of this function, even if I can resolve all calls?"

The circumstance should always be the same.  They depend on compilation 
modes and several computed flags.  But I don't see how different questions 
than the above are to be asked.

For instance even your first predicate 
(cgraph_can_remove_if_no_direct_calls_p) needs to take into account 
non-dead references (aka address-takens) to the function (in which case we 
need an offline copy).  Your second predicate seemingly doesn't take
node->address_taken into account, which I find strange.

And the third predicate also just adds a variant for answering the 
question "will this function be removed?".

In addition the pre-existing two predicates are each used exactly once, 
and all uses are itself in between a number of conditions.  This just adds 
the confusion between the different predicates (for instance why the 
surrounding condition isn't part of the predicate), e.g. here:

      if (!e->callee->callers->next_caller
          && cgraph_can_remove_if_no_direct_calls_p (e->callee)
          /* Don't reuse if more than one function shares a comdat group.
             If the other function(s) are needed, we need to emit even
             this function out of line.  */
          && !e->callee->same_comdat_group

So, why do you need three cgraph_can_remove predicates (and why don't they 
contain all conditions necessary?)

> So cgraph_removed_p name does not make it very clear how that predicate 
> differs from other.  Also it is not removed from program at the timewe 
> call it, only will be removed as consequence of transformation and 
> unreachable function removal later...

(that's what the _p is for, isn't it?)


Ciao,
Michael.



More information about the Gcc-patches mailing list