[LLVMdev] invoke/unwind
Mike Stump
mrs at apple.com
Wed Jan 13 11:11:10 PST 2010
On Jan 13, 2010, at 9:27 AM, Dustin Laurence wrote:
> So how is clang doing C++ exceptions?
Roughly, like so:
$ cat t.cc
int main() {
try { throw 1; } catch (int i) { }
}
$ clang -S t.cc -emit-llvm
$ cat t.s
; ModuleID = 't.cc'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin10.0"
@_ZTIi = external constant i8* ; <i8**> [#uses=1]
define i32 @main() ssp {
entry:
%retval = alloca i32 ; <i32*> [#uses=2]
%exception.ptr = alloca i8* ; <i8**> [#uses=1]
%_rethrow = alloca i8* ; <i8**> [#uses=4]
%i = alloca i32, align 4 ; <i32*> [#uses=1]
%cleanup.dst = alloca i32 ; <i32*> [#uses=3]
%cleanup.dst6 = alloca i32 ; <i32*> [#uses=5]
store i32 0, i32* %retval
%exception = call i8* @__cxa_allocate_exception(i64 4) ; <i8*> [#uses=3]
store i8* %exception, i8** %exception.ptr
%0 = bitcast i8* %exception to i32* ; <i32*> [#uses=1]
store i32 1, i32* %0
invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) noreturn
to label %invoke.cont unwind label %try.handler
invoke.cont: ; preds = %entry
unreachable
terminate.handler: ; preds = %match.end
%exc = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
%1 = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exc, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 1) ; <i32> [#uses=0]
call void @_ZSt9terminatev() noreturn nounwind
unreachable
try.handler: ; preds = %entry
%exc1 = call i8* @llvm.eh.exception() ; <i8*> [#uses=3]
%selector = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exc1, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i8* bitcast (i8** @_ZTIi to i8*), i8* null) ; <i32> [#uses=1]
%2 = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) ; <i32> [#uses=1]
%3 = icmp eq i32 %selector, %2 ; <i1> [#uses=1]
br i1 %3, label %match, label %catch.next
match: ; preds = %try.handler
%4 = call i8* @__cxa_begin_catch(i8* %exc1) ; <i8*> [#uses=1]
%5 = bitcast i8* %4 to i32* ; <i32*> [#uses=1]
%6 = load i32* %5 ; <i32> [#uses=1]
store i32 %6, i32* %i
store i32 1, i32* %cleanup.dst
br label %match.end
match.handler: ; No predecessors!
%exc2 = call i8* @llvm.eh.exception() ; <i8*> [#uses=2]
%7 = call i32 (i8*, i8*, ...)* @llvm.eh.selector(i8* %exc2, i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*), i32 0) ; <i32> [#uses=0]
store i8* %exc2, i8** %_rethrow
store i32 2, i32* %cleanup.dst
br label %match.end
cleanup.pad: ; preds = %cleanup.switch
store i32 1, i32* %cleanup.dst6
br label %finally
cleanup.pad3: ; preds = %cleanup.switch
store i32 2, i32* %cleanup.dst6
br label %finally
match.end: ; preds = %match.handler, %match
invoke void @__cxa_end_catch()
to label %invoke.cont4 unwind label %terminate.handler
invoke.cont4: ; preds = %match.end
br label %cleanup.switch
cleanup.switch: ; preds = %invoke.cont4
%tmp = load i32* %cleanup.dst ; <i32> [#uses=1]
switch i32 %tmp, label %cleanup.end [
i32 1, label %cleanup.pad
i32 2, label %cleanup.pad3
]
cleanup.end: ; preds = %cleanup.switch
%exc5 = call i8* @llvm.eh.exception() ; <i8*> [#uses=1]
store i8* %exc5, i8** %_rethrow
store i32 2, i32* %cleanup.dst6
br label %finally
catch.next: ; preds = %try.handler
store i8* %exc1, i8** %_rethrow
store i32 2, i32* %cleanup.dst6
br label %finally
finally: ; preds = %catch.next, %cleanup.end, %cleanup.pad3, %cleanup.pad
br label %cleanup.switch8
cleanup.switch8: ; preds = %finally
%tmp7 = load i32* %cleanup.dst6 ; <i32> [#uses=1]
switch i32 %tmp7, label %cleanup.end9 [
i32 1, label %finally.end
i32 2, label %finally.throw
]
cleanup.end9: ; preds = %cleanup.switch8
br label %finally.end
finally.throw: ; preds = %cleanup.switch8
%8 = load i8** %_rethrow ; <i8*> [#uses=1]
call void @_Unwind_Resume_or_Rethrow(i8* %8)
unreachable
finally.end: ; preds = %cleanup.end9, %cleanup.switch8
%9 = load i32* %retval ; <i32> [#uses=1]
ret i32 %9
}
declare i32 @__gxx_personality_v0(...)
declare i8* @llvm.eh.exception() nounwind readonly
declare i32 @llvm.eh.selector(i8*, i8*, ...) nounwind
declare i8* @__cxa_allocate_exception(i64)
declare void @__cxa_throw(i8*, i8*, i8*)
declare void @_ZSt9terminatev()
declare i32 @llvm.eh.typeid.for(i8*) nounwind
declare i8* @__cxa_begin_catch(i8*)
declare void @__cxa_end_catch()
declare void @_Unwind_Resume_or_Rethrow(i8*)
More information about the llvm-dev
mailing list