Yichao Yu via llvm-dev
2017-Oct-31 16:17 UTC
[llvm-dev] Status of llvm.invariant.{start|end}
> We at Azul have been using invariant.start for marking objects as immutable after a certain point. > Also, upstream changes to teach relevant optimizations about invariant.start and end were added > last year. > > With respect to store to load forwarding, this is handled in GVN. I think the test cases in test/Transforms/GVN/invariant.start.ll > handle what you’re looking for.Hmm, I'm pretty sure I checked that. It seems that none of the test cases in there actually requires invariant.start for store-to-load forwarding? (they need `invariant.start|end` to not be marked as modifying the memory but should all work without the intrinsics.) AFAICT the simple case in the issue I linked still doesn't work ``` declare void @g(i8*) declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) #0 define i8 @f() { %a = alloca i8 store i8 0, i8* %a %i = call {}* @llvm.invariant.start.p0i8(i64 1, i8* %a) call void @g(i8* %a) %r = load i8, i8* %a ret i8 %r } attributes #0 = { argmemonly nounwind } ``` A related note, can this be marked as inaccessiblemem_or_argmemonly plus readonly on the argument? As far as not messing with the alias analysis goes, this works very well without LLVM knowning anything about such a function. Of course the store to load forwarding still need to be handled separately but it seems that this can avoid some of the special cases on this intrinsics.> > > Hope this helps, > Anna > >> On Oct 29, 2017, at 9:01 PM, Yichao Yu via llvm-dev <llvm-dev at lists.llvm.org> wrote: >> >> Hi, >> >> From LangRef, these intrinsics seems really useful for letting LLVM >> know about certain higher level immutability guarantee, e.g. for >> objects that are not allowed to be mutated after construction. >> However, it doesn't seem to work[1] and a quick code search suggests >> that there's not a single optimization pass that's currently using it >> for store to load forwarding, only very few that use it to eliminate >> stores. The issue linked is marked as resolved-later and mentioned >> that it "probably have to be redesigned before they work out right". >> What has to be redesigned to make it work and is there a better way >> that works currently to mark an object as immutable after a certain >> point/in certain region? >> >> Yichao Yu >> >> [1] https://bugs.llvm.org/show_bug.cgi?id=5441 >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >
Anna Thomas via llvm-dev
2017-Oct-31 19:50 UTC
[llvm-dev] Status of llvm.invariant.{start|end}
> On Oct 31, 2017, at 12:17 PM, Yichao Yu <yyc1992 at gmail.com> wrote: > >> We at Azul have been using invariant.start for marking objects as immutable after a certain point. >> Also, upstream changes to teach relevant optimizations about invariant.start and end were added >> last year. >> >> With respect to store to load forwarding, this is handled in GVN. I think the test cases in test/Transforms/GVN/invariant.start.ll >> handle what you’re looking for. > > Hmm, I'm pretty sure I checked that. > It seems that none of the test cases in there actually requires > invariant.start for store-to-load forwarding? (they need > `invariant.start|end` to not be marked as modifying the memory but > should all work without the intrinsics.) AFAICT the simple case in the > issue I linked still doesn't work > > ``` > declare void @g(i8*) > > declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) #0 > > define i8 @f() { > %a = alloca i8 > store i8 0, i8* %a > %i = call {}* @llvm.invariant.start.p0i8(i64 1, i8* %a) > call void @g(i8* %a) > %r = load i8, i8* %a > ret i8 %r > } > > attributes #0 = { argmemonly nounwind } > ```Yes, you’re right. We don’t forward across the call even in presence of invariant.start. By definition, invariant.start represents constant physical memory, so I would think this is a legal transform to do. Ofcourse, this can lead to miscompiles if g is a special function that can modify %a in some way, but those are things the front end needs to identify. Anna> >> >> >> Hope this helps, >> Anna >> >>> On Oct 29, 2017, at 9:01 PM, Yichao Yu via llvm-dev <llvm-dev at lists.llvm.org> wrote: >>> >>> Hi, >>> >>> From LangRef, these intrinsics seems really useful for letting LLVM >>> know about certain higher level immutability guarantee, e.g. for >>> objects that are not allowed to be mutated after construction. >>> However, it doesn't seem to work[1] and a quick code search suggests >>> that there's not a single optimization pass that's currently using it >>> for store to load forwarding, only very few that use it to eliminate >>> stores. The issue linked is marked as resolved-later and mentioned >>> that it "probably have to be redesigned before they work out right". >>> What has to be redesigned to make it work and is there a better way >>> that works currently to mark an object as immutable after a certain >>> point/in certain region? >>> >>> Yichao Yu >>> >>> [1] https://bugs.llvm.org/show_bug.cgi?id=5441 >>> _______________________________________________ >>> LLVM Developers mailing list >>> llvm-dev at lists.llvm.org >>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>
Anna Thomas via llvm-dev
2017-Oct-31 21:07 UTC
[llvm-dev] Status of llvm.invariant.{start|end}
On Oct 31, 2017, at 3:50 PM, Anna Thomas via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote: On Oct 31, 2017, at 12:17 PM, Yichao Yu <yyc1992 at gmail.com<mailto:yyc1992 at gmail.com>> wrote: We at Azul have been using invariant.start for marking objects as immutable after a certain point. Also, upstream changes to teach relevant optimizations about invariant.start and end were added last year. With respect to store to load forwarding, this is handled in GVN. I think the test cases in test/Transforms/GVN/invariant.start.ll handle what you’re looking for. Hmm, I'm pretty sure I checked that. It seems that none of the test cases in there actually requires invariant.start for store-to-load forwarding? (they need `invariant.start|end` to not be marked as modifying the memory but should all work without the intrinsics.) AFAICT the simple case in the issue I linked still doesn't work ``` declare void @g(i8*) declare {}* @llvm.invariant.start.p0i8(i64, i8* nocapture) #0 define i8 @f() { %a = alloca i8 store i8 0, i8* %a %i = call {}* @llvm.invariant.start.p0i8(i64 1, i8* %a) call void @g(i8* %a) %r = load i8, i8* %a ret i8 %r } attributes #0 = { argmemonly nounwind } ``` Yes, you’re right. We don’t forward across the call even in presence of invariant.start. By definition, invariant.start represents constant physical memory, so I would think this is a legal transform to do. Ofcourse, this can lead to miscompiles if g is a special function that can modify %a in some way, but those are things the front end needs to identify. Just to clarify: If g can modify %a in some way, the front end needs to identify it and avoid adding invariant.start. Once the invariant.start has been added by the front end,this is a perfectly legal transform to do based on the LLVM spec. In fact we should be implementing this in LLVM, patches welcome :) Anna Hope this helps, Anna On Oct 29, 2017, at 9:01 PM, Yichao Yu via llvm-dev <llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org>> wrote: Hi, From LangRef, these intrinsics seems really useful for letting LLVM know about certain higher level immutability guarantee, e.g. for objects that are not allowed to be mutated after construction. However, it doesn't seem to work[1] and a quick code search suggests that there's not a single optimization pass that's currently using it for store to load forwarding, only very few that use it to eliminate stores. The issue linked is marked as resolved-later and mentioned that it "probably have to be redesigned before they work out right". What has to be redesigned to make it work and is there a better way that works currently to mark an object as immutable after a certain point/in certain region? Yichao Yu [1] https://bugs.llvm.org/show_bug.cgi?id=5441 _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev _______________________________________________ LLVM Developers mailing list llvm-dev at lists.llvm.org<mailto:llvm-dev at lists.llvm.org> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171031/83eb869e/attachment.html>