[cfe-dev] Disable certain llvm optimizations at clang frontend

Y Song via cfe-dev cfe-dev at lists.llvm.org
Fri Jun 19 11:39:54 PDT 2020


On Fri, Jun 19, 2020 at 8:53 AM Hal Finkel <hfinkel at anl.gov> wrote:
>
> On 6/19/20 10:19 AM, Y Song via cfe-dev wrote:
> > Hi,
> >
> > [resend with proper cfe-dev tag]
> >
> > This is to seek some advice on how to disable certain llvm
> > optimizations when compiled with clang for BPF backend. For example,
> > we want to disable two optimizations, instcombine and simplifyCFG. I
> > would like to get some advice about what is the best way to do it.
> >
> > Some Background on Why We want to do this
> > ===================================
> >
> > Any BPF code needs to go through a kernel verifier
> >     https://github.com/torvalds/linux/blob/master/kernel/bpf/verifier.c
> > before it can be executed in the kernel. verifier tries to ensure the safety
> > of the program, no illegal memory access, etc. In certain cases, clang
> > generated optimized codes make verification very hard, see pending
> > commits with another approach focused on BPF backend and some core
> > optimizations.
> >    https://reviews.llvm.org/D72787
> >    https://reviews.llvm.org/D82112
> >    https://reviews.llvm.org/D81859
> > To workaround the issue, people have to write inline asm or tweak
> > their program in a very user-unfriendly way to disable certain
> > transformations, in particular, instcombine and simplifyCFG.
> >
> > Alternative Method in clang Frontend
> > ============================
> >
> > The above approach tried to disable/undo/influence specific
> > optimizations. Another approach is to disable instcombine and
> > simplifyCFG during compilation process. This is a little bit heavy
> > weight. But it may still be fine as this will ease the pain for
> > development. For most customers, a little performance loss vs.
> > development gain probably will be fine.
> >
> > How to disable instcombine/simplifyCFG in clang frontends? It looks
> > like function attributes and insn metadatas are used to influence
> > optimizations.
> > The following approach might work, I think:
> >     BPF backend may add the following two attributes to all functions:
> >     "disable-instcombine" = "true"
> >     "disable-simplifyCFG" = "true"
> > And during instcombine and simplifyCFG, the above function attribute will
> > be checked, it is true, the pass will be skipped.
> >
> > Do you think the above method could work? Any alternative suggestions
> > are also appreciated.
>
>
> This is certainly an interesting problem. A few thoughts:
>
>   * A generalized mechanism to disable parts of the pass pipeline, or
> maybe specify a pass pipeline, using function attributes, may be of
> broad utility. That having been said, it's not clearly the right answer
> to this problem.
>
>   * If we're going to disable things, I would much prefer attributes
> with a semantic meaning. It's not like those passes are the only passes
> that might perform transformations that would be problematic for your
> backend.

Indeed specifying attributes with intention is better than disabling individual
passes. Based on intention, we can tailor related passes, disabling
the whole pass or
only some specific transformations in that particular pass.

Just to be more specific about what transformations we want to disable:
  (1). Undo a transformation in InstCombine/InstCombineAndOrXor.cpp
        (https://reviews.llvm.org/D72787)
        This transformation created a new variable "var.off" for comparison but
        using the original variable "var" later on. The kernel verifier does not
        have a better range of "var" at its use place and this may cause
        verification failure.

        To generalize, BPF prefers the single variable is refined and used later
        for each verification. New variable can be created and used for further
        value range refinement, but all later usage of old variable should be
        replaced with the new variable.
   (2). Prevent speculative code motion
          (https://reviews.llvm.org/D82112, https://reviews.llvm.org/D81859)
         If the code in the original program may not execute under
certain conditions,
         we could like the code not to execute in the final byte code
under the same
         condition, regardless of whether it is safe to execute or not.

    I guess we could have two attributes here:
       - "refine-value-range-with-original-var" (false by default, true for BPF)
       - "no-speculative-code-motion" (false by default, true for BPF)

>
>   * How difficult would it be for your backend to try harder to coerce
> the IR into the form accepted by the BPF verifier? The current
> compilation problem seems unsound, unfortunately, and I'm wondering how
> we might move the overall system to be better grounded.

The above two kinds of optimizations are totally okay for other
architectures. It probably
just BPF has particular problems due to its extra verification phase
before executing.

For the case "refine-value-range-with-original-var",
https://reviews.llvm.org/D72787,
we have moderate success. Essentially, it is an pattern-match undo to
the previous instcombine
optimizations. But I am thinking that preventing the transformation
from happening might be
a better approach. https://reviews.llvm.org/D70372 is an unsuccessful
attempt. I think function
attribute might be a better approach here than undoing the transformation.

For the case "no-speculative-code-motion", the BPF backend is going to implement
getUserCost() (https://reviews.llvm.org/D82112) and needs core
simplifyCFG change
as well (https://reviews.llvm.org/D81859).

All the above bpf and core changes resolved the test case I am seeing.
But my fear is that if in the future, we found some other
optimizations needs undo or disabled,
bpf will need to do pattern matching again or having special
arrangement with that optimization
pass like in https://reviews.llvm.org/D81859.
Having a generic attribute which describes intention and later used by
optimization passes
seem better long term.

Thoughts?

>
>   -Hal
>
>
> >
> > Thanks!
> >
> > Yonghong
> > _______________________________________________
> > cfe-dev mailing list
> > cfe-dev at lists.llvm.org
> > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
> --
> Hal Finkel
> Lead, Compiler Technology and Programming Languages
> Leadership Computing Facility
> Argonne National Laboratory
>


More information about the cfe-dev mailing list