[llvm-commits] [PATCH] Invariants (and Assume Aligned) - LLVM

Dan Gohman dan433584 at gmail.com
Thu Dec 6 15:19:39 PST 2012


On Thu, Dec 6, 2012 at 2:57 PM, Nuno Lopes <nunoplopes at sapo.pt> wrote:
>> This patch assumes that asserted conditions are globally true. This
>> significantly restricts their usefulness. Everything's easy if we just
>> think about asserting properties for an entire function:
>>
>> void foo(void *p) {
>>  __builtin_assume(p is aligned or whatever);
>>  use(p);
>> }
>>
>> However, as soon as a function like this can get inlined into a
>> perfectly reasonable callsite like this:
>>
>>  if (p is aligned or whatever)
>>    foo(p);
>>  else
>>    do_something_slow(p);
>>
>> it doesn't work anymore, because it would apply to all uses of p in
>> the caller, including uses where p isn't aligned.
>>
>> It seems that the intuitive semantics would be that an assertion
>> should hold for all the uses dominated by an assertion statement.
>> Requiring dominator trees for anything that wants to use assertion
>> information would unfortunately keep it out of instcombine, where it
>> would be very useful, so this is a significant problem. The
>> tentatively established way to solve this kind of problem is to make
>> the assertion return a copy of the value it is asserting a predicate
>> about. Something like this:
>>
>>  pp = __buiiltin_assume(p, p != 0);
>
>
> That starts sounding like SSI's pi nodes:
> p = ...;
> if (...) {
>    pp = pi(p);
>    use (pp)
> }
> assume(pp != 0);
>
>
> Then assumptions can be global again, since copies of vars are created where
> necessary.

I agree; if the IR were always in SSI form, this intrinsic would be
easier to design.

>
>
>
>> The other big topic to discuss in this patch is ephemeral values. This
>> would be a significant landmark change.
>>
>> Ephemeral values add uses of values to the program which wouldn't
>> otherwise be there. This has its purpose of course, but also its
>> downsides, as it will interfere with use_empty() and hasOneUse()
>> optimizations (much of instcombine, etc.). It could easily be a
>> dickens for indvars and lsr, unless, again, it gets the right
>> special-case handling. It'll need special-casing in several analyses
>> which walk def-use lists. The new EphemeralValues analysis pass will
>> make the special-casing less painful, but it's still a value map that
>> has to be passed around and kept current.
>
>
> Yes, I'm also worried about the burden for each optimization.
> On the other hand, the code for invariants is single-path, so it's not that
> bad, since e.g. it won't confuse the single-BB-loop kind of optimizations.

I'm not sure what you mean here.

> Some time ago we discussed the creation of a separate mini-language to
> specify invariants and other stuff that could be used in metadata. I think
> debug info was another potential client for this language. As well as
> assertions about buffer sizes. But it's a big project..

Yes.

> BTW, I think ephemeral calls should be limited to readnone (readonly?)
> functions. Stating assumptions and get side-effects at the same time doesn't
> really make sense. And assume() may or may not be deleted in between.

In one sense, this would happen automatically, because calls with
arbitrary side effects will be implicitly non-ephemeral. However,
there would be nothing which would prevent a call which writes to
memory in known ways, e.g. memcpy, from being ephemeral, if the only
uses of its output memory are ephemeral loads.

Dan



More information about the llvm-commits mailing list