On Tue, 6 Mar 2018, Richard Biener wrote:

> >   bb1
> >   ret = setjmp(buf)
> >    |       \              bb-recv
> >    |        ----------------\
> >    |                ret = setjmp_receiver
> >    |                        /
> >   normal   /---------------/
> >   path    /
> >    |     /
> >   bb-succ
> >
> > None of these edges would be abnormal.  bb-recv would be the target for
> > edges from all calls that might call longjmp(buf).  Those edges might need
> > to be abnormal.  As the above CFG reflects all runtime effects precisely,
> > but not which instructions are used to achieve them the expansion to RTL
> > will be special.
> Why do you still have the edge from setjmp to the setjmp receiver?

Ah, yes, that needs explanation.  Without that edge the receiver hangs in 
the air, so to speak.  But all effects that happened before the setjmp 
invocation also have happened before the second return, so the 
setjmp_receiver needs to be dominated by the setjmp call, and that 
requires and CFG edge.  A different way of thinking about this is that 
both "calls" need VDEF/VUSE, and the VUSE of setjmp_receiver needs to be 
the VDEF of the setjmp, so again that edge needs to be there for ordering 
reasons.  At least that's the obvious way of ordering.  Thinking harder 
might make the edge unnecessary after all: all paths leading to longjmps 
need to go through a setjmp, so the call->receiver edges are already 
ordered behind setjmp calls (though not necessarily dominated by them), so 
the receiver is, and so we might be fine.  I'd have to paint some pictures 
on our board to see how this behaves with multiple reaching setjmps.

> In your scheme ret is set twice on the longjmp return path, no?

No, it's set once on the first-return path, and once on the second-return 
path (from longjmp to setjmp_receiver, which sets ret, the set of the 
setjmp call isn't done on the second-return path).  Which is indeed what 
happens in reality, the return register is set once on first-return and 
once on second-return.

> That is, you have the same issue left as we have with EH returns from a 
> stmt with a LHS.

I don't see that, which problem?

> We currently have two outgoing edges from setjmp, one which feeds back 
> to right before the setjmp call via the abnormal dispatcher (so it looks 
> like a loop).  Jeffs change will make it two outgoing edges to the same 
> single successor, one dispatched through the abnormal dispatcher (that 
> also nicely gets around the limitation of only having a single edge 
> between two blocks...)

The crucial thing that needs to happen is that all paths from longjmp to 
the normal successor of the setjmp call contain an assignment to LHS.  
The edges out of setjmp aren't the important thing for this, the 
destination of edges from the dispatcher are (because that's the one 
targeted by the longjmp calls).  And IIUC Jeffs patch makes those edges 
target something after the LHS-set, and this can't be right.  Make the 
dispatcher set an LHS (and hence have one per setjmp, not one per 
function) and you're effectively ending up with my proposal above.


Reply via email to