[LLVMdev] RFC: Native Windows C++ exception handling (original) (raw)
Kaylor, Andrew andrew.kaylor at intel.com
Tue Jan 27 10:44:28 PST 2015
- Previous message: [LLVMdev] RFC: Native Windows C++ exception handling
- Next message: [LLVMdev] RFC: Native Windows C++ exception handling
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
I was thinking about this last night, and I came up with a third alternative which I think looks very promising. It’s basically a re-working of the previous alternative to use the landingpad concept rather than arbitrary fake logic, but it uses a single landing pad for the entire function that mimics the logic of the personality function to dispatch unwinding calls and catch handlers.
I believe this is consistent with the semantics and spirit of the existing landingpad mechanism, and it still has the properties that allow the required .xdata information to be easily extracted from the IR. It will require a new representation after the handlers have been outlined, but I have an idea for that which I’ll send out later today.
If we go this way, the inlining code will need to be taught to merge the landingpad of the inlined function, but I think that will be pretty easy.
So, here it is:
void test() { try { Outer outer; try { Inner inner; do_inner_thing(); } catch (int) { handle_int(); } } catch (float) { handle_float(); } keep_going(); }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Original ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Function Attrs: uwtable define void @_Z4testv() #0 { entry: %outer = alloca %class.Outer, align 1 %inner = alloca %class.Inner, align 1 call void @llvm.eh.setehstate(i32 0) invoke void @_ZN5OuterC1Ev(%class.Outer* %outer) to label %invoke.cont unwind label %lpad
invoke.cont: call void @llvm.eh.setehstate(i32 1) call void @llvm.eh.setehstate(i32 2) invoke void @_ZN5InnerC1Ev(%class.Inner* %inner) to label %invoke.cont1 unwind label %lpad
invoke.cont.1: call void @llvm.eh.setehstate(i32 3) invoke void @_Z14do_inner_thingv() to label %invoke.cont2 unwind label %lpad
invoke.cont2: call void @llvm.eh.setehstate(i32 2) invoke void @_ZN5InnerD1Ev(%class.Inner* %inner) to label %invoke.cont3 unwind label %lpad
invoke.cont3: call void @llvm.eh.setehstate(i32 1) invoke void @_ZN5OuterD1Ev(%class.Outer* %outer) to label %invoke.cont4 unwind label %lpad
invoke.cont4: call void @llvm.eh.setehstate(i32 0) call void @llvm.eh.setehstate(i32 -1) call void @_Z10keep_goingv() ret void
lpad: %eh.vals = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) cleanup catch i8* bitcast (i8** @_ZTIi to i8*) catch i8* bitcast (i8** @_ZTIf to i8*) %eh.ptrs = extractvalue { i8*, i32 } %eh.vals, 0 %eh.sel = extractvalue { i8*, i32 } %eh.vals, 1 br label %unwind.handlers
unwind.handlers: %unwind.state = call i32 @llvm.eh.getunwindstate(%eh.ptrs) br label %unwind.dispatch
unwind.dispatch: %4 = icmp eq i32 %unwind.state, i32 1 br i1 %4, label %unwind.handler.1, label %unwind.dispatch.1
unwind.handler.1: call void @_ZN5OuterD1Ev(%class.Outer* %outer) resume { i8*, i32 } %eh.vals
unwind.dispatch: %5 = icmp eq i32 %unwind.state, i32 3 br i1 %5, label %unwind.handler.3, label %catch.handlers
unwind.handler.3: call void @_ZN5InnerD1Ev(%class.Inner* %inner) resume { i8*, i32 } %eh.vals
catch.handlers: %catch.state = call i32 @llvm.eh.getcatchstate(i8* %eh.ptrs) br label %catch.dispatch
catch.dispatch.1: %6 = icmp sge i32 %catch.state, i32 2 br i1 %6, label %catch.1.lower.true, label %catch.dispatch.2
catch.1.lower.true %7 = icmp sle i32 %catch.state, i32 3 br i1 %7, label %catch.1.state.matches, label %catch.dispatch.2
catch.1.state.matches: %sel.1 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) %matches.1 = icmp eq i32 %sel.1, i32 %eh.sel br i1 %matches.1, label %catch.1.handler, label %catch.dispatch.2
catch.1.handler: call void @llvm.eh.setehstate(i32 4) call void @_Z10handle_intv() br label %invoke.cont3
catch.dispatch.2: %8 = icmp sge i32 %catch.state, i32 0 br i1 %8, label %catch.2.lower.true, label %catch.nomatch
catch.2.lower.true %9 = icmp sle i32 %catch.state, i32 4 br i1 %9, label %catch.2.state.matches, label %catch.nomatch
catch.2.state.matches: %sel.2 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIf to i8*)) %matches.2 = icmp eq i32 %sel.2, i32 %eh.sel br i1 %matches.2, label %catch.2.handler, label %catch.nonmatch
catch.2.handler: call void @llvm.eh.setehstate(i32 5) call void @_Z12handle_floatv() br label %invoke.cont4
catch.nomatch: resume { i8*, i32 } %eh.vals }
-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150127/edff9a72/attachment.html>
- Previous message: [LLVMdev] RFC: Native Windows C++ exception handling
- Next message: [LLVMdev] RFC: Native Windows C++ exception handling
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]