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
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to