Sanjoy Das via llvm-dev
2017-Feb-10 02:16 UTC
[llvm-dev] help me understand how nounwind attribute on functions works?
On Thu, Feb 9, 2017 at 8:41 AM, Reid Kleckner via llvm-dev <llvm-dev at lists.llvm.org> wrote:> On Wed, Feb 8, 2017 at 5:45 PM, Mehdi Amini <mehdi.amini at apple.com> wrote: >> >> What isn’t clear to me still is : why shouldn't this be transitive? >> In the example you’re showing, for a caller of f() in bar, what is the >> advantage of knowing that f() is nounwind if it an exception can still be >> thrown? What does it allow? > > > We know an exception cannot unwind out of f. An exception can be thrown > inside something that f calls, but it must be caught before it unwinds > beyond f.So perhaps a viable rule is that every CallInst in a nounwind function can be marked as nounwind (even though the callee for said CallInst can't be)? -- Sanjoy
Mehdi Amini via llvm-dev
2017-Feb-10 02:25 UTC
[llvm-dev] help me understand how nounwind attribute on functions works?
> On Feb 9, 2017, at 6:16 PM, Sanjoy Das <sanjoy at playingwithpointers.com> wrote: > > On Thu, Feb 9, 2017 at 8:41 AM, Reid Kleckner via llvm-dev > <llvm-dev at lists.llvm.org> wrote: >> On Wed, Feb 8, 2017 at 5:45 PM, Mehdi Amini <mehdi.amini at apple.com> wrote: >>> >>> What isn’t clear to me still is : why shouldn't this be transitive? >>> In the example you’re showing, for a caller of f() in bar, what is the >>> advantage of knowing that f() is nounwind if it an exception can still be >>> thrown? What does it allow? >> >> >> We know an exception cannot unwind out of f. An exception can be thrown >> inside something that f calls, but it must be caught before it unwinds >> beyond f. > > So perhaps a viable rule is that every CallInst in a nounwind function > can be marked as nounwind (even though the callee for said CallInst > can't be)?That should be an implicit assumption when a given function has the attribute. A `isCallNounwind(CallSite &C)` should be allowed to be implemented conceptually: return C.getCaller()->hasNounwindAttr() || C.getCaller()->hasNounwindAttr(); I’m still not sure what is LLVM doing differently for such calls thought? Why is it useful to know that a call is nounwind? I thought it is only useful to be able to turn invoke into calls, but what else? Thanks, — Mehdi
Sanjoy Das via llvm-dev
2017-Feb-10 02:37 UTC
[llvm-dev] help me understand how nounwind attribute on functions works?
On Thu, Feb 9, 2017 at 6:25 PM, Mehdi Amini <mehdi.amini at apple.com> wrote:> >> On Feb 9, 2017, at 6:16 PM, Sanjoy Das <sanjoy at playingwithpointers.com> wrote: >> >> On Thu, Feb 9, 2017 at 8:41 AM, Reid Kleckner via llvm-dev >> <llvm-dev at lists.llvm.org> wrote: >>> On Wed, Feb 8, 2017 at 5:45 PM, Mehdi Amini <mehdi.amini at apple.com> wrote: >>>> >>>> What isn’t clear to me still is : why shouldn't this be transitive? >>>> In the example you’re showing, for a caller of f() in bar, what is the >>>> advantage of knowing that f() is nounwind if it an exception can still be >>>> thrown? What does it allow? >>> >>> >>> We know an exception cannot unwind out of f. An exception can be thrown >>> inside something that f calls, but it must be caught before it unwinds >>> beyond f. >> >> So perhaps a viable rule is that every CallInst in a nounwind function >> can be marked as nounwind (even though the callee for said CallInst >> can't be)? > > > That should be an implicit assumption when a given function has the attribute. A `isCallNounwind(CallSite &C)` should be allowed to be implemented conceptually: return C.getCaller()->hasNounwindAttr() || C.getCaller()->hasNounwindAttr(); > > I’m still not sure what is LLVM doing differently for such calls thought? Why is it useful to know that a call is nounwind? > I thought it is only useful to be able to turn invoke into calls, but what else?Because nounwind functions do not have an implicit throw edge, you can do things like: call @readnone_nounwind() int k = a / b; ==> int k = a / b; call @readnone_nounwind() Unfortunately the readnone (or readonly) is important in LLVM today; since the informal semantics today are readnone or readonly functions can't exit(0) or infloop. -- Sanjoy> > Thanks, > > — > Mehdi >