sgraenitz updated this revision to Diff 477470.
sgraenitz marked an inline comment as done.
sgraenitz added a comment.
Rebase and update check-lines after D137939 <https://reviews.llvm.org/D137939>
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D137944/new/
https://reviews.llvm.org/D137944
Files:
clang/test/CodeGenObjCXX/arc-exceptions-seh.mm
llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
llvm/test/Transforms/ObjCARC/funclet-catchpad.ll
Index: llvm/test/Transforms/ObjCARC/funclet-catchpad.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/ObjCARC/funclet-catchpad.ll
@@ -0,0 +1,40 @@
+; RUN: opt -mtriple=x86_64-windows-msvc -passes=objc-arc -S < %s | FileCheck %s
+
+; Check that funclet tokens are preserved
+;
+; CHECK-LABEL: catch:
+; CHECK: %1 = catchpad within %0
+; CHECK: %2 = tail call ptr @llvm.objc.retain(ptr %exn) #0 [ "funclet"(token %1) ]
+; CHECK: call void @llvm.objc.release(ptr %exn) #0 [ "funclet"(token %1) ]
+; CHECK: catchret from %1 to label %eh.cont
+
+define void @try_catch_with_objc_intrinsic() personality ptr @__CxxFrameHandler3 {
+entry:
+ %exn.slot = alloca ptr, align 8
+ invoke void @may_throw(ptr null) to label %eh.cont unwind label %catch.dispatch
+
+catch.dispatch: ; preds = %entry
+ %0 = catchswitch within none [label %catch] unwind to caller
+
+eh.cont: ; preds = %catch, %entry
+ ret void
+
+catch: ; preds = %catch.dispatch
+ %1 = catchpad within %0 [ptr null, i32 0, ptr %exn.slot]
+ br label %if.then
+
+if.then: ; preds = %catch
+ %exn = load ptr, ptr null, align 8
+ %2 = call ptr @llvm.objc.retain(ptr %exn) [ "funclet"(token %1) ]
+ call void @may_throw(ptr %exn)
+ call void @llvm.objc.release(ptr %exn) [ "funclet"(token %1) ]
+ catchret from %1 to label %eh.cont
+}
+
+declare void @may_throw(ptr)
+declare i32 @__CxxFrameHandler3(...)
+
+declare ptr @llvm.objc.retain(ptr) #0
+declare void @llvm.objc.release(ptr) #0
+
+attributes #0 = { nounwind }
Index: llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
===================================================================
--- llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
+++ llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
@@ -546,7 +546,9 @@
void MoveCalls(Value *Arg, RRInfo &RetainsToMove, RRInfo &ReleasesToMove,
BlotMapVector<Value *, RRInfo> &Retains,
DenseMap<Value *, RRInfo> &Releases,
- SmallVectorImpl<Instruction *> &DeadInsts, Module *M);
+ SmallVectorImpl<Instruction *> &DeadInsts,
+ const DenseMap<BasicBlock *, ColorVector> &BlockColors,
+ Module *M);
bool PairUpRetainsAndReleases(DenseMap<const BasicBlock *, BBState> &BBStates,
BlotMapVector<Value *, RRInfo> &Retains,
@@ -559,7 +561,7 @@
bool PerformCodePlacement(DenseMap<const BasicBlock *, BBState> &BBStates,
BlotMapVector<Value *, RRInfo> &Retains,
- DenseMap<Value *, RRInfo> &Releases, Module *M);
+ DenseMap<Value *, RRInfo> &Releases, Function &F);
void OptimizeWeakCalls(Function &F);
@@ -756,6 +758,18 @@
return CallInst::Create(&CI, OpBundles);
}
+
+void addOpBundleForFunclet(BasicBlock *BB,
+ const DenseMap<BasicBlock *, ColorVector> &BlockColors,
+ SmallVectorImpl<OperandBundleDef> &OpBundles) {
+ if (!BlockColors.empty()) {
+ const ColorVector &CV = BlockColors.find(BB)->second;
+ assert(CV.size() == 1 && "non-unique color for block!");
+ BasicBlock *EHPadBB = CV.front();
+ if (auto *EHPad = dyn_cast<FuncletPadInst>(EHPadBB->getFirstNonPHI()))
+ OpBundles.emplace_back("funclet", EHPad);
+ }
+}
}
/// Visit each call, one at a time, and make simplifications without doing any
@@ -1757,12 +1771,12 @@
}
/// Move the calls in RetainsToMove and ReleasesToMove.
-void ObjCARCOpt::MoveCalls(Value *Arg, RRInfo &RetainsToMove,
- RRInfo &ReleasesToMove,
- BlotMapVector<Value *, RRInfo> &Retains,
- DenseMap<Value *, RRInfo> &Releases,
- SmallVectorImpl<Instruction *> &DeadInsts,
- Module *M) {
+void ObjCARCOpt::MoveCalls(
+ Value *Arg, RRInfo &RetainsToMove, RRInfo &ReleasesToMove,
+ BlotMapVector<Value *, RRInfo> &Retains,
+ DenseMap<Value *, RRInfo> &Releases,
+ SmallVectorImpl<Instruction *> &DeadInsts,
+ const DenseMap<BasicBlock *, ColorVector> &BlockColors, Module *M) {
Type *ArgTy = Arg->getType();
Type *ParamTy = PointerType::getUnqual(Type::getInt8Ty(ArgTy->getContext()));
@@ -1773,7 +1787,9 @@
Value *MyArg = ArgTy == ParamTy ? Arg :
new BitCastInst(Arg, ParamTy, "", InsertPt);
Function *Decl = EP.get(ARCRuntimeEntryPointKind::Retain);
- CallInst *Call = CallInst::Create(Decl, MyArg, "", InsertPt);
+ SmallVector<OperandBundleDef, 1> BundleList;
+ addOpBundleForFunclet(InsertPt->getParent(), BlockColors, BundleList);
+ CallInst *Call = CallInst::Create(Decl, MyArg, BundleList, "", InsertPt);
Call->setDoesNotThrow();
Call->setTailCall();
@@ -1786,7 +1802,9 @@
Value *MyArg = ArgTy == ParamTy ? Arg :
new BitCastInst(Arg, ParamTy, "", InsertPt);
Function *Decl = EP.get(ARCRuntimeEntryPointKind::Release);
- CallInst *Call = CallInst::Create(Decl, MyArg, "", InsertPt);
+ SmallVector<OperandBundleDef, 1> BundleList;
+ addOpBundleForFunclet(InsertPt->getParent(), BlockColors, BundleList);
+ CallInst *Call = CallInst::Create(Decl, MyArg, BundleList, "", InsertPt);
// Attach a clang.imprecise_release metadata tag, if appropriate.
if (MDNode *M = ReleasesToMove.ReleaseMetadata)
Call->setMetadata(MDKindCache.get(ARCMDKindID::ImpreciseRelease), M);
@@ -2015,9 +2033,14 @@
bool ObjCARCOpt::PerformCodePlacement(
DenseMap<const BasicBlock *, BBState> &BBStates,
BlotMapVector<Value *, RRInfo> &Retains,
- DenseMap<Value *, RRInfo> &Releases, Module *M) {
+ DenseMap<Value *, RRInfo> &Releases, Function &F) {
LLVM_DEBUG(dbgs() << "\n== ObjCARCOpt::PerformCodePlacement ==\n");
+ DenseMap<BasicBlock *, ColorVector> BlockColors;
+ if (F.hasPersonalityFn() &&
+ isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
+ BlockColors = colorEHFunclets(F);
+
bool AnyPairsCompletelyEliminated = false;
SmallVector<Instruction *, 8> DeadInsts;
@@ -2053,15 +2076,15 @@
RRInfo RetainsToMove, ReleasesToMove;
bool PerformMoveCalls = PairUpRetainsAndReleases(
- BBStates, Retains, Releases, M, Retain, DeadInsts,
+ BBStates, Retains, Releases, F.getParent(), Retain, DeadInsts,
RetainsToMove, ReleasesToMove, Arg, KnownSafe,
AnyPairsCompletelyEliminated);
if (PerformMoveCalls) {
// Ok, everything checks out and we're all set. Let's move/delete some
// code!
- MoveCalls(Arg, RetainsToMove, ReleasesToMove,
- Retains, Releases, DeadInsts, M);
+ MoveCalls(Arg, RetainsToMove, ReleasesToMove, Retains, Releases,
+ DeadInsts, BlockColors, F.getParent());
}
}
@@ -2251,9 +2274,8 @@
return false;
// Transform.
- bool AnyPairsCompletelyEliminated = PerformCodePlacement(BBStates, Retains,
- Releases,
- F.getParent());
+ bool AnyPairsCompletelyEliminated =
+ PerformCodePlacement(BBStates, Retains, Releases, F);
return AnyPairsCompletelyEliminated && NestingDetected;
}
Index: clang/test/CodeGenObjCXX/arc-exceptions-seh.mm
===================================================================
--- clang/test/CodeGenObjCXX/arc-exceptions-seh.mm
+++ clang/test/CodeGenObjCXX/arc-exceptions-seh.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-pc-windows-msvc -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fobjc-arc-exceptions -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-O0
-// RUN: %clang_cc1 -O2 -triple x86_64-pc-windows-msvc -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fobjc-arc-exceptions -fobjc-runtime=gnustep-2.0 -mllvm -enable-objc-arc-opts=false -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-O2
+// RUN: %clang_cc1 -O0 -triple x86_64-pc-windows-msvc -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fobjc-arc-exceptions -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-O0
+// RUN: %clang_cc1 -O2 -triple x86_64-pc-windows-msvc -emit-llvm -fobjc-arc -fexceptions -fobjc-exceptions -fobjc-arc-exceptions -fobjc-runtime=gnustep-2.0 -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-O2
// WinEH requires funclet tokens on nounwind intrinsics if they can lower to
// regular function calls in the course of IR transformations.
@@ -24,7 +24,9 @@
// CHECK-LABEL: try_catch_with_objc_intrinsic
//
// CHECK: catch.dispatch:
-// CHECK-NEXT: [[CATCHSWITCH:%[0-9]+]] = catchswitch within none [label %catch] unwind label %[[CLEANUP1:.*]]
+// CHECK-NEXT: [[CATCHSWITCH:%[0-9]+]] = catchswitch within none [label %catch]
+// CHECK-O0: unwind label %[[CLEANUP1:.*]]
+// CHECK-O2: unwind to caller
//
// All calls within a catchpad must have funclet tokens that refer to it:
// CHECK: catch:
@@ -58,12 +60,12 @@
// CHECK-O2: @llvm.objc.release
// CHECK: [ "funclet"(token [[CLEANUPPAD2]]) ]
// CHECK: cleanupret from [[CLEANUPPAD2]]
-// CHECK: unwind label %[[CLEANUP1]]
+// CHECK-O0: unwind label %[[CLEANUP1]]
+// CHECK-O2: unwind to caller
//
-// CHECK: [[CLEANUP1]]:
-// CHECK-NEXT: [[CLEANUPPAD1:%[0-9]+]] = cleanuppad within none
-// CHECK: call
+// CHECK-O0: [[CLEANUP1]]:
+// CHECK-O0-NEXT: [[CLEANUPPAD1:%[0-9]+]] = cleanuppad within none
+// CHECK-O0: call
// CHECK-O0: @llvm.objc.storeStrong
-// CHECK-O2: @llvm.objc.release
-// CHECK: [ "funclet"(token [[CLEANUPPAD1]]) ]
-// CHECK: cleanupret from [[CLEANUPPAD1]] unwind to caller
+// CHECK-O0: [ "funclet"(token [[CLEANUPPAD1]]) ]
+// CHECK-O0: cleanupret from [[CLEANUPPAD1]] unwind to caller
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits