[LLVMdev] nonlocal go to -- how?

Duncan Sands baldrick at free.fr
Mon May 5 00:56:26 PDT 2008


Hi,

> The problem is with the go to statement.  Again, local go to's, that go 
> somewhere within the same function are no particular problem -- though I 
> haven't studied the interaction with alloca yet; that might offer a few 
> surprises.  The questions I have are about goto's that exit from a 
> function.  The traditional mechanism is to implement a label as an 
> instruction-pointer/environment-pointer pair, just as for procedures.  
> You just load the environment-pointer into the appropriate register, and 
> jump to the address.  (again there are technical details about the size 
> of the local stack at the destination, disposition of alloca storage, and 
> the like, and nowadays, unwinding the stack).
> 
> I don't see a mechanism for this.

you can roll your unwinder using multiple return values (support for functions
that return multiple values was recently added): the first return value is the
usual function return value; the next one is the nesting depth to which you
want to go (I'm assuming that you can only go to a less nested function); the last
one is a number indicating which label in the final function you want to branch to.

A non-local goto (to function F, label L) becomes:
  ret { undef, F_static_depth, L_number }
After every call to this function you then check the second return value to see if
it is a valid static depth (if not, no non-local goto happened and execution
continues normally) and if it is then either: (a) the static depth is that for
this function; you then execute a switch statement using L_number that branches
to the right label; or (b) the static depth is for a lexically less nested
function, and you again execute ret { undef, F_static_depth, L_number }

> The closest I see is the mechanism for exceptions.  I cannot tell by 
> reading the documentation for exception-handling whether it is 
> sufficiently flexible to accomodate nonlocal goto's.  It's plain that on 
> modern systems (which dribble saved registers all over the sack) some 
> kind of unwinding is necessary, and that the traditional model of loading 
> a register and jumping is no longer sufficient.  What's not clear is 
> whether the exception handling mechanism is sufficiently dynamic to 
> permit an accurate specification of the jump target.  It's not 
> necessarily the most local version of the label on the stack that's the 
> target; it's the one whose stack frame is reached by the jumping 
> procedure's array of static links.

The problem with unwinding is that you need to have a personality
function and writing your own is a pain.  On my infinite list of
things to do is working out how to codegen invoke when there is no
personality function, and how to codegen unwind.

Ciao,

Duncan.



More information about the llvm-dev mailing list