Andrew Trick
2011-Jun-14 07:16 UTC
[LLVMdev] Is LLVM expressive enough to represent asynchronous exceptions?
On Jun 13, 2011, at 11:18 PM, Chris Lattner wrote:> > On Jun 13, 2011, at 3:15 PM, Jakob Stoklund Olesen wrote: > >> >> On Jun 13, 2011, at 2:52 PM, Chris Lattner wrote: >> >>> Synchronous exceptions like divide by zero or null pointer derefs are another thing entirely though. >> >> When runtimes support this, do they preserve all registers or just the non-volatile registers, like a normal unwinder? How is information about the exception passed to the landing pad? > > The idea is that each of these potentially trapping synchronous operations needs to be treated as a potential control flow operation, just like "invoke" is to "call".I think Jakob wants to know if the register allocator needs to clobber volatile regs at the trapping instructions. One way to model the trap is exactly like a conditional branch to the handler. In fact, whether the code emitter generates a trapping instruction or a conditional branch can be considered a detail of code emission that is hidden from the register allocator. This helps make the optimization of error checking code language and target independent--it's really the same problem whether the language supports exceptions or the target+runtime supports resuming from trapping instructions. Maybe that's not obvious to folks yet because the C front end doesn't currently tell the optimizer which conditions are exceptional--something that could be rectified. Anyway back to the point... if traps are modeled this way, then of course the runtime must preserve all registers. If there are no handlers or cleanup code, the CFG looks gratuitous on visual inspection, which I think is the objection to this representation. -Andy
Chris Lattner
2011-Jun-14 16:20 UTC
[LLVMdev] Is LLVM expressive enough to represent asynchronous exceptions?
On Jun 14, 2011, at 12:16 AM, Andrew Trick wrote:> On Jun 13, 2011, at 11:18 PM, Chris Lattner wrote: > >> >> On Jun 13, 2011, at 3:15 PM, Jakob Stoklund Olesen wrote: >> >>> >>> On Jun 13, 2011, at 2:52 PM, Chris Lattner wrote: >>> >>>> Synchronous exceptions like divide by zero or null pointer derefs are another thing entirely though. >>> >>> When runtimes support this, do they preserve all registers or just the non-volatile registers, like a normal unwinder? How is information about the exception passed to the landing pad? >> >> The idea is that each of these potentially trapping synchronous operations needs to be treated as a potential control flow operation, just like "invoke" is to "call". > > I think Jakob wants to know if the register allocator needs to clobber volatile regs at the trapping instructions.Yes, certainly. This isn't an IR-level issue though.> One way to model the trap is exactly like a conditional branch to the handler. In fact, whether the code emitter generates a trapping instruction or a conditional branch can be considered a detail of code emission that is hidden from the register allocator. This helps make the optimization of error checking code language and target independent--it's really the same problem whether the language supports exceptions or the target+runtime supports resuming from trapping instructions. Maybe that's not obvious to folks yet because the C front end doesn't currently tell the optimizer which conditions are exceptional--something that could be rectified. Anyway back to the point... if traps are modeled this way, then of course the runtime must preserve all registers.The point of this, for me, is that we need to distinguish in the IR a load that can trap with defined behavior (e.g. Java) from a load that cannot (e.g. C). Given that you need to capture this in the IR, it "simply" becomes a matter of exposing the right info at the Machine level as well. It turns out that just doing this at the IR level is full of tradeoffs and compromises, and hasn't been important enough for anyone to drive forward yet. -Chris
Andrew Trick
2011-Jun-14 17:07 UTC
[LLVMdev] Is LLVM expressive enough to represent asynchronous exceptions?
On Jun 14, 2011, at 9:20 AM, Chris Lattner wrote:> The point of this, for me, is that we need to distinguish in the IR a load that can trap with defined behavior (e.g. Java) from a load that cannot (e.g. C). Given that you need to capture this in the IR, it "simply" becomes a matter of exposing the right info at the Machine level as well. It turns out that just doing this at the IR level is full of tradeoffs and compromises, and hasn't been important enough for anyone to drive forward yet.It's also worth pointing out that Java can only trap on null pointer loads, assuming type checks remain. In that case, the trapping condition can be trivially expressed at the IR level, and whether H/W or S/W checks are ultimately emitted becomes a CodeGen detail. In fact, Java null checks are often removed by generic compiler optimization when expressed this way. I wonder if anyone cares about defined behavior (unwind+resume) from trapping loads when the trapping condition cannot already be expressed in the IR. -Andy
Apparently Analagous Threads
- [LLVMdev] Is LLVM expressive enough to represent asynchronous exceptions?
- [LLVMdev] Is LLVM expressive enough to represent asynchronous exceptions?
- [LLVMdev] Is LLVM expressive enough to represent asynchronous exceptions?
- [LLVMdev] Is LLVM expressive enough to represent asynchronous exceptions?
- [LLVMdev] Is LLVM expressive enough to represent asynchronous exceptions?