[LLVMdev] An alternate implementation of exceptions

Mikael Lyngvig mikael at lyngvig.org
Fri Sep 4 04:52:18 PDT 2009


Hi Duncan,

I agree on the problem about linking with code - I actually do mention
this in the paper.  I propose adding a new calling convention called
"excall".

The central point of my paper is that only one parameter is needed as the
return value (because of the use of the flag): the EAX register can safely
be used for both the exception instance and the return value as these
never appear simultaneously.  That's the primary reason I use the Carry
flag: To avoid allocating a global variable, a thread variable or an
entire register solely for communicating exception conditions.  Especially
on register scarce architectures (vink, vink, Intel), it is important to
avoid allocating an entire register for the purpose of signaling a single
bit of information: 1 = an exception has occurred, 0 = no exception has
occurred.  Also, when you use a register, instead of a flag, to indicate
the exception condition, the caller must explicitly check if the register
is non-zero - this adds some overhead compared to the simple
"jump-if-carry" instruction.

Thanks for looking at my stuff and I can only say that I am HAPPY that
this method is already known.  I have not seen it implemented in any of
the compilers I use, but the most important thing for me is just that the
method is so great -- about four to five times faster than the traditional
stack unwind method (try expands to setjmp, throw expands to longjmp) --
that I wanted to make sure that somebody somewhere knew about the method.

I think I'll take my ideas to the OpenWatcom C++ mailing list as the
OpenWatcom compiler uses setjmp()/longjmp() in its exception handling
implementation (despite being one of the best compilers on the Intel
platform).

Cheers,
Mikael Lyngvig

> Hi Mikael, the idea of modifying functions so they return two parameters
> (the usual one and an exception pointer or some kind of exception flag)
> is well known.  The LLVM vmkit project actually uses a variant of this:
> rather than returning the exception pointer in a register, it sticks it
> in a global thread local variable.
>
> I only took a quick look at your paper, but it seems to me that it has
> a serious problem: you can't link C code using your exception handling
> mechanism with C code compiled using another compiler, since the carry
> flag may not be cleared on function return by the code compiled by the
> other compiler.  Perhaps you addressed this issue in your paper, as I
> mentioned I only glanced at it.  Vmkit doesn't suffer from this problem,
> since only code that is aware of vmkit exceptions will store in the
> global.
>
> Also, I don't see the point of the carry flag.  Why don't you just
> return the exception pointer in another register?  If it is non-null
> then an exception was raised.  Are you trying to avoid register
> pressure or save a cycle or two?
>
> Finally, you could implement this (or something close to it) pretty
> easily in LLVM.  Suppose you have a function "int f(params) {...}".
> Rather than outputting this to LLVM IR as
>    define i32 @f(params) { ... }
> you output it as
>    define {i32, i8*} @f(params) { ... }
> The additional return value is the exception pointer, which callers
> can then inspect to see whether an exception was raised.  On x86-64
> codegen will return the i32 in RAX and the exception pointer in RDX.
>
> Ciao,
>
> Duncan.
>





More information about the llvm-dev mailing list