[PATCH] D108905: [ItaniumCXXABI] Set nounwind on __cxa_begin_catch/__cxa_end_catch nounwind
Fangrui Song via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 29 23:36:27 PDT 2021
MaskRay created this revision.
MaskRay added reviewers: ChuanqiXu, rjmccall.
MaskRay requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
See https://lists.llvm.org/pipermail/cfe-dev/2021-August/068740.html
A catch clause calls __cxa_begin_catch/__cxa_end_catch.
This allows a function with all non-nounwind callees surrounded by catch
(...) can infer the nounwind attribute, e.g.
`void test() { try { can_throw(); } catch (...) {}}`
This can avoid unneeded call site records whose action record offset is 0
(cleanup). In addition, a `__clang_call_terminate` define may be avoided.
Note: libcxxrt `__cxa_end_catch` doesn't call external functions. libsupc++/libc++abi
`__cxa_end_catch` calls `_Unwind_DeleteException` for a foreign exception.
We can except `_Unwind_DeleteException` does not throw (the behavior would be unclear
if it throws).
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D108905
Files:
clang/lib/CodeGen/ItaniumCXXABI.cpp
clang/test/CodeGenCXX/exceptions.cpp
clang/test/CodeGenCXX/stack-reuse-exceptions.cpp
Index: clang/test/CodeGenCXX/stack-reuse-exceptions.cpp
===================================================================
--- clang/test/CodeGenCXX/stack-reuse-exceptions.cpp
+++ clang/test/CodeGenCXX/stack-reuse-exceptions.cpp
@@ -86,8 +86,8 @@
//
// CHECK: [[CATCH]]:
// CHECK-NOT: call void @llvm.lifetime
-// CHECK: invoke void
-// CHECK-NEXT: to label %[[TRY_CONT]] unwind label %[[OUTER_LPAD:.+]]
+// CHECK: call void @__cxa_end_catch
+// CHECK-NEXT: br label %[[TRY_CONT]]
//
// CHECK: [[TRY_CONT]]:
// CHECK: %[[T_OUTER:[^ ]+]] = bitcast %struct.Large* %{{[^ ]+}} to i8*
@@ -100,15 +100,7 @@
// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]])
// CHECK: ret void
//
-// CHECK: [[OUTER_LPAD]]:
-// CHECK-NOT: call void @llvm.lifetime
-// CHECK: br label %[[EHCLEANUP:.+]]
-//
-// CHECK: [[OUTER_LPAD2]]:
-// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[T_OUTER]])
-// CHECK: br label %[[EHCLEANUP]]
-//
-// CHECK: [[EHCLEANUP]]:
+// CHECK: lpad[[#]]:
// CHECK: call void @llvm.lifetime.end.p0i8({{[^,]+}}, i8* nonnull %[[CLEAN]])
NontrivialDtor clean;
Index: clang/test/CodeGenCXX/exceptions.cpp
===================================================================
--- clang/test/CodeGenCXX/exceptions.cpp
+++ clang/test/CodeGenCXX/exceptions.cpp
@@ -326,9 +326,12 @@
}
}
+// CHECK11-LABEL: declare{{.*}} i8* @__cxa_begin_catch(i8*) #[[#NOUNWIND:]]
+
// PR9303: invalid assert on this
namespace test6 {
bool cond();
+ // CHECK11-LABEL: define{{.*}} void @_ZN5test64testEv() #[[#TEST6:]]
void test() {
try {
lbl:
@@ -634,3 +637,6 @@
}
// CHECK98: attributes [[NI_NR_NUW]] = { noinline noreturn nounwind }
+
+// CHECK11: attributes #[[#NOUNWIND]] = { nounwind }
+// CHECK11: attributes #[[#TEST6]] = {{.*}} nounwind
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -4393,7 +4393,12 @@
llvm::FunctionType *FTy = llvm::FunctionType::get(
CGM.Int8PtrTy, CGM.Int8PtrTy, /*isVarArg=*/false);
- return CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
+ // Set nounwind so that a function with all non-nounwind callees surrounded by
+ // catch (...) can infer nounwind, which can avoid unneded call site records.
+ llvm::FunctionCallee Ret =
+ CGM.CreateRuntimeFunction(FTy, "__cxa_begin_catch");
+ cast<llvm::Function>(Ret.getCallee())->addFnAttr(llvm::Attribute::NoUnwind);
+ return Ret;
}
static llvm::FunctionCallee getEndCatchFn(CodeGenModule &CGM) {
@@ -4401,7 +4406,9 @@
llvm::FunctionType *FTy =
llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);
- return CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
+ llvm::FunctionCallee Ret = CGM.CreateRuntimeFunction(FTy, "__cxa_end_catch");
+ cast<llvm::Function>(Ret.getCallee())->addFnAttr(llvm::Attribute::NoUnwind);
+ return Ret;
}
static llvm::FunctionCallee getGetExceptionPtrFn(CodeGenModule &CGM) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D108905.369379.patch
Type: text/x-patch
Size: 3061 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20210830/5639d97f/attachment.bin>
More information about the cfe-commits
mailing list