Summary says it all.
Note that this prevents the 253.perlbmk benchmark from working with the X86 backend.
I am happy to help out with this bug if someone gives me an idea of how to go about fixing it. Chris, I think you were trying to tell me that the basic idea is as follows: invoke: just like call unwind: 1) emit code to restore callee-saved registers and stack pointer 2) emit code to examine stack to see if this call was an invoke (how do we know, if invoke is just like call? wouldn't invoke need to push some kind of marker on the stack or something?) 3) emit branch to the appropriate successor BB (normal dest or exceptional dest) Let me know what it is I am missing here.
Absolutely. Before we can really implement this, here are some ideas for things that should be done first: 1. We need a general purpose stack walking API, supported by the code generator. This will be used to implement friends like __builtin_return_address, stack unwinding for 'unwind', and other things. This obviously needs to handle the frame-pointer-eliminated stack frame which is usually emitted by the code generator. 2. Sometime in the near future, we are going to have to have a way to add persistent attributes to functions, such as 'nothrow'. This is going to be critical because it will allow the code generator to avoid keeping track of how to restore registers for calls that can't throw. This is also useful for the midlevel optimizer. 3. There will have to be some way for the register allocator to remember where it spilled the registers which need to be restored, and for there to be some way to unspill them during unwinding. After all of this exists (#2 is optional, but nice), we can implement this feature. :) -Chris
Idle comments while I wait for 3 different trees to build... :-) For #1, I assume you mean a user-level API, i.e., a bytecode should be able to call uint %llvm.return_address() or call uint %llvm.frame_address(), right? For #3, I assume that this is also going to require some kind of runtime library component, because we cannot always assume that the JIT is running -- otherwise, we could just keep the register allocator's data structures in some kind of huge in-memory hash_map, or something, and call them up as we see fit.
Yup, exactly on both parts. Basically we will have to have a runtime library that provides the unwinder. -Chris
Oh, and llvm.return_address and llvm.frame_address will require code generator support too. :) -Chris
Another important piece if this puzzle that would be useful: The stack unwinder and other portions of the JIT will need to know the extents of various global objects. This is currently not tracked, but it could be. The simple way to do this would be to make the ExectionEngine class keep track of object extents as well as their addresses. In addition to stack unwinding, this is necessary to implement dladdr properly in the JIT. I recently added support to turn a machine address back into the LLVM global object starting at that address (for an unrelated project), and it seems like extending "addGlobalMapping" to take a size would be logical. -Chris
Another idea for implementing this sooner, rather than later: The lower-invoke pass could be modified to insert calls to setjmp/longjmp in the places necessary to implement SJLJ exceptions. Having this done in an LLVM-to-LLVM lowering pass would allow us to take the hard coded stuff out of the C backend, and have all of the backends use it. In the future, when there is time, we could implement zero cost exceptions as an _efficiency improvement_ instead of living with this missing feature. As such, I'm changing the Bug 15 to be a duplicate of this bug, and changing the subject of this PR. -Chris
*** Bug 15 has been marked as a duplicate of this bug. ***
This bug is now fixed. Patch here: http://mail.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20040202/011324.html Testcase here: test/Regression/CodeGen/X86/2004-02-08-UnwindSupport.llx Because SJLJ exceptions are potentially expensive, they default to being off. If the program throws an exception, it will terminate, with this message: "Exception handler needed, but not enabled. Recompile program with -enable-correct-eh-support.". In the testsuite, a program should set 'REQUIRES_EH_SUPPORT = 1' in the makefile if it needs exception handling support (for longjmp or throw). I finally got around to doing this, because having all of the EH singlesource tests fail on LLC/JIT masks real problems. :( Both the X86 and Sparc code generators should now support invoke/unwind property. Now all Regression/C++/EH tests pass, for example. -Chris