Sanjoy Das via llvm-dev
2017-Jan-03 17:59 UTC
[llvm-dev] RFC: Allow readnone and readonly functions to throw exceptions
Hi Michael, On Mon, Jan 2, 2017 at 11:49 PM, Michael Kuperstein <michael.kuperstein at gmail.com> wrote:> This sounds right to me. > > IIUC, historically, readonly and readnone are meant to model the "pure" and > "const" GCC attributes. These attributes make pretty strong guarantees: > > "[a pure] function can be subject to common subexpression elimination and > loop optimization just as an arithmetic operator would be. These functions > should be declared with the attribute pure [...] Interesting non-pure > functions are functions with infinite loops or those depending on volatile > memory or other system resource, that may change between two consecutive > calls (such as feof in a multithreading environment)." > > In particular, pure/const imply termination - something that's not entirely > clear w.r.t readonly. However, apparently, they don't imply nothrow. I've > actually always thought they *do* imply it - and said so on-list :-) - but > it looks like GCC itself doesn't interpret them that way. E.g. see John > Regher's example here: https://t.co/REzy5m1tT3 > So there's at least one use-case for possibly throwing readonly/readnone.One important thing to note then: clang marks const and pure functions as nounwind *explicitly*. That needs to be fixed. https://godbolt.org/g/SMF4C9> As a side note, I'm slightly less optimistic about the amount of required > code fixes. One thing that comes to mind is that we need to make sure we > mark all(?) the intrinsics currently marked readonly/argmemonly/readnone as > nothrow. This should be mostly mechanical, I hope, but it's a decent amount > of churn.The behavior around intrinsics today is that they're implicitly marked NoUnwind unless they're specifically annotated as [Throws], of which there are very few instances (statepoints, stackmap, patchpoint, coro_*). My intent was to (document and) keep this behavior. -- Sanjoy
Michael Kuperstein via llvm-dev
2017-Jan-03 18:47 UTC
[llvm-dev] RFC: Allow readnone and readonly functions to throw exceptions
On Tue, Jan 3, 2017 at 9:59 AM, Sanjoy Das via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hi Michael, > > On Mon, Jan 2, 2017 at 11:49 PM, Michael Kuperstein > <michael.kuperstein at gmail.com> wrote: > > This sounds right to me. > > > > IIUC, historically, readonly and readnone are meant to model the "pure" > and > > "const" GCC attributes. These attributes make pretty strong guarantees: > > > > "[a pure] function can be subject to common subexpression elimination and > > loop optimization just as an arithmetic operator would be. These > functions > > should be declared with the attribute pure [...] Interesting non-pure > > functions are functions with infinite loops or those depending on > volatile > > memory or other system resource, that may change between two consecutive > > calls (such as feof in a multithreading environment)." > > > > In particular, pure/const imply termination - something that's not > entirely > > clear w.r.t readonly. However, apparently, they don't imply nothrow. I've > > actually always thought they *do* imply it - and said so on-list :-) - > but > > it looks like GCC itself doesn't interpret them that way. E.g. see John > > Regher's example here: https://t.co/REzy5m1tT3 > > So there's at least one use-case for possibly throwing readonly/readnone. > > One important thing to note then: clang marks const and pure functions > as nounwind *explicitly*. That needs to be fixed. > > https://godbolt.org/g/SMF4C9 > >Hah. So it does. Eric, this was originally your change. Do I understand GCC's behavior incorrectly?> > As a side note, I'm slightly less optimistic about the amount of required > > code fixes. One thing that comes to mind is that we need to make sure we > > mark all(?) the intrinsics currently marked readonly/argmemonly/readnone > as > > nothrow. This should be mostly mechanical, I hope, but it's a decent > amount > > of churn. > > The behavior around intrinsics today is that they're implicitly marked > NoUnwind unless they're specifically annotated as [Throws], of which > there are very few instances (statepoints, stackmap, patchpoint, > coro_*). My intent was to (document and) keep this behavior. > >Oh, ok, this makes a lot of sense.> -- Sanjoy > _______________________________________________ > LLVM Developers mailing list > 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/20170103/ff717a93/attachment.html>
Daniel Berlin via llvm-dev
2017-Jan-03 19:52 UTC
[llvm-dev] RFC: Allow readnone and readonly functions to throw exceptions
On Tue, Jan 3, 2017 at 10:47 AM, Michael Kuperstein via llvm-dev < llvm-dev at lists.llvm.org> wrote:> > > On Tue, Jan 3, 2017 at 9:59 AM, Sanjoy Das via llvm-dev < > llvm-dev at lists.llvm.org> wrote: > >> Hi Michael, >> >> On Mon, Jan 2, 2017 at 11:49 PM, Michael Kuperstein >> <michael.kuperstein at gmail.com> wrote: >> > This sounds right to me. >> > >> > IIUC, historically, readonly and readnone are meant to model the "pure" >> and >> > "const" GCC attributes. These attributes make pretty strong guarantees: >> > >> > "[a pure] function can be subject to common subexpression elimination >> and >> > loop optimization just as an arithmetic operator would be. These >> functions >> > should be declared with the attribute pure [...] Interesting non-pure >> > functions are functions with infinite loops or those depending on >> volatile >> > memory or other system resource, that may change between two consecutive >> > calls (such as feof in a multithreading environment)." >> > >> > In particular, pure/const imply termination - something that's not >> entirely >> > clear w.r.t readonly. However, apparently, they don't imply nothrow. >> I've >> > actually always thought they *do* imply it - and said so on-list :-) - >> but >> > it looks like GCC itself doesn't interpret them that way. E.g. see John >> > Regher's example here: https://t.co/REzy5m1tT3 >> > So there's at least one use-case for possibly throwing >> readonly/readnone. >> >> One important thing to note then: clang marks const and pure functions >> as nounwind *explicitly*. That needs to be fixed. >> >> https://godbolt.org/g/SMF4C9 >> >> > Hah. So it does. > Eric, this was originally your change. Do I understand GCC's behavior > incorrectly? >No, but I was in the office when Kenny wrote ipa-pure-const, which is the equivalent to llvm's pass to find function attributions, and it mostly wasn't thought about. GCC isn't as consistent as one may think here. /* Non-looping const functions always return normally. Otherwise the call might not return or have side-effects that forbids hoisting possibly trapping expressions before it. */ int flags = gimple_call_flags (stmt); if (!(flags & ECF_CONST) || (flags & ECF_LOOPING_CONST_OR_PURE)) BB_MAY_NOTRETURN (block) = 1; } It also, for example, will do this: double cos (double) __attribute__ ((const)); double sin (double) __attribute__ ((const)); double f(double a) { double b; double c,d; double (*fp) (double) __attribute__ ((const)); /* Partially redundant call */ if (a < 2.0) { fp = sin; c = fp (a); } else { c = 1.0; fp = cos; } d = fp (a); return d + c; } into double cos (double) __attribute__ ((const)); double sin (double) __attribute__ ((const)); double f(double a) { double b; double c,d; double (*fp) (double) __attribute__ ((const)); /* Partially redundant call */ if (a < 2.0) { fp = sin; c = fp (a); } else { c = 1.0; fp = cos; temp = fp(a) } d = phi(c, temp) return d + c; } This only works if the second call to sin is guaranteed not to throw, no? In any case, optimizations check throwing separately from pure/const, but i'm not sure it's well thought out here. Note that GCC also has a notion of possibly infinite looping pure/const as well:) -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170103/b14132a1/attachment.html>