Reid Kleckner via llvm-dev
2015-Nov-11 19:06 UTC
[llvm-dev] [RFC] A new intrinsic, `llvm.blackbox`, to explicitly prevent constprop, die, etc optimizations
On Wed, Nov 11, 2015 at 10:41 AM, Daniel Berlin <dberlin at dberlin.org> wrote:> On Wed, Nov 11, 2015 at 10:32 AM, Reid Kleckner <rnk at google.com> wrote: > >> I think the idea is to model the intrinsic as a normal external function >> call: >> > - Can read/write escaped memory >> > - Escapes pointer args >> - Functionattrs cannot infer anything about it >> - Returns a pointer which may alias any escaped data >> >> As you point out so nicely, there is already a list of stuff that > external function calls may do, but we may be able to prove things about > them anyway due to attributes, etc. > > So it's not just an external function call, it's a super-magic one. >Right, an external function, with a definition that the compiler will never find.> Now, can we handle that? > Sure. > > For example, i can move external function calls if i can prove things > about their dependencies, and the above list is not sufficient to prevent > me from moving (or PRE'ing) most of the blackbox calls that just take > normal non-pointer args. > Is that going to be okay? > > (Imagine, for example, LTO modes where i can guarantee i have the entire > program, etc. > You still want blackbox to be magically special in these modes, even > though nothing else is). >Sure, the compiler can reorder all the memory accesses to non-escaped memory as it sees fit across the barrier. That's part of the normal modelling of external calls. I don't know how you could CSE it, though. Any call you can't reason about can always use inline asm to talk to external devices or issue a write syscall. I don't know how you could practically deploy a super-duper LTO mode that doesn't allow that as part of its model. The following CFG simplification would be legal, as it also fits the normal model of an external call: if (cond) y =llvm.blackbox(x) else y = llvm.blackbox(x) --> y = llvm.blackbox(x) I don't see how this is special. It just provides an overloaded intrinsic whose definition we promise to never reason about. Other than that it follows the same familiar rules that function calls do. -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151111/392154e8/attachment.html>
Daniel Berlin via llvm-dev
2015-Nov-11 19:13 UTC
[llvm-dev] [RFC] A new intrinsic, `llvm.blackbox`, to explicitly prevent constprop, die, etc optimizations
On Wed, Nov 11, 2015 at 11:06 AM, Reid Kleckner <rnk at google.com> wrote:> On Wed, Nov 11, 2015 at 10:41 AM, Daniel Berlin <dberlin at dberlin.org> > wrote: > >> On Wed, Nov 11, 2015 at 10:32 AM, Reid Kleckner <rnk at google.com> wrote: >> >>> I think the idea is to model the intrinsic as a normal external function >>> call: >>> >> - Can read/write escaped memory >>> >> - Escapes pointer args >>> - Functionattrs cannot infer anything about it >>> - Returns a pointer which may alias any escaped data >>> >>> As you point out so nicely, there is already a list of stuff that >> external function calls may do, but we may be able to prove things about >> them anyway due to attributes, etc. >> >> So it's not just an external function call, it's a super-magic one. >> > > Right, an external function, with a definition that the compiler will > never find. > > >> Now, can we handle that? >> Sure. >> >> For example, i can move external function calls if i can prove things >> about their dependencies, and the above list is not sufficient to prevent >> me from moving (or PRE'ing) most of the blackbox calls that just take >> normal non-pointer args. >> Is that going to be okay? >> >> (Imagine, for example, LTO modes where i can guarantee i have the entire >> program, etc. >> You still want blackbox to be magically special in these modes, even >> though nothing else is). >> > > Sure, the compiler can reorder all the memory accesses to non-escaped > memory as it sees fit across the barrier. That's part of the normal > modelling of external calls. > > I don't know how you could CSE it, though. >You'd have to make sure everything you ever built in LLVM handled this particular intrinsic specially.> Any call you can't reason about >can always use inline asm to talk to external devices or issue a write> syscall. >Heck, i could even reason about inline asm if i wanted to ;-). My point is that this call is super special compared to all other calls, and literally everything in LLVM has to understand that. The liklihood of subtle bugs being introduced in functionality (IE analysis/etc doing the wrong thing because it is not special cased) seems super high to me.> I don't know how you could practically deploy a super-duper LTO mode that > doesn't allow that as part of its model. >Sure.> > The following CFG simplification would be legal, as it also fits the > normal model of an external call: > if (cond) y =llvm.blackbox(x) > else y = llvm.blackbox(x) > --> > y = llvm.blackbox(x) > > I don't see how this is special. It just provides an overloaded intrinsic > whose definition we promise to never reason about. Other than that it > follows the same familiar rules that function calls do. >You have now removed some conditional evaluation and jumps. those would normally take benchmark time. Why is that okay? -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151111/d1b7dff5/attachment-0001.html>
Alex Elsayed via llvm-dev
2015-Nov-11 21:01 UTC
[llvm-dev] [RFC] A new intrinsic, `llvm.blackbox`, to explicitly prevent constprop, die, etc optimizations
On Wed, 11 Nov 2015 11:13:43 -0800, Daniel Berlin via llvm-dev wrote: <snip for gmane>> Heck, i could even reason about inline asm if i wanted to ;-). > > My point is that this call is super special compared to all other > calls, > and literally everything in LLVM has to understand that. > The liklihood of subtle bugs being introduced in functionality (IE > analysis/etc doing the wrong thing because it is not special cased) > seems super high to me.I do agree this is a concern.>> I don't know how you could practically deploy a super-duper LTO mode >> that doesn't allow that as part of its model. >> >> > Sure. > > >> The following CFG simplification would be legal, as it also fits the >> normal model of an external call: >> if (cond) y =llvm.blackbox(x) >> else y = llvm.blackbox(x) >> --> >> y = llvm.blackbox(x) >> >> I don't see how this is special. It just provides an overloaded >> intrinsic whose definition we promise to never reason about. Other than >> that it follows the same familiar rules that function calls do. >> >> > You have now removed some conditional evaluation and jumps. those > would normally take benchmark time. > Why is that okay?Because the original post in terms of wanting to inhibit specific optimizations was a flawed way of describing the problem. Reid's explanation of "an external function that LLVM is not allowed to reason about the body of" is a much better explanation, as a good benchmark will place llvm.blackbox() exactly where real code would call, say, getrandom() (on input) or printf() (on output). However, as the function call overhead of said external function isn't part of the _developer's_ code, and not something they can make faster in case of slow results, it's not relevant to the benchmarks - thus, using an _actual_ external function is suboptimal, even leaving aside that with LTO and such, llvm may STILL infer things about such functions, obviating the benchark. Perhaps the best explanation is that it's about *simulating the existence* of a "perfectly efficient" external world.