You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Since the landingpad will only ever be entered with an exception type ID of 1 (representing the "int" type), the call to _Unwind_Resume() is dead code and could be omitted. Similarly, the check for the exception type ID could be omitted too.
The reason is that the LLVM IR for this function contains the following:
Since the "landingpad" IR instruction contains only a single "catch" clause (for "int") and no "cleanup" clause, the standard C++ personality routine will only enter the landingpad if the exception being thrown matches the "catch" clause.
The IR needs to contain the "resume" instruction and the typeid check in case this function gets inlined. However, once this code reaches the LLVM backend, we know that the backend is not going to inline the function. The backend could simplify the code given that %3 will always be 1. Maybe this could be added as an optimisation to lib/CodeGen/DwarfEHPrepare.cpp?
The text was updated successfully, but these errors were encountered:
When I filed this, I meant to ping some people who are familiar with DWARF/Itanium exception handling to check that my understanding here was correct, but I never got around to doing that.
It's hard to tell how worthwhile it would be to optimise this. Are there any good benchmarks for C++ exception handling that we could use for comparing code size before and after a codegen change?
Extended Description
This is an opportunity for reducing the size of generated code for C++ source that catches exceptions.
When I compile the following function, LLVM/Clang generates an unnecessary call to _Unwind_Resume() in the landingpad code:
void external_func();
extern int caught;
void foo() {
try {
external_func();
} catch (int) {
caught = 123;
}
}
$ clang cxx_exception_catch1.cc -S -o - -O2
...
// Landingpad for call to external_func():
movq %rdx, %rcx
movq %rax, %rdi
cmpl $1, %ecx // Check exception type ID
jne .LBB0_4
BB#3:
.LBB0_4:
callq _Unwind_Resume
...
Since the landingpad will only ever be entered with an exception type ID of 1 (representing the "int" type), the call to _Unwind_Resume() is dead code and could be omitted. Similarly, the check for the exception type ID could be omitted too.
The reason is that the LLVM IR for this function contains the following:
$ clang cxx_exception_catch1.cc -S -o - -O2 -emit-llvm
...
; Landingpad:
%2 = landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
catch i8* bitcast (i8** @_ZTIi to i8*)
%3 = extractvalue { i8*, i32 } %2, 1
%4 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #3
%5 = icmp eq i32 %3, %4
br i1 %5, label %6, label %10
; Handle exception:
; :6 ; preds = %1
%7 = extractvalue { i8*, i32 } %2, 0
%8 = tail call i8* @__cxa_begin_catch(i8* %7) #3
store i32 123, i32* @caught, align 4, !tbaa !1
tail call void @__cxa_end_catch() #3
ret void
; Resume unwinding from exception:
; :10 ; preds = %1
resume { i8*, i32 } %2
Since the "landingpad" IR instruction contains only a single "catch" clause (for "int") and no "cleanup" clause, the standard C++ personality routine will only enter the landingpad if the exception being thrown matches the "catch" clause.
The IR needs to contain the "resume" instruction and the typeid check in case this function gets inlined. However, once this code reaches the LLVM backend, we know that the backend is not going to inline the function. The backend could simplify the code given that %3 will always be 1. Maybe this could be added as an optimisation to lib/CodeGen/DwarfEHPrepare.cpp?
The text was updated successfully, but these errors were encountered: