[LLVMdev] Does nounwind have semantics?

Andrew Trick atrick at apple.com
Mon Jul 22 01:23:08 PDT 2013


On Jul 22, 2013, at 12:56 AM, Duncan Sands <baldrick at free.fr> wrote:

> my understanding is different.  I'm pretty sure that what I'm about to say is
> the traditional way these things have been viewed in LLVM.  That doesn't mean
> that it's the best way to view these things.
> 
>> - nounwind means no dwarf EH. Absence
> 
> I guess you mean presence.
> 
> of nounwind means absence of dwarf EH. It
>> would be unwise for optimization passes to reason about the semantics beyond
>> that. I was momentarily mislead by the LICM code that handles MayThrow specially.
> 
> nounwind has nothing to do with dwarf, since exceptions themselves need have
> nothing to do with dwarf (which is just one way of implementing exception
> handling).  Don't forget setjmp/longjmp exception handling, and also exception
> handling by returning an extra invisible parameter (which I mentioned in
> another email) which IIRC was actually implemented by someone at the codegen
> level at some point as it was faster than dwarf for code that throws exceptions
> a lot.  An additional point is that while in C++ you create an exception object,
> not all languages associate an object with an exception, some just want to do
> the equivalent of a non-local goto.  Creating an exception object means
> allocating memory, mucking around with global data structures and obviously
> writing memory.  A non-local goto doesn't have to do more than unwind the stack
> until it gets to the right frame then do a jump.  It's not clear to me that that
> should be considered as writing memory.
> 
> Here's my take: a call to an function marked nounwind either never returns
> (eg infinite loop or exits the program) or returns normally.  It doesn't
> "return" by unwinding the stack out of the caller.  On the other hand a
> function that is not marked nounwind may "return" by unwinding the stack;
> control in this case doesn't continue in the caller, it continues at least one
> further up the stack.  Thus in this case the instructions after the call
> instruction are not executed.  Note I'm talking about an ordinary call here,
> not an invoke.  In the case of an invoke control may continue in the caller
> function, but only at a well-defined point (the landing pad).

Good explanation. Your definition of nounwind is completely logical. I would prefer not to rely on it though because
- Realistically, the semantics won’t be well tested.
- It doesn’t seem terribly important to treat nonlocal gotos as readonly (though maybe it is to you :)
- When it is important to optimize memory access around nonlocal gotos, I prefer to expose control flow to the optimizer explicitly.
e.g. why not just use invokes for all your may-throw calls, then you’re free to mark them readonly?

-Andy

>> - Things that throw exceptions or trap in defined ways are not readonly.
> 
> See above for why throwing an exception doesn't have to write memory.  Dwarf
> exception handling, and anything which can be used to implement C++ exception
> handling, is clearly writing memory and thus cannot be used inside a readonly
> function.  So yes, any function Clang produces that throws an exception is not
> going to be readonly.  But as I mentioned above some languages have no
> exception object and just unwind the stack.  For these the expression "throwing
> an exception" (which implicitly includes the idea that there is an exception
> object) is not really appropriate; "unwinds the stack" is the basic concept
> here.  This is basically orthogonal to readonly.
> 
>> - Runtime checks for overflow, div-by-zero, bounds checks, etc. should be
>> implemented at the IR level as branches to noreturn calls because it can be done
>> that way and I haven’t seen concrete evidence that it’s too expensive. Don’t try
>> to do something fancy with intrinsics and attributes unless absolutely required.
> 
> I agree with this.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130722/ccfcb60f/attachment.html>


More information about the llvm-dev mailing list