[llvm-commits] [llvm] r55638 - /llvm/trunk/include/llvm/Function.h

Duncan Sands baldrick at free.fr
Thu Sep 25 01:24:52 PDT 2008


> >> The pass that updates readonly and readone status can look at call
> >> llvm.log parameters and do the right thing.
> >
> > Not if there are several calls to it with different parameters,
> > which may be the case with link time optimization.
> 
> Would it be possible for you to give an example here ? Thx.

Module A is compiled with -ffast-math.  All calls to llvm.log
are therefore of the form:
  %x = call double @llvm.log(double %a, i1 0, i1 0) readnone

Module B is compiled without -ffast-math and with errno math.
All calls to llvm.log are therefore of the form:
  %y = call double @llvm.log(double %b, i1 1, i1 1)

[In both modules llvm.log is declared as:
 double llvm.log(double, i1, i1)
i.e. with no readonly/readnone attributes.]

Now llvm-link modules A and B to form module C.  In module C you
have two calls to llvm.log:
  %x = call double @llvm.log(double %a, i1 0, i1 0) readnone
  %y = call double @llvm.log(double %b, i1 1, i1 1)
while llvm.log itself is still declared as
 double llvm.log(double, i1, i1)

The optimizers understand that the first call does not access
memory while the second call does (writes errno), because alias
analysis automatically looks at both the attributes of the callsite
and of the callee (this is the situation right now).

> >  Also, this
> > is a general mechanism - imagine it being used not for an llvm
> > intrinsic but for a routine from a runtime library; then llvm
> > wouldn't know about the special properties of the function.  But
> > that's ok, it doesn't have to!
> 
> Sorry for being dense. I do not understand.
> If I am using a library function F then I want the optimizer to know  
> whether F is readonly or not. I do not care whether llvm.log() called  
> by F is readonly or not.

What does readonly mean?  It means that there are no stores to non-local
memory.  Define a call to be a readonly call if that particular call does
not store to non-local memory.  You can imagine a clever alias analysis
that is capable of working out whether a particular call is readonly: it
would look at the parameters of the callsite, look at the callee, analyse
control flow in the callee given the particular parameter values passed,
observe that for these particular parameter values there are no stores to
non-local memory, and deduce that this particular call was a readonly call.
Note that another call to the *same function* may not be a readonly call.
Define a function to be readonly if it never writes to non-local memory,
no matter what parameter values are passed to it.

Thus if a function is readonly then all calls to it are readonly calls.
If a function is not readonly then some calls to it might nonetheless
be readonly calls.

We have the infrastructure already corresponding to these notions:
if a function is marked with the 'readonly' attribute then it is
a readonly function.  If a callsite is marked with the 'readonly'
attribute or if the callee function is marked with the 'readonly'
attribute then it is a readonly call (the onlyReadsMemory CallSite
method implements this logic; it is used by alias analysis and a
bunch of other places).

Ciao,

Duncan.

PS: This infrastructure also makes it possible to mark indirect calls
"readonly".

PPS: I think it is pointless to discuss whether having readonly attributes
on callsites is useful or not.  It clearly *might* be useful.  What is better
to discuss is whether the usefulness (it is not very useful) outweighs the
costs.  Is there a benefit to eliminating this facility?  How much benefit
is there, and does it outweigh the loss?  Personally I don't see any reason
to eliminate it, and if readonly is left alone then my love for logic and
consistency tells me that noinline and alwaysinline should be done this way
too.



More information about the llvm-commits mailing list