LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 16 - [lowerinvoke] The -lowerinvoke pass does not insert calls to setjmp/longjmp
Summary: [lowerinvoke] The -lowerinvoke pass does not insert calls to setjmp/longjmp
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Scalar Optimizations (show other bugs)
Version: 1.0
Hardware: All All
: P normal
Assignee: Brian R. Gaeke
URL:
Keywords: missing-feature
: 15 (view as bug list)
Depends on:
Blocks:
 
Reported: 2003-10-07 17:08 PDT by Chris Lattner
Modified: 2010-02-22 12:43 PST (History)
2 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Lattner 2003-10-07 17:08:56 PDT
Summary says it all.
Comment 1 Chris Lattner 2003-10-14 14:56:57 PDT
Note that this prevents the 253.perlbmk benchmark from working with the X86 backend.
Comment 2 Brian R. Gaeke 2003-11-04 13:12:23 PST
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.
Comment 3 Chris Lattner 2003-11-04 13:18:45 PST
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
Comment 4 Brian R. Gaeke 2003-11-16 18:59:15 PST
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.
Comment 5 Chris Lattner 2003-11-16 19:02:50 PST
Yup, exactly on both parts.  Basically we will have to have a runtime library
that provides the unwinder.

-Chris
Comment 6 Chris Lattner 2003-11-16 19:06:37 PST
Oh, and llvm.return_address and llvm.frame_address will require code generator
support too.  :)

-Chris
Comment 7 Chris Lattner 2003-12-31 16:24:58 PST
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
Comment 8 Chris Lattner 2004-01-18 14:09:25 PST
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
Comment 9 Chris Lattner 2004-01-18 14:09:49 PST
*** Bug 15 has been marked as a duplicate of this bug. ***
Comment 10 Chris Lattner 2004-02-08 13:57:47 PST
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