From java at stefan-marr.de Sun Sep 2 21:54:22 2018 From: java at stefan-marr.de (Stefan Marr) Date: Sun, 2 Sep 2018 22:54:22 +0100 Subject: Any known changes in Graal around sin/sqrt/exp? Message-ID: <80F27F12-1BBB-4C64-9333-7461E1BFCAB3@stefan-marr.de> Hi: After updating to >1.0.0-rc5 from previously 0.33, I have a benchmark that now takes more than 4 times as much execution time on Graal core. Before investigating this further, I wanted to ask whether there are any recent changes around the handling of math functions such as sin, sqrt, and exp. A look at IGV seems to indicate that either something didn?t get recognized as a constant or some branches can?t be eliminated (or got added). I put some IGV screenshots here: https://gist.github.com/smarr/5369b4fa9685b1886fd5402ce9d2e0f2 Any idea whether something that could be related to this was changed? Thank you Stefan -- Stefan Marr School of Computing, University of Kent http://stefan-marr.de/research/ From java at stefan-marr.de Sun Sep 2 21:59:31 2018 From: java at stefan-marr.de (Stefan Marr) Date: Sun, 2 Sep 2018 22:59:31 +0100 Subject: Update Report Truffle 0.33 to 1.0.0-rc5 Message-ID: Hi: Thought I share same thoughts on my latest Truffle update. It took me quite a while to update, because some of my patches to Truffle needed major revisions or reimplementation to account for some new features in Truffle. As you may know, I have been maintaining patches on top of Truffle for the last three years. They revolve mostly around support for more dynamic instrumentation and advanced debugging features. # Now unnecessary patches The good news is that I was finally able to drop some custom patches. ## Node.notifyInserted(.) This method is apparently already there since 0.27, but I didn't notice before. It allows me to drop one of my earliest patches to insert wrapper nodes for newly inserted subtrees. Thank you. ## InstrumentableNode.hasTag(.) This new interface and its hasTag(.) method make it unnecessary for me to add an isTaggedWith(.,.) method to Instrument. ## Thread-safety checks I used to remove assertions in the PolyglotEngine that made sure it was only used from a specific thread. Seems like this idea was dropped, which means I don't need to hack out these checks any more :) # Still maintained patches However, I still maintain a few patches, I consider more generally useful. So, perhaps the ideas underlying them could be picked up at some point. ## Java Run-Time condition for Breakpoints While guest-language conditions have been supported from early on, I do need breakpoint conditions on the interpreter level, and therefore got the support for a simple condition in Java, too: https://github.com/smarr/truffle/commit/96253f73ee6243cd15222a0eae095b0e00620b36 ## Advanced Breakpointing and Stepping I use tags for advance breakpoints, for instance on thread creation, on joining a fork join task, or sending an actor message: https://github.com/smarr/truffle/commit/d448d9c2af94c7f9d771139123d96209a10361e1 I use a stepping strategy to step until the next node with a given tag. This is very useful when I can't statically determine the target of a specific stepping operation, but I know that it has to be of a specific kind. I use this for instance to trigger a breakpoint when an async. message/callback is starting to execute, or just before a method returns that is going to be used to resolve a promise. Highly useful to step through async. code. https://github.com/smarr/truffle/commit/7689d6f383621959d357dfe492bcee85ae3eb466 Much of this depends on being able to set breakpoints precisely (with line, column, length, and tag). So, I also needed to add support for that. Currently, Truffle tries to find a best match, perhaps based on column and line, which isn't precise enough for my use case: https://github.com/smarr/truffle/commit/3c68e3dcffb3beab3e537ce5ac8e61a78c6b449d These last three points where the major elements that needed revision for my Truffle updated, because the related Truffle code was changed substantially, which means I needed to completely reimplement my patches. # Other notes on the update Beside rewriting my custom patches, the change that required most work was likely going from @Instrumentable to @GenerateWrapper: https://github.com/smarr/SOMns/pull/266/commits/7c21cda8d69ac479dfa0d838061a049fb02311ce To make this work nicely, I had to change a couple of things around. One problem with the notion of wrappers is that it is rather complicated to ensure that they always have the right type. The type is constrained on the one side by the field containing the child node, and on the other side, by the node that is actually wrapped. So, there is a tension between having few very general wrappers, and the specifics one might want to use in some node. It requires quite a bit of care to have a more specific field type for the child node and make everything work out correctly. Not sure what one could do about this, but it sounds like something that would deserve some general guideline and recommendation about how to structure the tree of nodes one has in a language. Though, I don't really know what one would recommend. I dealt with my nodes mostly on a case-by-case basis. The language interop support is something I haven't invested much time in yet. So, the fact that the old testing infrastructure is gone is somewhat unfortunate, because this means my interop support is now untested. Adopting the basic bits of the Graal SDK, and switching away from PolyglotEngine was comparably simple. Though, I didn't build a full SDK-style launcher. In an other email, I mentioned some compilation issues, but I suppose those are mostly Graal issues. For the curious, the SOMns PR for the update is here: https://github.com/smarr/SOMns/pull/266 Best regards Stefan -- Stefan Marr School of Computing, University of Kent http://stefan-marr.de/research/ From christian.humer at gmail.com Mon Sep 3 10:12:51 2018 From: christian.humer at gmail.com (Christian Humer) Date: Mon, 3 Sep 2018 11:12:51 +0100 Subject: Update Report Truffle 0.33 to 1.0.0-rc5 In-Reply-To: References: Message-ID: Hi Stefan, Thanks a lot for the report. I've added a few notes. > ## Java Run-Time condition for Breakpoints > > While guest-language conditions have been supported from early on, > I do need breakpoint conditions on the interpreter level, and therefore got > the support for a simple condition in Java, too: > https://github.com/smarr/truffle/commit/96253f73ee6243cd15222a0eae095b0e00620b36 I remember discussing this long time ago. That patch exposes PE to the debugging API user. I wanted to avoid this to reduce complexity for debugging protocol implementers. I think it would be best to discuss some use-cases, to find out whether a generic feature like this really is necessary. > ## Advanced Breakpointing and Stepping > > I use tags for advance breakpoints, for instance on thread creation, on joining > a fork join task, or sending an actor message: > https://github.com/smarr/truffle/commit/d448d9c2af94c7f9d771139123d96209a10361e1 > > I use a stepping strategy to step until the next node with a given tag. > This is very useful when I can't statically determine the target of a specific > stepping operation, but I know that it has to be of a specific kind. > I use this for instance to trigger a breakpoint when an async. message/callback > is starting to execute, or just before a method returns that is going to be > used to resolve a promise. Highly useful to step through async. code. We will likely need such a feature for async/wait breakpoints in Chrome Inspector support as well. (cc)Martin, please make sure we also support Stefans use-cases when we work on this. > One problem with the notion of wrappers is that it is rather complicated to ensure that they always have the right type. This is a long time issue we also had with the old instrumentation API. The general rule of thumb is to generate a new wrapper for all nodes that declare new public API like execute methods or meta-data accessors. > The language interop support is something I haven't invested much time in yet. > So, the fact that the old testing infrastructure is gone is somewhat > unfortunate, because this means my interop support is now untested. Please consider adopting the new TCK: https://github.com/oracle/graal/blob/master/truffle/docs/TCK.md It is more flexible as it allows to enumerate all language constructs to be tested. > Adopting the basic bits of the Graal SDK, and switching away from PolyglotEngine > was comparably simple. Though, I didn't build a full SDK-style launcher. FYI: You may also use our language launcher framework here: https://github.com/oracle/graal/tree/master/sdk/src/org.graalvm.launcher/src/org/graalvm/launcher It only depends on the SDK and language command line options are fully customizable. It adds commands flags like --jvm or --polyglot. - Christian Humer On Mon, Sep 3, 2018 at 12:00 AM Stefan Marr wrote: > Hi: > > Thought I share same thoughts on my latest Truffle update. > > It took me quite a while to update, because some of my patches to Truffle > needed > major revisions or reimplementation to account for some new features in > Truffle. > > As you may know, I have been maintaining patches on top of Truffle > for the last three years. They revolve mostly around support for more > dynamic > instrumentation and advanced debugging features. > > > # Now unnecessary patches > > The good news is that I was finally able to drop some custom patches. > > ## Node.notifyInserted(.) > > This method is apparently already there since 0.27, but I didn't notice > before. > It allows me to drop one of my earliest patches to insert wrapper nodes for > newly inserted subtrees. Thank you. > > ## InstrumentableNode.hasTag(.) > > This new interface and its hasTag(.) method make it unnecessary for me to > add > an isTaggedWith(.,.) method to Instrument. > > ## Thread-safety checks > > I used to remove assertions in the PolyglotEngine that made sure it was > only > used from a specific thread. Seems like this idea was dropped, which means > I > don't need to hack out these checks any more :) > > > # Still maintained patches > > However, I still maintain a few patches, I consider more generally useful. > So, perhaps the ideas underlying them could be picked up at some point. > > ## Java Run-Time condition for Breakpoints > > While guest-language conditions have been supported from early on, > I do need breakpoint conditions on the interpreter level, and therefore got > the support for a simple condition in Java, too: > > https://github.com/smarr/truffle/commit/96253f73ee6243cd15222a0eae095b0e00620b36 > > ## Advanced Breakpointing and Stepping > > I use tags for advance breakpoints, for instance on thread creation, on > joining > a fork join task, or sending an actor message: > > https://github.com/smarr/truffle/commit/d448d9c2af94c7f9d771139123d96209a10361e1 > > I use a stepping strategy to step until the next node with a given tag. > This is very useful when I can't statically determine the target of a > specific > stepping operation, but I know that it has to be of a specific kind. > I use this for instance to trigger a breakpoint when an async. > message/callback > is starting to execute, or just before a method returns that is going to be > used to resolve a promise. Highly useful to step through async. code. > > > https://github.com/smarr/truffle/commit/7689d6f383621959d357dfe492bcee85ae3eb466 > > Much of this depends on being able to set breakpoints precisely (with > line, column, length, and tag). > So, I also needed to add support for that. Currently, Truffle tries to > find a > best match, perhaps based on column and line, which isn't precise enough > for > my use case: > > > https://github.com/smarr/truffle/commit/3c68e3dcffb3beab3e537ce5ac8e61a78c6b449d > > These last three points where the major elements that needed revision for > my Truffle updated, because the related Truffle code was changed > substantially, > which means I needed to completely reimplement my patches. > > > # Other notes on the update > > Beside rewriting my custom patches, the change that required most work was > likely going from @Instrumentable to @GenerateWrapper: > https://github.com/smarr/SOMns/pull/266/commits/7c21cda8d69ac479dfa0d838061a049fb02311ce > > To make this work nicely, I had to change a couple of things around. > One problem with the notion of wrappers is that it is rather complicated to > ensure that they always have the right type. > The type is constrained on the one side by the field containing the child > node, > and on the other side, by the node that is actually wrapped. > So, there is a tension between having few very general wrappers, and the > specifics one might want to use in some node. > It requires quite a bit of care to have a more specific field type for the > child node and make everything work out correctly. > Not sure what one could do about this, but it sounds like something that > would deserve some general guideline and recommendation about how to > structure > the tree of nodes one has in a language. Though, I don't really know what > one > would recommend. I dealt with my nodes mostly on a case-by-case basis. > > The language interop support is something I haven't invested much time in > yet. > So, the fact that the old testing infrastructure is gone is somewhat > unfortunate, because this means my interop support is now untested. > > Adopting the basic bits of the Graal SDK, and switching away from > PolyglotEngine > was comparably simple. Though, I didn't build a full SDK-style launcher. > > In an other email, I mentioned some compilation issues, but I suppose > those are mostly Graal issues. > > For the curious, the SOMns PR for the update is here: > https://github.com/smarr/SOMns/pull/266 > > Best regards > Stefan > > -- > Stefan Marr > School of Computing, University of Kent > http://stefan-marr.de/research/ > > > From Martin.Entlicher at oracle.com Mon Sep 3 13:55:31 2018 From: Martin.Entlicher at oracle.com (Martin Entlicher) Date: Mon, 3 Sep 2018 15:55:31 +0200 Subject: Update Report Truffle 0.33 to 1.0.0-rc5 In-Reply-To: References: Message-ID: <4e3f8c70-9fdb-28b5-2d56-1bad03b62136@oracle.com> Thanks Stefan, I'm adding few comments... On 3.9.2018 12:12, Christian Humer wrote: > Hi Stefan, > > Thanks a lot for the report. I've added a few notes. > > > ## Java Run-Time condition for Breakpoints > > > > While guest-language conditions have been supported from early on, > > I do need breakpoint conditions on the interpreter level, and > therefore got > > the support for a simple condition in Java, too: > > > https://github.com/smarr/truffle/commit/96253f73ee6243cd15222a0eae095b0e00620b36 > > > I remember discussing this long time ago. That patch exposes PE to the > debugging API user. > I wanted to avoid this to reduce complexity for debugging protocol > implementers. > I think it would be best to discuss some use-cases, to find out > whether a generic feature like this really is necessary. This can be a way how to extend the debugging logic. But it looks strange to me, that SimpleCondition.evaluate() does not take any context information. I'm also curious about the use-cases and about how a typical Java condition might look like. > > > ## Advanced Breakpointing and Stepping > > > >?I use tags for advance breakpoints, for instance on thread creation, > on joining > >?a fork join task, or sending an actor message: > > > https://github.com/smarr/truffle/commit/d448d9c2af94c7f9d771139123d96209a10361e1 > We use SourceElement enum to abstract the Tag and to limit the set of tags that can be used in debugging. So far we support StatementTag and ExpressionTag only. Use of a non-standard tag would limit debugging to those languages that provide such tag. It might be easier to patch just the SourceElement with your additional tags. > > > >?I use a stepping strategy to step until the next node with a given tag. > >?This is very useful when I can't statically determine the target of > a specific > >?stepping operation, but I know that it has to be of a specific kind. > >?I use this for instance to trigger a breakpoint when an async. > message/callback > >?is starting to execute, or just before a method returns that is > going to be > >?used to resolve a promise. Highly useful to step through async. code. > > We will likely need such a feature for async/wait breakpoints in > Chrome Inspector support as well. > (cc)Martin, please make sure we also support Stefans use-cases when we > work on this. If you have SourceElement for the tag, then the only difference from the existing prepareStepInto/Over(StepConfig stepConfig) is a Thread. But it looks a bit strange to me to submit steps from SuspendedEvent into other threads. If we add API for this, it will likely be the DebuggerSession.suspend(Thread t) (which is package-private now), or something similar. In general, when pausing different threads, you might not have any SuspendedEvent. I can imagine that the suspend will take SourceElement(s) as an argument. However, where do you find the Thread from, to enter the async call? It can also be the current thread (in case of JavaScript, for instance). There can also be several async calls scheduled. > Much of this depends on being able to set breakpoints precisely (with line, column, length, and tag). > So, I also needed to add support for that. Currently, Truffle tries to find a > best match, perhaps based on column and line, which isn't precise enough for > my use case: > > https://github.com/smarr/truffle/commit/3c68e3dcffb3beab3e537ce5ac8e61a78c6b449d When debugging expressions it happens that there are sections with the same tag starting or ending on the same position. The section length is a way to distinguish that. Expression debugging is not used much in practice yet, but we could consider adding a way to specify it precisely. Thanks, Martin > > > One problem with the notion of wrappers is that it is rather > complicated to ensure that they always have the right type. > > This is a long time issue we also had with the old instrumentation API. > The general rule of thumb is to generate a new wrapper for all nodes > that declare new public API like execute methods or meta-data accessors. > > > The language interop support is something I haven't invested much > time in yet. > > So, the fact that the old testing infrastructure is gone is somewhat > > unfortunate, because this means my interop support is now untested. > > Please consider adopting the new TCK: > https://github.com/oracle/graal/blob/master/truffle/docs/TCK.md > > It is more flexible as it allows to enumerate all language constructs > to be tested. > > > Adopting the basic bits of the Graal SDK, and switching away from > PolyglotEngine > > was comparably simple. Though, I didn't build a full SDK-style launcher. > > FYI: You may also use our language launcher framework here: > https://github.com/oracle/graal/tree/master/sdk/src/org.graalvm.launcher/src/org/graalvm/launcher > > It only depends on the SDK and language command line options are fully > customizable. It adds commands flags like --jvm or --polyglot. > > - Christian Humer > > > > On Mon, Sep 3, 2018 at 12:00 AM Stefan Marr > wrote: > > Hi: > > Thought I share same thoughts on my latest Truffle update. > > It took me quite a while to update, because some of my patches to > Truffle needed > major revisions or reimplementation to account for some new > features in Truffle. > > As you may know, I have been maintaining patches on top of Truffle > for the last three years. They revolve mostly around support for > more dynamic > instrumentation and advanced debugging features. > > > # Now unnecessary patches > > The good news is that I was finally able to drop some custom patches. > > ## Node.notifyInserted(.) > > This method is apparently already there since 0.27, but I didn't > notice before. > It allows me to drop one of my earliest patches to insert wrapper > nodes for > newly inserted subtrees. Thank you. > > ## InstrumentableNode.hasTag(.) > > This new interface and its hasTag(.) method make it unnecessary > for me to add > an isTaggedWith(.,.) method to Instrument. > > ## Thread-safety checks > > I used to remove assertions in the PolyglotEngine that made sure > it was only > used from a specific thread. Seems like this idea was dropped, > which means I > don't need to hack out these checks any more :) > > > # Still maintained patches > > However, I still maintain a few patches, I consider more generally > useful. > So, perhaps the ideas underlying them could be picked up at some > point. > > ## Java Run-Time condition for Breakpoints > > While guest-language conditions have been supported from early on, > I do need breakpoint conditions on the interpreter level, and > therefore got > the support for a simple condition in Java, too: > https://github.com/smarr/truffle/commit/96253f73ee6243cd15222a0eae095b0e00620b36 > > > ## Advanced Breakpointing and Stepping > > I use tags for advance breakpoints, for instance on thread > creation, on joining > a fork join task, or sending an actor message: > https://github.com/smarr/truffle/commit/d448d9c2af94c7f9d771139123d96209a10361e1 > > > I use a stepping strategy to step until the next node with a given > tag. > This is very useful when I can't statically determine the target > of a specific > stepping operation, but I know that it has to be of a specific kind. > I use this for instance to trigger a breakpoint when an async. > message/callback > is starting to execute, or just before a method returns that is > going to be > used to resolve a promise. Highly useful to step through async. code. > > https://github.com/smarr/truffle/commit/7689d6f383621959d357dfe492bcee85ae3eb466 > > > Much of this depends on being able to set breakpoints precisely > (with line, column, length, and tag). > So, I also needed to add support for that. Currently, Truffle > tries to find a > best match, perhaps based on column and line, which isn't precise > enough for > my use case: > > https://github.com/smarr/truffle/commit/3c68e3dcffb3beab3e537ce5ac8e61a78c6b449d > > > These last three points where the major elements that needed > revision for > my Truffle updated, because the related Truffle code was changed > substantially, > which means I needed to completely reimplement my patches. > > > # Other notes on the update > > Beside rewriting my custom patches, the change that required most > work was > likely going from @Instrumentable to @GenerateWrapper: > https://github.com/smarr/SOMns/pull/266/commits/7c21cda8d69ac479dfa0d838061a049fb02311ce > > > To make this work nicely, I had to change a couple of things around. > One problem with the notion of wrappers is that it is rather > complicated to > ensure that they always have the right type. > The type is constrained on the one side by the field containing > the child node, > and on the other side, by the node that is actually wrapped. > So, there is a tension between having few very general wrappers, > and the > specifics one might want to use in some node. > It requires quite a bit of care to have a more specific field type > for the > child node and make everything work out correctly. > Not sure what one could do about this, but it sounds like > something that > would deserve some general guideline and recommendation about how > to structure > the tree of nodes one has in a language. Though, I don't really > know what one > would recommend. I dealt with my nodes mostly on a case-by-case basis. > > The language interop support is something I haven't invested much > time in yet. > So, the fact that the old testing infrastructure is gone is somewhat > unfortunate, because this means my interop support is now untested. > > Adopting the basic bits of the Graal SDK, and switching away from > PolyglotEngine > was comparably simple. Though, I didn't build a full SDK-style > launcher. > > In an other email, I mentioned some compilation issues, but I > suppose those are mostly Graal issues. > > For the curious, the SOMns PR for the update is here: > https://github.com/smarr/SOMns/pull/266 > > > Best regards > Stefan > > -- > Stefan Marr > School of Computing, University of Kent > http://stefan-marr.de/research/ > > > From java at stefan-marr.de Mon Sep 3 16:25:14 2018 From: java at stefan-marr.de (Stefan Marr) Date: Mon, 3 Sep 2018 17:25:14 +0100 Subject: Update Report Truffle 0.33 to 1.0.0-rc5 In-Reply-To: <4e3f8c70-9fdb-28b5-2d56-1bad03b62136@oracle.com> References: <4e3f8c70-9fdb-28b5-2d56-1bad03b62136@oracle.com> Message-ID: <298B8FE9-75FD-40AB-8501-2B3E0492E810@stefan-marr.de> Hi Martin, Hi Christian: > On 3 Sep 2018, at 14:55, Martin Entlicher wrote: > >> > ## Java Run-Time condition for Breakpoints >> >> I remember discussing this long time ago. That patch exposes PE to the debugging API user. >> I wanted to avoid this to reduce complexity for debugging protocol implementers. >> I think it would be best to discuss some use-cases, to find out whether a generic feature like this really is necessary. > > This can be a way how to extend the debugging logic. But it looks strange to me, that SimpleCondition.evaluate() does not take any context information. I?m also curious about the use-cases and about how a typical Java condition might look like. For me this is the simplest solution to figure out whether a method is activated via an asynchronous message send or just via normal invocation. For that test, I do not need any context, and it is the only thing I am doing with it. I don?t have a good other use case for it. The main reason I listed it, is because of the seeming asymmetry in the API. You can do something at the guest language level, but not easily at the interpreter level. But, this is really a rather trivial patch, so, I don?t think it is necessary to go upstream. >> > I use tags for advance breakpoints, for instance on thread creation, on joining > > We use SourceElement enum to abstract the Tag and to limit the set of tags that can be used in debugging. So far we support StatementTag and ExpressionTag only. Use of a non-standard tag would limit debugging to those languages that provide such tag. > It might be easier to patch just the SourceElement with your additional tags. My tags are far from general, so, I didn?t want to move them into the enum. And yes, they are not just language specific, but perhaps even framework/library specific. One possible way of decoupling is described here: http://stefan-marr.de/papers/dls-marr-et-al-concurrency-agnostic-protocol-for-debugging/ I?d think that the basic idea would also neatly apply to Truffle. We already do advertise what features a language provides, we just don?t have the Truffle debugger ?configureable? from the language yet. Perhaps relevant to know: I am using custom breakpoint-trigger nodes in my language. So, there is a node that is only executed in case of a breakpoint, and then the normal Truffle debugger mechanisms are used. (The node is tagged to always suspend execution.) While this exposes the debugger to the language, the debugger itself is still independent from the language. I suppose it could also be solved differently, but then I would be less free in how I design my nodes. So, I chose this way around. (But, I can understand that this is likely not your preferred solution.) >> > I use a stepping strategy to step until the next node with a given tag. > > If you have SourceElement for the tag, then the only difference from the existing prepareStepInto/Over(StepConfig stepConfig) is a Thread. Ehm, I am not sure what you mean. ?Step to next node with given tag? is sufficiently different from step into/over. > But it looks a bit strange to me to submit steps from SuspendedEvent into other threads. I don?t submit steps into other threads. A suspended event only instructs the current thread on how to proceed. > > Much of this depends on being able to set breakpoints precisely (with line, column, length, and tag). > > So, I also needed to add support for that. Currently, Truffle tries to find a > > best match, perhaps based on column and line, which isn't precise enough for > > my use case: > > > > https://github.com/smarr/truffle/commit/3c68e3dcffb3beab3e537ce5ac8e61a78c6b449d > > When debugging expressions it happens that there are sections with the same tag starting or ending on the same position. The section length is a way to distinguish that. Yes. My understanding is that the current algorithm can find the perfect match, but then still end up using some other source section, which also somewhat fits, but more fuzzily. This didn?t work for me. So, I added a step that identifies the perfect match (i.e., matching line, column, length) and disregards other matches afterwards. Best regards Stefan -- Stefan Marr School of Computing, University of Kent http://stefan-marr.de/research/ From eregontp at gmail.com Tue Sep 4 20:32:05 2018 From: eregontp at gmail.com (Benoit Daloze) Date: Tue, 4 Sep 2018 22:32:05 +0200 Subject: Any known changes in Graal around sin/sqrt/exp? In-Reply-To: <80F27F12-1BBB-4C64-9333-7461E1BFCAB3@stefan-marr.de> References: <80F27F12-1BBB-4C64-9333-7461E1BFCAB3@stefan-marr.de> Message-ID: Hello, I would guess it's due to https://github.com/oracle/graal/issues/652 Benoit On Sun, Sep 2, 2018 at 11:54 PM, Stefan Marr wrote: > Hi: > > After updating to >1.0.0-rc5 from previously 0.33, I have a benchmark that now takes more than 4 times as much execution time on Graal core. > > Before investigating this further, I wanted to ask whether there are any recent changes around the handling of math functions such as sin, sqrt, and exp. > > A look at IGV seems to indicate that either something didn?t get recognized as a constant or some branches can?t be eliminated (or got added). > > I put some IGV screenshots here: https://gist.github.com/smarr/5369b4fa9685b1886fd5402ce9d2e0f2 > > Any idea whether something that could be related to this was changed? > > Thank you > Stefan > > -- > Stefan Marr > School of Computing, University of Kent > http://stefan-marr.de/research/ > > From java at stefan-marr.de Wed Sep 5 10:22:47 2018 From: java at stefan-marr.de (Stefan Marr) Date: Wed, 5 Sep 2018 11:22:47 +0100 Subject: Any known changes in Graal around sin/sqrt/exp? In-Reply-To: References: <80F27F12-1BBB-4C64-9333-7461E1BFCAB3@stefan-marr.de> Message-ID: Hi Benoit: > On 4 Sep 2018, at 21:32, Benoit Daloze wrote: > > I would guess it?s due to https://github.com/oracle/graal/issues/652 Yes, thanks. I thought so too. I tried to verify this by reverting the related changes, but I failed to apply them cleanly, and couldn?t spend more time on it. Best regards Stefan -- Stefan Marr School of Computing, University of Kent http://stefan-marr.de/research/ From dean.long at oracle.com Mon Sep 10 20:08:02 2018 From: dean.long at oracle.com (dean.long at oracle.com) Date: Mon, 10 Sep 2018 13:08:02 -0700 Subject: RFR(XS) 8210434: [Graal] 8209301 prevents GitHub Graal from compiling with latest JDK Message-ID: <87209ade-9c45-2edd-3370-31a447e38588@oracle.com> http://cr.openjdk.java.net/~dlong/8210434/webrev/ https://bugs.openjdk.java.net/browse/JDK-8210434 This change reverts the 8209301 rename in AOTCompiledClass and adds back HotSpotResolvedObjectType.isAnonymous to preserve compatibility. dl From doug.simon at oracle.com Mon Sep 10 20:33:17 2018 From: doug.simon at oracle.com (Doug Simon) Date: Mon, 10 Sep 2018 22:33:17 +0200 Subject: RFR(XS) 8210434: [Graal] 8209301 prevents GitHub Graal from compiling with latest JDK In-Reply-To: <87209ade-9c45-2edd-3370-31a447e38588@oracle.com> References: <87209ade-9c45-2edd-3370-31a447e38588@oracle.com> Message-ID: <7E57CA1D-4B3F-46A2-94AD-6CE169093E94@oracle.com> Looks good to me. > On 10 Sep 2018, at 22:08, dean.long at oracle.com wrote: > > http://cr.openjdk.java.net/~dlong/8210434/webrev/ > https://bugs.openjdk.java.net/browse/JDK-8210434 > > This change reverts the 8209301 rename in AOTCompiledClass and adds back HotSpotResolvedObjectType.isAnonymous to preserve compatibility. > > dl From marc at petit-huguenin.org Mon Sep 10 21:10:43 2018 From: marc at petit-huguenin.org (Marc Petit-Huguenin) Date: Mon, 10 Sep 2018 14:10:43 -0700 Subject: GraalVM 11 Message-ID: <29bc5ee8-ecd8-6812-8b5b-1b40df35838a@petit-huguenin.org> Hello, Building a GraalVM for Java 11 does not seem to work yet (cd graal/vm; JAVA_HOME=jdk11 EXTRA_JAVA_HOMES=jdk8-jvmci mx build). Is it work in progress, or am I doing something wrong? Thanks. -- Marc Petit-Huguenin Email: marc at petit-huguenin.org Blog: https://marc.petit-huguenin.org Profile: https://www.linkedin.com/in/petithug From vladimir.kozlov at oracle.com Mon Sep 10 21:23:50 2018 From: vladimir.kozlov at oracle.com (Vladimir Kozlov) Date: Mon, 10 Sep 2018 14:23:50 -0700 Subject: RFR(XS) 8210434: [Graal] 8209301 prevents GitHub Graal from compiling with latest JDK In-Reply-To: <7E57CA1D-4B3F-46A2-94AD-6CE169093E94@oracle.com> References: <87209ade-9c45-2edd-3370-31a447e38588@oracle.com> <7E57CA1D-4B3F-46A2-94AD-6CE169093E94@oracle.com> Message-ID: <492e8d6b-1897-8dd4-5d79-4ee2a7c1f60f@oracle.com> +1 Thanks, Vladimir On 9/10/18 1:33 PM, Doug Simon wrote: > Looks good to me. > >> On 10 Sep 2018, at 22:08, dean.long at oracle.com wrote: >> >> http://cr.openjdk.java.net/~dlong/8210434/webrev/ >> https://bugs.openjdk.java.net/browse/JDK-8210434 >> >> This change reverts the 8209301 rename in AOTCompiledClass and adds back HotSpotResolvedObjectType.isAnonymous to preserve compatibility. >> >> dl > From dean.long at oracle.com Mon Sep 10 23:18:07 2018 From: dean.long at oracle.com (dean.long at oracle.com) Date: Mon, 10 Sep 2018 16:18:07 -0700 Subject: RFR(XS) 8210434: [Graal] 8209301 prevents GitHub Graal from compiling with latest JDK In-Reply-To: <492e8d6b-1897-8dd4-5d79-4ee2a7c1f60f@oracle.com> References: <87209ade-9c45-2edd-3370-31a447e38588@oracle.com> <7E57CA1D-4B3F-46A2-94AD-6CE169093E94@oracle.com> <492e8d6b-1897-8dd4-5d79-4ee2a7c1f60f@oracle.com> Message-ID: Thanks Doug and Vladimir. dl On 9/10/18 2:23 PM, Vladimir Kozlov wrote: > +1 > > Thanks, > Vladimir > > On 9/10/18 1:33 PM, Doug Simon wrote: >> Looks good to me. >> >>> On 10 Sep 2018, at 22:08, dean.long at oracle.com wrote: >>> >>> http://cr.openjdk.java.net/~dlong/8210434/webrev/ >>> https://bugs.openjdk.java.net/browse/JDK-8210434 >>> >>> This change reverts the 8209301 rename in AOTCompiledClass and adds >>> back HotSpotResolvedObjectType.isAnonymous to preserve compatibility. >>> >>> dl >> From gilles.m.duboscq at oracle.com Tue Sep 11 09:32:21 2018 From: gilles.m.duboscq at oracle.com (Gilles Duboscq) Date: Tue, 11 Sep 2018 11:32:21 +0200 Subject: GraalVM 11 In-Reply-To: <29bc5ee8-ecd8-6812-8b5b-1b40df35838a@petit-huguenin.org> References: <29bc5ee8-ecd8-6812-8b5b-1b40df35838a@petit-huguenin.org> Message-ID: <343d2f32-3519-652a-8fe4-7cbaf9b38db4@oracle.com> Hi Marc, While we plan to make GraalVM releases based on JDK 11, it does not work at the moment. While the compiler itself already works on JDK 11, we are in the process of adding compatibility for other parts of the stack. Gilles On 10/09/18 23:10, Marc Petit-Huguenin wrote: > Hello, > > Building a GraalVM for Java 11 does not seem to work yet (cd graal/vm; JAVA_HOME=jdk11 EXTRA_JAVA_HOMES=jdk8-jvmci mx build). Is it work in progress, or am I doing something wrong? > > Thanks. > From mtraverso at gmail.com Fri Sep 14 18:17:09 2018 From: mtraverso at gmail.com (Martin Traverso) Date: Fri, 14 Sep 2018 11:17:09 -0700 Subject: Intrinsics Message-ID: Hi, I'm playing around with Graal, and as an experiment, I'm trying to see what it would take to intrinsify some operations to do math on 128-bit values. I have a method with the following signature: boolean add128(long low1, long high1, long low2, long high2, long[] result) It computes the sum of two 128-bit integers encoded in two longs each and stores the result in the 2-element array that's provided via the last argument. It returns true if the sum overflows. I'd like to emit the equivalent of the following assembly pseudocode: result[0] = ADD low1 low2 result[1] = ADC high1 high2 return = (carry == 1) >From what I gathered so far, I should add a new node (e.g., Add128Node) and register a builder a graph builder plugin that swaps invocations to that method with the new node. But that's where I'm getting stuck. Two paths I've started exploring: 1. Lower the Add128Node into operations that perform the sums of the high vs low parts (e.g., Add128LowNode, Add128HighNode), do the assignments to the resulting array, etc. This would seem to require modeling operations that produce multiple outputs (low + low produces one value + carry). Is this even possible? 2. Make Add128Node LIRLowerable and generate the whole sequence of low-level operations in one shot. I'm not sure how the assignments to the output array and return value would fit here, though. I'm sure I'm missing something obvious, so I appreciate any pointers or suggestions. Are there similar examples I can draw inspiration from? Thanks, Martin From tbaldridge at gmail.com Tue Sep 18 13:57:54 2018 From: tbaldridge at gmail.com (Timothy Baldridge) Date: Tue, 18 Sep 2018 07:57:54 -0600 Subject: How to understand the mechanics of Truffle Message-ID: I'm evaluating Truffle for use in a language I'm developing. I've written several interpreters (with JITs) in RPython in the past, so I'm familiar with the concepts involved. I've also read quite a few papers on Truffle and the differences between it and RPython. However, I have a few questions, these are things that are still vague in my mind even after reading the literature available on Truffle: 1) When does Truffle start the merging of AST nodes into compiled code? Is this demarcation specified by the programmer, or by a profiler in Truffle? Is there a way for the programmer to influence these mechanics? 2) How much of a given AST is compiled into a single code unit by Truffle? How is that controlled? 3) Does Truffle search an AST graph via partial execution, or by reflection (by walking all fields on nodes that are marked with @Node annotations?). What is the point of the annotations for Nodes and Node children, is it purely programmer convenience or does it tie into the JIT? 4) The literature states that a requirement for a Truffle interpreter is that the AST should stabilize at some point in order to not require continual re-compilation. How does this work for code that uses generators (like ZipPy) that use the special Control-Flow exception? Is it possible to have a control-flow exception return an AST node that is executed by the exception handler? 5) What is the definition of "not changing" for a AST graph? Is it that the AST nodes should stop throwing de-optimization exceptions at some point? Is it that the node types must change? Or is it that the actual instances of the AST nodes must not change from one evaluation of the AST tree to the next? Thanks for the help, and for the great work on Truffle! Timothy Baldridge From gilles.m.duboscq at oracle.com Tue Sep 18 15:24:43 2018 From: gilles.m.duboscq at oracle.com (Gilles Duboscq) Date: Tue, 18 Sep 2018 17:24:43 +0200 Subject: Intrinsics In-Reply-To: References: Message-ID: <471267e0-b44a-5565-5d0f-11ea1199340c@oracle.com> Hi Martin, One of the way to do that is to combine both solution and use "projection" nodes to model the "multiple outputs" part" while still emitting the whole code sequence at once. In the graph you have ``` add128Node = Add128Node(long low1, long high1, long low2, long high2) result[0] = Add128LowNode(add128Node) // this is a projection of Add128Node result[1] = Add128HighNode(add128Node) // this is a projection of Add128Node return = Add128CarryNode(add128Node) // this is a projection of Add128Node ```` In `Add128Node.generate`, you will need to generate a LIR Op that has 3 results: ``` class Add128Op extends AMD64LIRInstruction { @Use({REG, STACK}) protected AllocatableValue low1; // TODO might need HINTs @Use({REG, STACK}) protected AllocatableValue low2; @Use({REG, STACK}) protected AllocatableValue high1; @Use({REG, STACK}) protected AllocatableValue high2; @Def({REG}) protected AllocatableValue lowResult; @Def({REG}) protected AllocatableValue highResult; @Def({REG}) protected AllocatableValue carryResult; ... void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { // see AMD64Binary.CommutativeTwoOp#emitCode AllocatableValue lowInput; if (sameRegister(lowResult, low2)) { lowInput = low1; } else { AMD64Move.move(crb, masm, lowResult, low1); lowInput = low2; } // TODO deal with stack vs reg etc. masm.add(asRegister(lowResult), asRegister(lowInput)); // TODO setup highInput, stack vs reg etc. masm.adc(highResult, highInput); AMD64ControlFlow.cmove(crb, masm, carryResult, false, ConditionFlag.CarrySet, false, new ConstantValue(toRegisterKind(AMD64Kind.BYTE), JavaConstant.forBoolean(true)), new ConstantValue(toRegisterKind(AMD64Kind.BYTE), JavaConstant.forBoolean(false))) } } ``` During `Add128Node.generate`, remember the values you used for `lowResult`, `highResult`, and `carryResult`: ``` AllocatableValue low1Value = tool.operand(low1); ... this.lowResultValue = tool.getLIRGeneratorTool().newVariable(LIRKind.value(AMD64Kind.QWORD)); ... tool.setResult(this, tool.getLIRGeneratorTool().append(new Add128Op( low1Value, low2Value, high1Value, high2Value, lowResultValue, highResultValue, carrtResultValue))); ``` In `Add128LowNode.generate`, just do: `tool.setResult(this, getAdd128Node().getLowResultValue());` I hope that helps. Gilles On 14/09/18 20:17, Martin Traverso wrote: > Hi, > > I'm playing around with Graal, and as an experiment, I'm trying to see what > it would take to intrinsify some operations to do math on 128-bit values. > > I have a method with the following signature: > > boolean add128(long low1, long high1, long low2, long high2, long[] > result) > > It computes the sum of two 128-bit integers encoded in two longs each and > stores the result in the 2-element array that's provided via the last > argument. It returns true if the sum overflows. > > I'd like to emit the equivalent of the following assembly pseudocode: > > result[0] = ADD low1 low2 > result[1] = ADC high1 high2 > return = (carry == 1) > > From what I gathered so far, I should add a new node (e.g., Add128Node) and > register a builder a graph builder plugin that swaps invocations to that > method with the new node. > > But that's where I'm getting stuck. Two paths I've started exploring: > 1. Lower the Add128Node into operations that perform the sums of the high > vs low parts (e.g., Add128LowNode, Add128HighNode), do the assignments to > the resulting array, etc. This would seem to require modeling operations > that produce multiple outputs (low + low produces one value + carry). Is > this even possible? > 2. Make Add128Node LIRLowerable and generate the whole sequence of > low-level operations in one shot. I'm not sure how the assignments to the > output array and return value would fit here, though. > > I'm sure I'm missing something obvious, so I appreciate any pointers or > suggestions. Are there similar examples I can draw inspiration from? > > Thanks, > Martin > From christian.wimmer at oracle.com Tue Sep 18 15:53:23 2018 From: christian.wimmer at oracle.com (Christian Wimmer) Date: Tue, 18 Sep 2018 08:53:23 -0700 Subject: Intrinsics In-Reply-To: <471267e0-b44a-5565-5d0f-11ea1199340c@oracle.com> References: <471267e0-b44a-5565-5d0f-11ea1199340c@oracle.com> Message-ID: <60dfebff-7b90-7fff-8138-b3fccf72a541@oracle.com> It might make sense to not only have a "projection" node that splits a 128 bit value into two 64-bit values, but also an explicit "fuse" node that combines two 64-bit values into one 128 bit value. I assume that in most cases you are going to have not a single arithmetic node, but an expression tree of 128-bit arithmetic nodes. You need to rely either on escape analysis or read elimination to get rid of the intermediate array stores / loads. With the explicit "fuse" nodes, you can then more easily remove the projections and fusing that are initially between arithmetic nodes, i.e., you can end up with an expression tree in high-level Graal IR that consists only of 128 bit arithmetic nodes, and only the final result needs a projection. -Christian On 09/18/2018 08:24 AM, Gilles Duboscq wrote: > Hi Martin, > > One of the way to do that is to combine both solution and use "projection" nodes to model the "multiple outputs" part" while still emitting the whole code sequence at once. > > In the graph you have > ``` > add128Node = Add128Node(long low1, long high1, long low2, long high2) > result[0] = Add128LowNode(add128Node) // this is a projection of Add128Node > result[1] = Add128HighNode(add128Node) // this is a projection of Add128Node > return = Add128CarryNode(add128Node) // this is a projection of Add128Node > ```` > > In `Add128Node.generate`, you will need to generate a LIR Op that has 3 results: > > ``` > class Add128Op extends AMD64LIRInstruction { > @Use({REG, STACK}) protected AllocatableValue low1; // TODO might need HINTs > @Use({REG, STACK}) protected AllocatableValue low2; > @Use({REG, STACK}) protected AllocatableValue high1; > @Use({REG, STACK}) protected AllocatableValue high2; > > @Def({REG}) protected AllocatableValue lowResult; > @Def({REG}) protected AllocatableValue highResult; > @Def({REG}) protected AllocatableValue carryResult; > ... > void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) { > // see AMD64Binary.CommutativeTwoOp#emitCode > AllocatableValue lowInput; > if (sameRegister(lowResult, low2)) { > lowInput = low1; > } else { > AMD64Move.move(crb, masm, lowResult, low1); > lowInput = low2; > } > // TODO deal with stack vs reg etc. > masm.add(asRegister(lowResult), asRegister(lowInput)); > // TODO setup highInput, stack vs reg etc. > masm.adc(highResult, highInput); > AMD64ControlFlow.cmove(crb, masm, carryResult, false, ConditionFlag.CarrySet, false, > new ConstantValue(toRegisterKind(AMD64Kind.BYTE), JavaConstant.forBoolean(true)), > new ConstantValue(toRegisterKind(AMD64Kind.BYTE), JavaConstant.forBoolean(false))) > } > } > ``` > > During `Add128Node.generate`, remember the values you used for `lowResult`, `highResult`, and `carryResult`: > > ``` > AllocatableValue low1Value = tool.operand(low1); > ... > this.lowResultValue = tool.getLIRGeneratorTool().newVariable(LIRKind.value(AMD64Kind.QWORD)); > ... > tool.setResult(this, tool.getLIRGeneratorTool().append(new Add128Op( > low1Value, low2Value, high1Value, high2Value, > lowResultValue, highResultValue, carrtResultValue))); > > ``` > > In `Add128LowNode.generate`, just do: `tool.setResult(this, getAdd128Node().getLowResultValue());` > > I hope that helps. > Gilles > > On 14/09/18 20:17, Martin Traverso wrote: >> Hi, >> >> I'm playing around with Graal, and as an experiment, I'm trying to see what >> it would take to intrinsify some operations to do math on 128-bit values. >> >> I have a method with the following signature: >> >> boolean add128(long low1, long high1, long low2, long high2, long[] >> result) >> >> It computes the sum of two 128-bit integers encoded in two longs each and >> stores the result in the 2-element array that's provided via the last >> argument. It returns true if the sum overflows. >> >> I'd like to emit the equivalent of the following assembly pseudocode: >> >> result[0] = ADD low1 low2 >> result[1] = ADC high1 high2 >> return = (carry == 1) >> >> From what I gathered so far, I should add a new node (e.g., Add128Node) and >> register a builder a graph builder plugin that swaps invocations to that >> method with the new node. >> >> But that's where I'm getting stuck. Two paths I've started exploring: >> 1. Lower the Add128Node into operations that perform the sums of the high >> vs low parts (e.g., Add128LowNode, Add128HighNode), do the assignments to >> the resulting array, etc. This would seem to require modeling operations >> that produce multiple outputs (low + low produces one value + carry). Is >> this even possible? >> 2. Make Add128Node LIRLowerable and generate the whole sequence of >> low-level operations in one shot. I'm not sure how the assignments to the >> output array and return value would fit here, though. >> >> I'm sure I'm missing something obvious, so I appreciate any pointers or >> suggestions. Are there similar examples I can draw inspiration from? >> >> Thanks, >> Martin >> > From chris.seaton at oracle.com Tue Sep 18 18:53:01 2018 From: chris.seaton at oracle.com (Chris Seaton) Date: Tue, 18 Sep 2018 19:53:01 +0100 Subject: How to understand the mechanics of Truffle In-Reply-To: References: Message-ID: <8F2FCFD5-A730-4C81-BE81-E8EE47F418AD@oracle.com> > On 18 Sep 2018, at 14:57, Timothy Baldridge wrote: > > I'm evaluating Truffle for use in a language I'm developing. I've written > several interpreters (with JITs) in RPython in the past, so I'm familiar > with the concepts involved. I've also read quite a few papers on Truffle > and the differences between it and RPython. > > However, I have a few questions, these are things that are still vague in > my mind even after reading the literature available on Truffle: > > 1) When does Truffle start the merging of AST nodes into compiled code? Is > this demarcation specified by the programmer, or by a profiler in Truffle? > Is there a way for the programmer to influence these mechanics? There is a call threshold for compilation Truffle methods (a method represented as Truffle AST nodes). When the threshold is hit, all nodes in the AST are compiled as one compilation unit. Exceptions to this include on-stack-replacement, inlining, and splitting (creating multiple copies of ASTs). > 2) How much of a given AST is compiled into a single code unit by Truffle? > How is that controlled? All of the AST that is compiled into a single unit. Exceptions to this include branches that the profiler has found are never used, or that through some other constant value there is never actually a branch that executes them, even though they are there in the AST. > 3) Does Truffle search an AST graph via partial execution, or by reflection > (by walking all fields on nodes that are marked with @Node annotations?). > What is the point of the annotations for Nodes and Node children, is it > purely programmer convenience or does it tie into the JIT? Truffle has a method `replace(otherNode)` to replace a node with another node. To do that automatically, it needs to know which fields the node has that points to other nodes, so it can update those fields. Instead of manually specifying these, the `@Node` annotations allow Truffle to find them automatically via reflection. The annotation also tells Truffle?s partial evaluator to treat the fields as final, even though they?re mutable for the purposes of the interpreter. > 4) The literature states that a requirement for a Truffle interpreter is > that the AST should stabilize at some point in order to not require > continual re-compilation. How does this work for code that uses generators > (like ZipPy) that use the special Control-Flow exception? Is it possible to > have a control-flow exception return an AST node that is executed by the > exception handler? Control-flow exceptions do not cause deoptimisation in most cases. The execute method of nodes (really, any method that takes a `VirtualFrame` parameter) needs to be called on an object reference that is compilation final. If an exception is thrown that contains a node as a field, then that node is unlikely to be constant by the time you read it back out (it could be, if the exception is thrown and caught in the same compilation unit, and the catch-site can see the node is only ever one object, and probably more conditions). That?s not normally how you write a Truffle interpreter and I wouldn?t recommend that. I?m not sure what ZipPy is doing that you?re referring to. > 5) What is the definition of "not changing" for a AST graph? Is it that the > AST nodes should stop throwing de-optimization exceptions at some point? Is > it that the node types must change? Or is it that the actual instances of > the AST nodes must not change from one evaluation of the AST tree to the > next? The key thing is that you stop deoptimising. Changing the AST (replacing one node with another) is one cause of deoptimisation. It doesn?t matter if the type changes - it?s the reference changing to refer to another object that is the problem. > Thanks for the help, and for the great work on Truffle! > > Timothy Baldridge From mtraverso at gmail.com Tue Sep 18 20:27:49 2018 From: mtraverso at gmail.com (Martin Traverso) Date: Tue, 18 Sep 2018 13:27:49 -0700 Subject: Intrinsics In-Reply-To: <60dfebff-7b90-7fff-8138-b3fccf72a541@oracle.com> References: <471267e0-b44a-5565-5d0f-11ea1199340c@oracle.com> <60dfebff-7b90-7fff-8138-b3fccf72a541@oracle.com> Message-ID: Thanks guys. This is very helpful. I'll give it a try and report back. - Martin On Tue, Sep 18, 2018 at 8:53 AM Christian Wimmer < christian.wimmer at oracle.com> wrote: > It might make sense to not only have a "projection" node that splits a > 128 bit value into two 64-bit values, but also an explicit "fuse" node > that combines two 64-bit values into one 128 bit value. I assume that in > most cases you are going to have not a single arithmetic node, but an > expression tree of 128-bit arithmetic nodes. You need to rely either on > escape analysis or read elimination to get rid of the intermediate array > stores / loads. With the explicit "fuse" nodes, you can then more easily > remove the projections and fusing that are initially between arithmetic > nodes, i.e., you can end up with an expression tree in high-level Graal > IR that consists only of 128 bit arithmetic nodes, and only the final > result needs a projection. > > -Christian > > > On 09/18/2018 08:24 AM, Gilles Duboscq wrote: > > Hi Martin, > > > > One of the way to do that is to combine both solution and use > "projection" nodes to model the "multiple outputs" part" while still > emitting the whole code sequence at once. > > > > In the graph you have > > ``` > > add128Node = Add128Node(long low1, long high1, long low2, long high2) > > result[0] = Add128LowNode(add128Node) // this is a projection of > Add128Node > > result[1] = Add128HighNode(add128Node) // this is a projection of > Add128Node > > return = Add128CarryNode(add128Node) // this is a projection of > Add128Node > > ```` > > > > In `Add128Node.generate`, you will need to generate a LIR Op that has 3 > results: > > > > ``` > > class Add128Op extends AMD64LIRInstruction { > > @Use({REG, STACK}) protected AllocatableValue low1; // TODO might > need HINTs > > @Use({REG, STACK}) protected AllocatableValue low2; > > @Use({REG, STACK}) protected AllocatableValue high1; > > @Use({REG, STACK}) protected AllocatableValue high2; > > > > @Def({REG}) protected AllocatableValue lowResult; > > @Def({REG}) protected AllocatableValue highResult; > > @Def({REG}) protected AllocatableValue carryResult; > > ... > > void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) > { > > // see AMD64Binary.CommutativeTwoOp#emitCode > > AllocatableValue lowInput; > > if (sameRegister(lowResult, low2)) { > > lowInput = low1; > > } else { > > AMD64Move.move(crb, masm, lowResult, low1); > > lowInput = low2; > > } > > // TODO deal with stack vs reg etc. > > masm.add(asRegister(lowResult), asRegister(lowInput)); > > // TODO setup highInput, stack vs reg etc. > > masm.adc(highResult, highInput); > > AMD64ControlFlow.cmove(crb, masm, carryResult, false, > ConditionFlag.CarrySet, false, > > new ConstantValue(toRegisterKind(AMD64Kind.BYTE), > JavaConstant.forBoolean(true)), > > new ConstantValue(toRegisterKind(AMD64Kind.BYTE), > JavaConstant.forBoolean(false))) > > } > > } > > ``` > > > > During `Add128Node.generate`, remember the values you used for > `lowResult`, `highResult`, and `carryResult`: > > > > ``` > > AllocatableValue low1Value = tool.operand(low1); > > ... > > this.lowResultValue = > tool.getLIRGeneratorTool().newVariable(LIRKind.value(AMD64Kind.QWORD)); > > ... > > tool.setResult(this, tool.getLIRGeneratorTool().append(new Add128Op( > > low1Value, low2Value, high1Value, high2Value, > > lowResultValue, highResultValue, carrtResultValue))); > > > > ``` > > > > In `Add128LowNode.generate`, just do: `tool.setResult(this, > getAdd128Node().getLowResultValue());` > > > > I hope that helps. > > Gilles > > > > On 14/09/18 20:17, Martin Traverso wrote: > >> Hi, > >> > >> I'm playing around with Graal, and as an experiment, I'm trying to see > what > >> it would take to intrinsify some operations to do math on 128-bit > values. > >> > >> I have a method with the following signature: > >> > >> boolean add128(long low1, long high1, long low2, long high2, long[] > >> result) > >> > >> It computes the sum of two 128-bit integers encoded in two longs each > and > >> stores the result in the 2-element array that's provided via the last > >> argument. It returns true if the sum overflows. > >> > >> I'd like to emit the equivalent of the following assembly pseudocode: > >> > >> result[0] = ADD low1 low2 > >> result[1] = ADC high1 high2 > >> return = (carry == 1) > >> > >> From what I gathered so far, I should add a new node (e.g., > Add128Node) and > >> register a builder a graph builder plugin that swaps invocations to that > >> method with the new node. > >> > >> But that's where I'm getting stuck. Two paths I've started exploring: > >> 1. Lower the Add128Node into operations that perform the sums of the > high > >> vs low parts (e.g., Add128LowNode, Add128HighNode), do the assignments > to > >> the resulting array, etc. This would seem to require modeling operations > >> that produce multiple outputs (low + low produces one value + carry). Is > >> this even possible? > >> 2. Make Add128Node LIRLowerable and generate the whole sequence of > >> low-level operations in one shot. I'm not sure how the assignments to > the > >> output array and return value would fit here, though. > >> > >> I'm sure I'm missing something obvious, so I appreciate any pointers or > >> suggestions. Are there similar examples I can draw inspiration from? > >> > >> Thanks, > >> Martin > >> > > > From java at stefan-marr.de Wed Sep 19 18:10:56 2018 From: java at stefan-marr.de (Stefan Marr) Date: Wed, 19 Sep 2018 19:10:56 +0100 Subject: native-image: jline substitution fails, because I don't use jline Message-ID: Hi: After some fiddling, I managed to move my 1year old SOMns-substrate experiment to current substrate, and it works quite nicely, even with all the actor/concurrency features :) Though, at the moment, I have to work around the following issue: error: could not find target method: public static jline.Terminal com.oracle.svm.jline.subst.Target_jline_TerminalFactory.create(java.lang.String) On my local machine, I simply deleted the substitution. Is there a better way to avoid the substitution failing? It simply does not apply in my case. There aren?t any jline classes on my classpath. Thanks Stefan -- Stefan Marr School of Computing, University of Kent http://stefan-marr.de/research/ From christian.wimmer at oracle.com Wed Sep 19 18:30:12 2018 From: christian.wimmer at oracle.com (Christian Wimmer) Date: Wed, 19 Sep 2018 11:30:12 -0700 Subject: native-image: jline substitution fails, because I don't use jline In-Reply-To: References: Message-ID: The jline substitutions are only enabled when jline is on the classpath. This is done by checking if the class "jline.console.ConsoleReader" is found - we assume that if ConsoleReader is found, everything of jline is there. So some parts of jline (and maybe a older/newer version than what we support) must be on your classpath. -Christian On 09/19/2018 11:10 AM, Stefan Marr wrote: > Hi: > > After some fiddling, I managed to move my 1year old SOMns-substrate experiment to current substrate, and it works quite nicely, even with all the actor/concurrency features :) > > Though, at the moment, I have to work around the following issue: > > error: could not find target method: public static jline.Terminal com.oracle.svm.jline.subst.Target_jline_TerminalFactory.create(java.lang.String) > > On my local machine, I simply deleted the substitution. > > Is there a better way to avoid the substitution failing? > It simply does not apply in my case. There aren?t any jline classes on my classpath. > > Thanks > Stefan > > From java at stefan-marr.de Thu Sep 20 08:13:08 2018 From: java at stefan-marr.de (Stefan Marr) Date: Thu, 20 Sep 2018 09:13:08 +0100 Subject: native-image: jline substitution fails, because I don't use jline In-Reply-To: References: Message-ID: <04E82224-319E-421B-AD0C-9611E2F3C1AF@stefan-marr.de> Hi Christian: > On 19 Sep 2018, at 19:30, Christian Wimmer wrote: > > The jline substitutions are only enabled when jline is on the classpath. This is done by checking if the class "jline.console.ConsoleReader" is found - we assume that if ConsoleReader is found, everything of jline is there. So some parts of jline (and maybe a older/newer version than what we support) must be on your classpath. Turns out, I indeed had an old version of jline, which was hiding in some jar. Didn?t remember that, and there was no source dependency to be found. Removing it from the jar and SOMns-native builds successfully :) Thank you Stefan -- Stefan Marr School of Computing, University of Kent http://stefan-marr.de/research/