[llvm-dev] Dereferenceable load semantics & LICM

Piotr Padlewski via llvm-dev llvm-dev at lists.llvm.org
Sat Apr 1 06:59:03 PDT 2017

2017-03-31 23:20 GMT+02:00 Sanjoy Das <sanjoy at playingwithpointers.com>:

> Hi Piotr,
> On March 31, 2017 at 1:07:12 PM, Piotr Padlewski
> (piotr.padlewski at gmail.com) wrote:
> > [snip]
> > Do I understand it correctly, that it is legal to do the hoist because
> all
> > of the instructions above %vtable does not throw?
> Yes, I think you're right.  HeaderMayThrow is a conservative
> approximation, and the conservativeness is biting us here.
> > Are there any plans to fix it in the future? The fix doesn't seem hard to
> Not to my knowledge.
> > write and I can do it, but I am not sure if it won't be too expensive.
> Maybe we can do it (relatively) cheaply:
>  - Remember the first throwing instruction in the header, instead of a
>    boolean, in LoopSafetyInfo
>  - In hoistRegion, remember if you've seen the first throwing
>    instruction yet
>  - Pass the above as a boolean parameter to isGuaranteedToExecute, and
>    instead of
>      if (Inst.getParent() == CurLoop->getHeader())
>        return !SafetyInfo->HeaderMayThrow;
>    do something like
>      if (Inst.getParent() == CurLoop->getHeader())
>        return IsBeforeThrowingInst;
> -- Sanjoy
I was thinking about something very similar and it seems to be a good
approach to me because it has much lower complexity.

In the review Sanjoy correctly spoted that I am not discarding
invariant.group metadata when hoisting, which is incorrect in general.
This generates a big problem to devirtualization, because discarding
metadata when hoisting vtable load might be worse than not hoisting when
there might be another load/store with !invariant.group dominating it (e.g.
after inlining).

I don't see any way to model it right now in LLVM, but I see a one simple
 add extra information to the metadata nodes indicating that this property
is non-local:

%0 = load... %p, !invariant.group !1, !dereferenceable !2
%1 = load ... %0, !invariant.load !0, !dereferenceable !2

!0 = !{!"GlobalProperty"}
!1 = !{!"MyType", !"GlobalProperty"}
!2 = !{i64 8, !"GlobalProperty}

With that we would strip only the metadata not containing this information.

For devirtualization it would make sense with invariant.load,
invariant.group and dereferenceable.

What do you think about this idea?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170401/2bf6a738/attachment-0001.html>

More information about the llvm-dev mailing list