Dan Gohman via llvm-dev
2017-Oct-27 05:08 UTC
[llvm-dev] Infinite loops with no side effects
Hello, This email picks up the thread that to my knowledge was last discussed here: http://lists.llvm.org/pipermail/llvm-dev/2015-July/088103.html In brief, infinite loops containing no side effects produce undefined behavior in C++ (and C in some cases), however in other languages, they have fully defined behavior. LLVM's optimizer currently assumes that infinite loops eventually terminate in a few places, and will sometimes delete them in practice. There is currently no clean way to opt out of this behavior from languages where it's not valid. This is the subject of a long-standing LLVM bug: https://bugs.llvm.org/show_bug.cgi?id=965 I wrote a patch implementing Chandler's idea from the above thread, @llvm.sideeffect, a new intrinsic which is a no-op except that it tells the optimizer to behave as if there were side effects present: https://reviews.llvm.org/D38336 Similar results can be achieved with empty inline asms, however they tend to pessimize optimizations. The patch above allows all of the major optimizations to work in the presence of @llvm.sideeffect. One of the concerns raised is that front-ends would have to emit a lot of these intrinsics, potentially one in every loop, one in every function (due to opportunistic tail-call optimization), and one in front of every label reachable by goto or similar, if a front-end can't determine when they aren't needed. This is indeed a downside. It's mitigated in this patch by making sure that the major optimization passes aren't pessimized.>From the alternatives I've read, the most promising alternative is Reid'sproposal here: https://bugs.llvm.org/show_bug.cgi?id=965#c25 to make infinite loops defined by default, and add a "known to be productive" attribute to functions. It would be a more complex change, and could potentially require changes in out-of-tree codebases. And it would be suboptimal in some cases when cross-language inlining. However, it would solve the problem in a much less cluttered way. I'm willing to implement the LLVM portion of this if there's consensus that it's a better approach. Thoughts? Dan -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171026/f1177cbe/attachment.html>
David Majnemer via llvm-dev
2017-Oct-27 14:28 UTC
[llvm-dev] Infinite loops with no side effects
The two proposals have interesting upsides and downsides: Making it a property of the function makes a lot of sense because we don't need the power to say that loops A and B have different termination guarantees in the same function. Also, as you mention, it makes the front-end's job a lot easier because it just slaps the attribute down and calls it a day. I think the problem with the attribute (which is solved by the intrinsic) is that we would have to come up a very careful set of semantics for CFGs to make sure that hoisting wouldn't "break" things like: while (always_true_at_runtime) ; *(volatile int *)NULL = 0; doesn't turn into: *(volatile int *)NULL = 0; while (always_true_at_runtime) ; The intrinsic gives us a way of reifying the side effect in a semantically obvious way. In the same way that calls which are not nounwind have an implicit abnormal edge heading out of the function, this intrinsic basically makes it possible to add abnormal edges to the CFG without having to retrofit LLVM to *really* have abnormal edges. On Thu, Oct 26, 2017 at 10:08 PM, Dan Gohman via llvm-dev < llvm-dev at lists.llvm.org> wrote:> Hello, > > This email picks up the thread that to my knowledge was last discussed > here: > > http://lists.llvm.org/pipermail/llvm-dev/2015-July/088103.html > > In brief, infinite loops containing no side effects produce undefined > behavior in C++ (and C in some cases), however in other languages, they > have fully defined behavior. LLVM's optimizer currently assumes that > infinite loops eventually terminate in a few places, and will sometimes > delete them in practice. There is currently no clean way to opt out of this > behavior from languages where it's not valid. > > This is the subject of a long-standing LLVM bug: > > https://bugs.llvm.org/show_bug.cgi?id=965 > > I wrote a patch implementing Chandler's idea from the above thread, > @llvm.sideeffect, a new intrinsic which is a no-op except that it tells the > optimizer to behave as if there were side effects present: > > https://reviews.llvm.org/D38336 > > Similar results can be achieved with empty inline asms, however they tend > to pessimize optimizations. The patch above allows all of the major > optimizations to work in the presence of @llvm.sideeffect. > > One of the concerns raised is that front-ends would have to emit a lot of > these intrinsics, potentially one in every loop, one in every function (due > to opportunistic tail-call optimization), and one in front of every label > reachable by goto or similar, if a front-end can't determine when they > aren't needed. This is indeed a downside. It's mitigated in this patch by > making sure that the major optimization passes aren't pessimized. > > From the alternatives I've read, the most promising alternative is Reid's > proposal here: > > https://bugs.llvm.org/show_bug.cgi?id=965#c25 > > to make infinite loops defined by default, and add a "known to be > productive" attribute to functions. It would be a more complex change, and > could potentially require changes in out-of-tree codebases. And it would be > suboptimal in some cases when cross-language inlining. However, it would > solve the problem in a much less cluttered way. I'm willing to implement > the LLVM portion of this if there's consensus that it's a better approach. > > Thoughts? > > Dan > > > _______________________________________________ > 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/20171027/0e76e1d7/attachment-0001.html>
Hal Finkel via llvm-dev
2017-Oct-27 19:37 UTC
[llvm-dev] Infinite loops with no side effects
On 10/27/2017 12:08 AM, Dan Gohman via llvm-dev wrote:> Hello, > > This email picks up the thread that to my knowledge was last discussed > here: > > http://lists.llvm.org/pipermail/llvm-dev/2015-July/088103.html > <http://lists.llvm.org/pipermail/llvm-dev/2015-July/088103.html> > > In brief, infinite loops containing no side effects produce undefined > behavior in C++ (and C in some cases), however in other languages, > they have fully defined behavior. LLVM's optimizer currently assumes > that infinite loops eventually terminate in a few places, and will > sometimes delete them in practice. There is currently no clean way to > opt out of this behavior from languages where it's not valid. > > This is the subject of a long-standing LLVM bug: > > https://bugs.llvm.org/show_bug.cgi?id=965 > <https://bugs.llvm.org/show_bug.cgi?id=965> > > I wrote a patch implementing Chandler's idea from the above thread, > @llvm.sideeffect, a new intrinsic which is a no-op except that it > tells the optimizer to behave as if there were side effects present: > > https://reviews.llvm.org/D38336 <https://reviews.llvm.org/D38336> > > Similar results can be achieved with empty inline asms, however they > tend to pessimize optimizations. The patch above allows all of the > major optimizations to work in the presence of @llvm.sideeffect.I think that we should move forward with this approach (as may be obvious given that I've okay'd the patch). It's a lightweight solution, at least on LLVM's side of things, and does not prevent other solutions later.> > One of the concerns raised is that front-ends would have to emit a lot > of these intrinsics, potentially one in every loop, one in every > function (due to opportunistic tail-call optimization), and one in > front of every label reachable by goto or similar, if a front-end > can't determine when they aren't needed.This is a valid concern, however, I expect that most programs from higher-level languages will have well-structured loops, and it will be straightforward to emit the intrinsics.> This is indeed a downside. It's mitigated in this patch by making sure > that the major optimization passes aren't pessimized. > > From the alternatives I've read, the most promising alternative is > Reid's proposal here: > > https://bugs.llvm.org/show_bug.cgi?id=965#c25 > > to make infinite loops defined by default, and add a "known to be > productive" attribute to functions. It would be a more complex change, > and could potentially require changes in out-of-tree codebases. And it > would be suboptimal in some cases when cross-language inlining. > However, it would solve the problem in a much less cluttered way. I'm > willing to implement the LLVM portion of this if there's consensus > that it's a better approach.The problem is that it is not a function-level property, it is a per-loop property. This is even true in C. In C, we would need to mark loops that have source-level-constant controlling conditions, and only those loops, and allowed to be infinite. And, so, maybe we could use loop-level metadata, but that seems hard to place/preserve for unstructured loops (and, arguably, that's more important in C/C++ than in other languages). -Hal> > Thoughts? > > Dan > > > > _______________________________________________ > 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171027/761d6a42/attachment.html>
Reid Kleckner via llvm-dev
2017-Oct-27 19:51 UTC
[llvm-dev] Infinite loops with no side effects
Personally, I don't like the side effect intrinsic. It will pollute all the IR generated by non-C frontends. What most of these frontends really want is just a switch to disable a targeted set of optimizations. One thing I like about the function attribute idea is that it's conservatively correct to discard it when doing cross-language inlining. It just becomes something that C-family frontends need to remember to add to enable their special-case language rules, rather than something that non-C languages need to think about. Similar to the 'access', builtin vs nonbuiltin discussion happening in parallel, the attribute enables the optimization, rather than inhibiting it. On Fri, Oct 27, 2017 at 12:37 PM, Hal Finkel via llvm-dev < llvm-dev at lists.llvm.org> wrote:> > On 10/27/2017 12:08 AM, Dan Gohman via llvm-dev wrote: > > Hello, > > This email picks up the thread that to my knowledge was last discussed > here: > > http://lists.llvm.org/pipermail/llvm-dev/2015-July/088103.html > > In brief, infinite loops containing no side effects produce undefined > behavior in C++ (and C in some cases), however in other languages, they > have fully defined behavior. LLVM's optimizer currently assumes that > infinite loops eventually terminate in a few places, and will sometimes > delete them in practice. There is currently no clean way to opt out of this > behavior from languages where it's not valid. > > This is the subject of a long-standing LLVM bug: > > https://bugs.llvm.org/show_bug.cgi?id=965 > > I wrote a patch implementing Chandler's idea from the above thread, > @llvm.sideeffect, a new intrinsic which is a no-op except that it tells the > optimizer to behave as if there were side effects present: > > https://reviews.llvm.org/D38336 > > Similar results can be achieved with empty inline asms, however they tend > to pessimize optimizations. The patch above allows all of the major > optimizations to work in the presence of @llvm.sideeffect. > > > I think that we should move forward with this approach (as may be obvious > given that I've okay'd the patch). It's a lightweight solution, at least on > LLVM's side of things, and does not prevent other solutions later. > > > One of the concerns raised is that front-ends would have to emit a lot of > these intrinsics, potentially one in every loop, one in every function (due > to opportunistic tail-call optimization), and one in front of every label > reachable by goto or similar, if a front-end can't determine when they > aren't needed. > > > This is a valid concern, however, I expect that most programs from > higher-level languages will have well-structured loops, and it will be > straightforward to emit the intrinsics. > > This is indeed a downside. It's mitigated in this patch by making sure > that the major optimization passes aren't pessimized. > > From the alternatives I've read, the most promising alternative is Reid's > proposal here: > > https://bugs.llvm.org/show_bug.cgi?id=965#c25 > > to make infinite loops defined by default, and add a "known to be > productive" attribute to functions. It would be a more complex change, and > could potentially require changes in out-of-tree codebases. And it would be > suboptimal in some cases when cross-language inlining. However, it would > solve the problem in a much less cluttered way. I'm willing to implement > the LLVM portion of this if there's consensus that it's a better approach. > > > The problem is that it is not a function-level property, it is a per-loop > property. This is even true in C. In C, we would need to mark loops that > have source-level-constant controlling conditions, and only those loops, > and allowed to be infinite. And, so, maybe we could use loop-level > metadata, but that seems hard to place/preserve for unstructured loops > (and, arguably, that's more important in C/C++ than in other languages). > > -Hal > > > Thoughts? > > Dan > > > > _______________________________________________ > LLVM Developers mailing listllvm-dev at lists.llvm.orghttp://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev > > > -- > 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 > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20171027/27042a33/attachment.html>