Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

_Unwind_Resume() call in landingpad for C++ EH is sometimes dead code #20674

Closed
llvmbot opened this issue Jul 14, 2014 · 3 comments
Closed

_Unwind_Resume() call in landingpad for C++ EH is sometimes dead code #20674

llvmbot opened this issue Jul 14, 2014 · 3 comments
Labels
bugzilla Issues migrated from bugzilla tools:llc

Comments

@llvmbot
Copy link
Collaborator

llvmbot commented Jul 14, 2014

Bugzilla Link 20300
Resolution FIXED
Resolved on Feb 19, 2015 19:10
Version trunk
OS Linux
Reporter LLVM Bugzilla Contributor
CC @rnk

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:

    callq   __cxa_begin_catch
    movl    $123, caught(%rip)
    popq    %rax
    jmp     __cxa_end_catch         # TAILCALL

.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?

@rnk
Copy link
Collaborator

rnk commented Jan 27, 2015

I just ran into this and was about to file this but, but apparently you already have.

@llvmbot
Copy link
Collaborator Author

llvmbot commented Jan 27, 2015

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?

By the way, GCC has the same issue.

@rnk
Copy link
Collaborator

rnk commented Feb 20, 2015

Should be fixed in r229944.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 9, 2021
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla tools:llc
Projects
None yet
Development

No branches or pull requests

2 participants