David Chisnall via llvm-dev
2015-Oct-18 11:53 UTC
[llvm-dev] Managed Languages BOF @ Dev Meeting
I won’t be able to attend, but I’d be interested in hearing if any conclusions are reached on several of these topics:> On 16 Oct 2015, at 21:27, Joe Ranieri via llvm-dev <llvm-dev at lists.llvm.org> wrote: > > - Dealing with the explosion of basic blocks that come up with > languages where almost every function call, implicit and explicit, can > raise exceptions.This also relates to non-call exceptions. There was a proposal a few years ago to adopt a model a bit closer to WHRIL’s exception regions, where the unwind destination would become a property of the basic block, not the call site (this also maps fairly closely to the underlying implementation, which deals with PC-ranges). You would need to split blocks in places to ensure that every used value in the unwind target is live on entry to a block that can unwind to it, but that should still reduce the basic block explosion.> - Proper ABI implementation without reimplementing Clang's > TargetInfo.cpp or embedding Clang.Although the implementation is a bit hairy, GCC’s JIT interfaces are a lot cleaner in this respect, as they deal with C types. I’m not opposed to having to embed a chunk of clang (clang itself isn’t that huge, and in a shared-library build the size is easily amortised), but it would be very nice to have some of this exposed via stable interfaces. I believe that Apple folks have done some work in this direction for Swift - perhaps they could be persuaded (either as part of, or separately from, the open sourcing of Swift) to put some work into a stable library interface for external consumers?> - The issue of knowing what the canonical IR is to begin with and then > how to deal with the differences.This is largely a documentation issue. Various passes all have different notions of canonical forms for various constructs in their input and output and these are all undocumented. David
Chris Lattner via llvm-dev
2015-Oct-18 16:23 UTC
[llvm-dev] Managed Languages BOF @ Dev Meeting
On Oct 18, 2015, at 4:53 AM, David Chisnall via llvm-dev <llvm-dev at lists.llvm.org> wrote:>> - Proper ABI implementation without reimplementing Clang's >> TargetInfo.cpp or embedding Clang. > > Although the implementation is a bit hairy, GCC’s JIT interfaces are a lot cleaner in this respect, as they deal with C types. > > I’m not opposed to having to embed a chunk of clang (clang itself isn’t that huge, and in a shared-library build the size is easily amortised), but it would be very nice to have some of this exposed via stable interfaces. I believe that Apple folks have done some work in this direction for Swift - perhaps they could be persuaded (either as part of, or separately from, the open sourcing of Swift) to put some work into a stable library interface for external consumers?FYI, there are details about this work at the last devmtg: http://llvm.org/devmtg/2014-10/#talk18 -Chris
Sanjoy Das via llvm-dev
2015-Oct-18 22:08 UTC
[llvm-dev] Managed Languages BOF @ Dev Meeting
> This also relates to non-call exceptions. There was a proposal a> few years ago to adopt a model a bit closer to WHRIL’s exception > regions, where the unwind destination would become a property of the > basic block, not the call site (this also maps fairly closely to the > underlying implementation, which deals with PC-ranges). You would > need to split blocks in places to ensure that every used value in the > unwind target is live on entry to a block that can unwind to it, but > that should still reduce the basic block explosion. Supporting only basic block level granularity for "try ranges" may not be sufficient for Java -- if a basic block has more than one null check in it then throwing the NullPtrException for the first null check (if it fails) is semantically different from throwing the NullPtrException for the second null check (the constructed exceptions will have different stack traces attached to them, for instance [1]). So we'd have to do repeat the null checks in the unwind block, like superblock: # unwinds to unwind_block null_check(ptr_a) do_something null_check(ptr_b) do_something_again unwind_block: ;; either ptr_a is null or ptr_b is null if (ptr_a == null) throw_nullptrexception(bci = 42) else ;; if (ptr_b == null) throw_nullptrexception(bci = 43) So the code explosion problem still exists (in unwind_block), and we've duplicated a bunch of code. Having said that, I'd love to take a look at the proposal that was made -- will it be easy for you to dig up a link? -- Sanjoy [1]: there is a "hot exception" optimization that some JVMs can do that may allow us to get around this (http://jawspeak.com/2010/05/26/hotspot-caused-exceptions-to-lose-their-stack-traces-in-production-and-the-fix/), but that's an _optimization_ that Java programmers should be able to turn off. > >> - Proper ABI implementation without reimplementing Clang's >> TargetInfo.cpp or embedding Clang. > > Although the implementation is a bit hairy, GCC’s JIT interfaces are a lot cleaner in this respect, as they deal with C types. > > I’m not opposed to having to embed a chunk of clang (clang itself isn’t that huge, and in a shared-library build the size is easily amortised), but it would be very nice to have some of this exposed via stable interfaces. I believe that Apple folks have done some work in this direction for Swift - perhaps they could be persuaded (either as part of, or separately from, the open sourcing of Swift) to put some work into a stable library interface for external consumers? > >> - The issue of knowing what the canonical IR is to begin with and then >> how to deal with the differences. > > This is largely a documentation issue. Various passes all have different notions of canonical forms for various constructs in their input and output and these are all undocumented. > > David > > _______________________________________________ > LLVM Developers mailing list > llvm-dev at lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
David Chisnall via llvm-dev
2015-Oct-19 08:56 UTC
[llvm-dev] Managed Languages BOF @ Dev Meeting
On 18 Oct 2015, at 23:08, Sanjoy Das <sanjoy at playingwithpointers.com> wrote:> > Supporting only basic block level granularity for "try ranges" may not > be sufficient for Java -- if a basic block has more than one null check > in it then throwing the NullPtrException for the first null check (if > it fails) is semantically different from throwing the NullPtrException > for the second null check (the constructed exceptions will have > different stack traces attached to them, for instance [1]).[ Footnote inlined ]> [1]: there is a "hot exception" optimization that some JVMs can do > that may allow us to get around this > (http://jawspeak.com/2010/05/26/hotspot-caused-exceptions-to-lose-their-stack-traces-in-production-and-the-fix/), > but that's an _optimization_ that Java programmers should be able to > turn off.There are some quite exciting security vulnerabilities associated with this optimisation (it turns out that running a few instructions after a security-critical check has failed is not always a good thing to do) so I agree that it’s a good idea to avoid depending on it.> So we'd > have to do repeat the null checks in the unwind block, like > > superblock: # unwinds to unwind_block > null_check(ptr_a) > do_something > null_check(ptr_b) > do_something_again > > unwind_block: > ;; either ptr_a is null or ptr_b is null > if (ptr_a == null) > throw_nullptrexception(bci = 42) > else ;; if (ptr_b == null) > throw_nullptrexception(bci = 43) > > So the code explosion problem still exists (in unwind_block), and > we've duplicated a bunch of code.Does it? I guess it depends on how you are implementing the exceptions. I was expecting that the non-call exceptions would be implemented on top of signals (or something SEH-like on Windows), so the trap handler would have some generic code to identify the faulting instruction, map this back to something useful, and then throw the exception. You wouldn’t be throwing the null pointer exception from the unwind target, that would be generated in the signal handler and the unwind target would only have to do the normal unwinding. In a JIT environment, the unwind targets could probably also be lazily emitted, so in your initial IR you’d just have a single patchpoint for the unwind target. My knowledge of common Java idioms is slightly rusty, but my impression was that, while lots of Java code abuses exceptions for non-exceptional behaviour, this is quite rare for null-pointer exceptions. Is there much (any?) real-world code where the handling of null pointer exceptions is performance critical?> Having said that, I'd love to take a look at the proposal that was > made -- will it be easy for you to dig up a link?It was this mailing list, but your ability to search it is probably as good as mine. My brain, unfortunately, does not contain a well indexed cross-reference of the archive. I believe that the general consensus was that something like this would be good to have, but not sufficiently important to anyone with time to spend actively hacking on stuff to do. Given that people are now seriously using LLVM for languages that are not so C-like, this might be different... David