[llvm-dev] [RFC] How to manifest information in LLVM-IR, or, revisiting llvm.assume
Doerfert, Johannes via llvm-dev
llvm-dev at lists.llvm.org
Wed Dec 18 12:09:47 PST 2019
On 12/18, Michael Kruse wrote:
> Am Mo., 16. Dez. 2019 um 17:17 Uhr schrieb Doerfert, Johannes via
> llvm-dev <llvm-dev at lists.llvm.org>:
> > 1) Use named operand bundles to encode information.
> > If we want to encode property XYZ for a value %V holds at a certain
> > program point and the property is dependent on %N we could encode
> > that as:
> > `llvm.assume() ["XYZ"(%V, %N)]`
>
> What is the advantage of using operator bundles over directly using
> arguments? That is, why not using
>
> call llvm.assume_fn.i32.i32(@llvm.assume.expression_#27, %i, %j)
>
> Is it to avoid the overloads of llvm.assume_fn? If yes, why are
> overloads of llvm.assume a problem?
The advantage is that we can encode all attributes and other "simple"
properties without outlining in a very easy to recognize way. While it
is not as powerful I'm also happy if we adopt something like:
call llvm.assume.pi32(i32* align(8) dereferenceable(16) %ptr)
Pure outlining based assumptions might also work.
> > 2) Outline assumption expression code (with side-effects).
> > If we potentially have side-effects, or we simply have a non-trivial
> > expression that requires to be lowered into instructions, we can
> > outline the assumption expression code and tie it to the
> > `llvm.assume` via another operand bundle property. It could look
> > something like this:
> > `__builtin_assume(foo(i) == bar(j));`
> > will cause us to generate
> > ```
> > /// Must return true!
> > static bool llvm.assume.expression_#27(int i, int j) {
> > return foo(i) == bar(j);
> > }
> > ```
> > and a `llvm.assume` call like this:
> > `llvm.assume() ["assume_fn"(@llvm.assume.expression_#27, %i, %j))]
> > So we generate the expression in a new function which we (only) tie to
> > the `llvm.assume()` through the "assume_fn" operand bundle. This will
> > make sure we do not accidentally evaluate the code, or assume it is
> > evaluated and produced side-effects. We can still optimize the code
> > and use the information that we learn from it at the `llvm.assume`
> > site though.
>
> I like the idea. If emitting assume_fns to the object file is an
> issue, we could introduce a LinkageType that is never emitted to an
> object file (and can only be used in an llvm.assume).
That is a really cool idea.
> > 3) Use tokens to mark ranges.
> > We have tokens which can be used to tie two instructions together,
> > basically forming a range (with some conditions on the initial CFG).
> > If we tie two `llvm.assume` calls together we can say that the
> > information provided by the first holds for any point dominated by it
> > and post-dominated by the second.
>
> Is this the same mechanism as for llvm.lifetime.start/end? It may not
> be easy to keep them consistently (post-)dominating each other, see
> http://lists.llvm.org/pipermail/llvm-dev/2017-March/111551.html .
Fair, but I argue that is fine as long as it means we only "loose" information.
We would still have the assume calls so point wise information would not
even be lost.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20191218/930bc37c/attachment.sig>
More information about the llvm-dev
mailing list