[llvm-dev] Revisiting/refining the definition of optnone with interprocedural transformations

via llvm-dev llvm-dev at lists.llvm.org
Thu Apr 22 09:05:18 PDT 2021


> On 4/22/21 9:43 AM, paul.robinson at sony.com wrote:
> >> That said, I believe it is a mistake that `optnone` requires
> >> `noinline`. There is no reason for it to do so on the IR level.
> >> If you argue C-level `optnone` should imply `noinline`, that is
> >> a something worth discussing, though on the IR level we can
> >> decouple them. Use case, for example, the not-optimized version
> >> is called from functions that are `optnone` themselves while
> >> other call sites are inlined and your function is optimized. So
> >> you can use the two attributes to do context sensitive `optnone`.
> > The original intent for `optnone` was to imitate the -O0 pipeline
> > to the extent that was feasible.  The -O0 pipeline (as constructed
> > by Clang) runs just the always-inliner, not the regular inliner;
> > so, functions marked `optnone` should not be inlined.  The way
> > to achieve that effect most simply is to have `optnone` require
> > `noinline` and that's what we did.
> >
> > If we have `optnone` stop requiring `noinline` and teach the
> > inliner to inline an `optnone` callee only into an `optnone` caller,
> > then we are violating the intent that `optnone` imitate -O0, because
> > that inlining would not have happened at -O0.
> 
> I think I initially read this wrong, hence the part below.
> After reading it again, I have one question: Why would the
> inliner inline something that is not `always_inline` into
> an `optnone` caller? That would violate the idea of `optnone`,
> IMHO, regardless if the callee is `optnone` or not. That is
> why I don't believe `noinline` on the callee is necessary
> for your use case.

The inliner should be ignoring `optnone` callers, so it would
never inline *anything* into an `optnone` caller.  (Other than
an `alwaysinline` function.)

I had read this:

> >> I believe it is a mistake that `optnone` requires `noinline`.

and the case that came to mind is inlining an `optnone` callee
into a not-`optnone` caller.  The inlined copy would then be
treated to further optimization, which violates the idea of
`optnone`.

Now, the inliner already knows to avoid `noinline` callees, so
attaching `noinline` to `optnone` functions was (at the time)
considered an optimal way to avoid the problematic case.  We
could instead teach the inliner to skip `optnone` callees, and
that would allow us to eliminate the requirement that `optnone`
functions must also be `noinline`.  I am unclear why redefining
`optnone` to _imply_ `noinline` (rather than _require_ `noinline`)
is better, but then I don't work much with attributes.

The notion of allowing an `optnone` caller to inline an `optnone`
callee sounds like it would also violate the intent of `optnone`
in that it should imitate -O0, where inlining is confined to
`alwaysinline` callees, and `optnone` is defined to conflict with
`alwaysinline` (because if you always inline something, you are
allowing it to have subsequent optimizations same as the caller,
which conflicts with `optnone`).

So, if you want to undo the _requirement_ that `optnone` must
have `noinline`, but then redefine `optnone` such that it can't
be inlined anywhere, you've done something that seems to have no
practical effect.  Maybe that helps Attributor in some way, but
I don't see any other reason to be making this change.
--paulr



More information about the llvm-dev mailing list