Hal Finkel via llvm-dev
2017-Jan-05 19:43 UTC
[llvm-dev] RFC: Allow readnone and readonly functions to throw exceptions
On 01/05/2017 01:20 PM, Sanjoy Das wrote:> Hi Hal, > > On Thu, Jan 5, 2017 at 11:10 AM, Hal Finkel via llvm-dev > <llvm-dev at lists.llvm.org> wrote: >> It is still only a function of its arguments, so it can be CSE'd. > That's a good example -- we can CSE it without worrying about the > memory state flowing in. > > In fact, if we have: > > *a = 10; > call @readnone_may_unwind() > *a = 20; > call @readnone_may_unwind() > *a = 30; > > then we can first transform this to: > > *a = 10; > call @readnone_may_unwind() > *a = 20; > call @readnone_may_unwind() nounwind // only on this call (since we > returned normally) > *a = 30; > > and then DSE: > > *a = 10; > call @readnone_may_unwind() > // *a = 20; > call @readnone_may_unwind() nounwind // only on this call > *a = 30; > > >> Also, if I have this: >> >> *a = 10; >> b = a_readnone_unwind_func(); >> *a = 10; >> >> I can still conclude that this last store is redundant and can be removed. I >> know that the readnone function does not touch it, and if it unwinds, than >> the later store is dead. If I know that &*a has not escaped to where an >> exception handler might access it, then I know that the first store than be >> removed. > That's not specific to readnone though, right? Even if the function > was readonly-mayunwind, the optimization would be legal.Yes, unless the readonly-mayunwind functions takes the memory as a parameter, in which case the latter sentence does not apply. -Hal> >> -Hal >> >> >> >> I don't think we'll do DSE in your example because the store isn't dead, >> it's visible along the invoke's unwind edge, and we don't need to change the >> semantics of readnone to see that. >> >> >> I’ve been wondering the same thing on Sanjoy’s example. >> >> — >> Mehdi >> >> >> -- >> Hal Finkel >> Lead, Compiler Technology and Programming Languages >> Leadership Computing Facility >> Argonne National Laboratory >> >> >> _______________________________________________ >> LLVM Developers mailing list >> llvm-dev at lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev >>-- Hal Finkel Lead, Compiler Technology and Programming Languages Leadership Computing Facility Argonne National Laboratory
Sanjoy Das via llvm-dev
2017-Jan-05 20:03 UTC
[llvm-dev] RFC: Allow readnone and readonly functions to throw exceptions
On Thu, Jan 5, 2017 at 11:43 AM, Hal Finkel <hfinkel at anl.gov> wrote:> > On 01/05/2017 01:20 PM, Sanjoy Das wrote: >> >> Hi Hal, >> >> On Thu, Jan 5, 2017 at 11:10 AM, Hal Finkel via llvm-dev >> <llvm-dev at lists.llvm.org> wrote: >>> >>> It is still only a function of its arguments, so it can be CSE'd. >> >> That's a good example -- we can CSE it without worrying about the >> memory state flowing in. >> >> In fact, if we have: >> >> *a = 10; >> call @readnone_may_unwind() >> *a = 20; >> call @readnone_may_unwind() >> *a = 30; >> >> then we can first transform this to: >> >> *a = 10; >> call @readnone_may_unwind() >> *a = 20; >> call @readnone_may_unwind() nounwind // only on this call (since we >> returned normally) >> *a = 30; >> >> and then DSE: >> >> *a = 10; >> call @readnone_may_unwind() >> // *a = 20; >> call @readnone_may_unwind() nounwind // only on this call >> *a = 30; >> >> >>> Also, if I have this: >>> >>> *a = 10; >>> b = a_readnone_unwind_func(); >>> *a = 10; >>> >>> I can still conclude that this last store is redundant and can be >>> removed. I >>> know that the readnone function does not touch it, and if it unwinds, >>> than >>> the later store is dead. If I know that &*a has not escaped to where an >>> exception handler might access it, then I know that the first store than >>> be >>> removed. >> >> That's not specific to readnone though, right? Even if the function >> was readonly-mayunwind, the optimization would be legal. > > Yes, unless the readonly-mayunwind functions takes the memory as a > parameter, in which case the latter sentence does not apply.I'm not a 100% sure I understand what you meant to say, but I don't think that part is specific to readonly either. Neither readonly nor readnone functions can escape pointers by writing them to memory (within their body). However, both readnone or readonly functions could resume with a pointer they take as an argument which the exception handler could read from. That is: void f(i32* %ptr) { // either readnone or readonly resume %ptr } void g() { %p = malloc() *%p = 20; // can't DSE this because ... f(%p) } ... we could have this further up the stack void h() { invoke g() to %normal unwind %unwind unwind: %ptr = landingpad assert(*%ptr == 20) }
Hal Finkel via llvm-dev
2017-Jan-05 20:05 UTC
[llvm-dev] RFC: Allow readnone and readonly functions to throw exceptions
On 01/05/2017 02:03 PM, Sanjoy Das wrote:> On Thu, Jan 5, 2017 at 11:43 AM, Hal Finkel <hfinkel at anl.gov> wrote: >> On 01/05/2017 01:20 PM, Sanjoy Das wrote: >>> Hi Hal, >>> >>> On Thu, Jan 5, 2017 at 11:10 AM, Hal Finkel via llvm-dev >>> <llvm-dev at lists.llvm.org> wrote: >>>> It is still only a function of its arguments, so it can be CSE'd. >>> That's a good example -- we can CSE it without worrying about the >>> memory state flowing in. >>> >>> In fact, if we have: >>> >>> *a = 10; >>> call @readnone_may_unwind() >>> *a = 20; >>> call @readnone_may_unwind() >>> *a = 30; >>> >>> then we can first transform this to: >>> >>> *a = 10; >>> call @readnone_may_unwind() >>> *a = 20; >>> call @readnone_may_unwind() nounwind // only on this call (since we >>> returned normally) >>> *a = 30; >>> >>> and then DSE: >>> >>> *a = 10; >>> call @readnone_may_unwind() >>> // *a = 20; >>> call @readnone_may_unwind() nounwind // only on this call >>> *a = 30; >>> >>> >>>> Also, if I have this: >>>> >>>> *a = 10; >>>> b = a_readnone_unwind_func(); >>>> *a = 10; >>>> >>>> I can still conclude that this last store is redundant and can be >>>> removed. I >>>> know that the readnone function does not touch it, and if it unwinds, >>>> than >>>> the later store is dead. If I know that &*a has not escaped to where an >>>> exception handler might access it, then I know that the first store than >>>> be >>>> removed. >>> That's not specific to readnone though, right? Even if the function >>> was readonly-mayunwind, the optimization would be legal. >> Yes, unless the readonly-mayunwind functions takes the memory as a >> parameter, in which case the latter sentence does not apply. > I'm not a 100% sure I understand what you meant to say, but I don't > think that part is specific to readonly either. Neither readonly nor > readnone functions can escape pointers by writing them to memory > (within their body). However, both readnone or readonly functions > could resume with a pointer they take as an argument which the > exception handler could read from.Agreed. Thanks again, Hal> That is: > > void f(i32* %ptr) { // either readnone or readonly > resume %ptr > } > > void g() { > %p = malloc() > *%p = 20; // can't DSE this because ... > f(%p) > } > > ... we could have this further up the stack > > void h() { > invoke g() to %normal unwind %unwind > unwind: > %ptr = landingpad > assert(*%ptr == 20) > }-- Hal Finkel Lead, Compiler Technology and Programming Languages Leadership Computing Facility Argonne National Laboratory