https://llvm.org/bugs/show_bug.cgi?id=1269
Reid Kleckner <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED CC| |[email protected], | |[email protected] Resolution|WONTFIX |--- Summary|Add support for "non-call" |Add support for |exceptions, eliminate |asynchronous "non-call" |invoke |exceptions, eliminate | |invoke/call dichotomy --- Comment #36 from Reid Kleckner <[email protected]> --- People keep asking for this, so we should probably reopen this and write down some of the better ideas we've had for doing it here. --- The original idea that Chris outlined boils down to implicitly allowing every possibly trapping instruction to have an implicit exceptional control flow edge. Correct optimizations would have to remember to check for this edge before hoisting, sinking, or doing any of the things they normally do. The fact that this is all implicit is what seems to bug most folks that I've discussed this with. I happen to think we could make this work. We could add a method like getUnwindLabel to Instruction that checks if the instruction may trap and pulls the unwind label off the BasicBlock if present. The fact that it's on the BB and not the Instruction is merely a memory usage optimization. Then we'd have to audit all the optimizations, of which there are many. Passes like simplifycfg would be required to avoid joining BBs with different unwind edge labels. --- As an alternative to the implicit design, we could try something that makes the edges very explicit. The first approach is to build a pile of intrinsics for every possibly trapping operation that we care to support catching (load, store, fpmath, div, leave the rest unsupported). We can then invoke these intrinsics and allow the backend to do the usual EH_LABEL lowering around the instruction. Alternatively, we could make first class instructions for them (iload/istore, as Peter proposed). This is just making the duplication between the call and invoke instructions worse, though, as now optimizers have to match more instructions that do the same things. --- Another way we could do this is by making the 'invoke' instruction a wrapper that uses or contains an arbitrary other instruction. The invoke wrapper takes any instruction and essentially promotes it to a terminator with a normal edge and an exceptional edge. The in-memory representation would be that the possibly-trapping instruction precedes the invoke instruction in the basic block ilist, and the invoke instruction has a use of the trapping instruction. This would require auditing for passes that would insert code between the two instructions, but we'd handle it just like we did for landingpads: add a getLastInsertionPt() to go along with getFirstInsertionPt(). We could also relax the invariant to allow non-trapping instructions (bitcasts, adds, dbg intrinsics) between the trapping instruction and the invoke. The assembly syntax for this would be: invoke <any instruction> to label %normal_edge unwind label %ehedge The standard call syntax would be: invoke call void @f() to label %normal_edge unwind label %ehedge %x = invoke call i32 @g() to label %normal_edge unwind label %ehedge For stores, the other big void type instruction: invoke store i32 0, i32* null to label %normal_edge unwind label %ehedge We can still support the old invoke syntax by checking if the token following 'invoke' names an instruction or a type. The old syntax: invoke void @f() to label %normal_edge unwind label %ehedge %x = invoke i32 @g() to label %normal_edge unwind label %ehedge ---- I have no intention of immediately working on this stuff, but I figured I should dump some ideas in the bug tracker. -- You are receiving this mail because: You are on the CC list for the bug.
_______________________________________________ LLVMbugs mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/llvmbugs
