Hi, 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. Ciao, ichael.