[llvm-commits] [llvm] r135821 - in /llvm/trunk: lib/Transforms/Scalar/ObjCARC.cpp test/Transforms/ObjCARC/retain-not-declared.ll

Dan Gohman gohman at apple.com
Fri Jul 22 15:29:21 PDT 2011


Author: djg
Date: Fri Jul 22 17:29:21 2011
New Revision: 135821

URL: http://llvm.org/viewvc/llvm-project?rev=135821&view=rev
Log:
Move the last uses of RetainFunc etc. over to using getRetainCallee() etc.
so that a declaration for objc_retain is created when needed if it doesn't
already exist. rdar://9825114.

Modified:
    llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp
    llvm/trunk/test/Transforms/ObjCARC/retain-not-declared.ll

Modified: llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp?rev=135821&r1=135820&r2=135821&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/ObjCARC.cpp Fri Jul 22 17:29:21 2011
@@ -1406,15 +1406,11 @@
     /// Run - A flag indicating whether this optimization pass should run.
     bool Run;
 
-    /// RetainFunc, RelaseFunc - Declarations for objc_retain,
-    /// objc_retainBlock, and objc_release.
-    Function *RetainFunc, *RetainBlockFunc, *RetainRVFunc, *ReleaseFunc;
-
     /// RetainRVCallee, etc. - Declarations for ObjC runtime
     /// functions, for use in creating calls to them. These are initialized
     /// lazily to avoid cluttering up the Module with unused declarations.
     Constant *RetainRVCallee, *AutoreleaseRVCallee, *ReleaseCallee,
-             *RetainCallee, *AutoreleaseCallee;
+             *RetainCallee, *RetainBlockCallee, *AutoreleaseCallee;
 
     /// UsedInThisFunciton - Flags which determine whether each of the
     /// interesting runtine functions is in fact used in the current function.
@@ -1428,6 +1424,7 @@
     Constant *getAutoreleaseRVCallee(Module *M);
     Constant *getReleaseCallee(Module *M);
     Constant *getRetainCallee(Module *M);
+    Constant *getRetainBlockCallee(Module *M);
     Constant *getAutoreleaseCallee(Module *M);
 
     void OptimizeRetainCall(Function &F, Instruction *Retain);
@@ -1452,11 +1449,13 @@
     void MoveCalls(Value *Arg, RRInfo &RetainsToMove, RRInfo &ReleasesToMove,
                    MapVector<Value *, RRInfo> &Retains,
                    DenseMap<Value *, RRInfo> &Releases,
-                   SmallVectorImpl<Instruction *> &DeadInsts);
+                   SmallVectorImpl<Instruction *> &DeadInsts,
+                   Module *M);
 
     bool PerformCodePlacement(DenseMap<const BasicBlock *, BBState> &BBStates,
                               MapVector<Value *, RRInfo> &Retains,
-                              DenseMap<Value *, RRInfo> &Releases);
+                              DenseMap<Value *, RRInfo> &Releases,
+                              Module *M);
 
     void OptimizeWeakCalls(Function &F);
 
@@ -1561,6 +1560,22 @@
   return RetainCallee;
 }
 
+Constant *ObjCARCOpt::getRetainBlockCallee(Module *M) {
+  if (!RetainBlockCallee) {
+    LLVMContext &C = M->getContext();
+    std::vector<Type *> Params;
+    Params.push_back(PointerType::getUnqual(Type::getInt8Ty(C)));
+    AttrListPtr Attributes;
+    Attributes.addAttr(~0u, Attribute::NoUnwind);
+    RetainBlockCallee =
+      M->getOrInsertFunction(
+        "objc_retainBlock",
+        FunctionType::get(Params[0], Params, /*isVarArg=*/false),
+        Attributes);
+  }
+  return RetainBlockCallee;
+}
+
 Constant *ObjCARCOpt::getAutoreleaseCallee(Module *M) {
   if (!AutoreleaseCallee) {
     LLVMContext &C = M->getContext();
@@ -2565,12 +2580,10 @@
                            RRInfo &ReleasesToMove,
                            MapVector<Value *, RRInfo> &Retains,
                            DenseMap<Value *, RRInfo> &Releases,
-                           SmallVectorImpl<Instruction *> &DeadInsts) {
+                           SmallVectorImpl<Instruction *> &DeadInsts,
+                           Module *M) {
   Type *ArgTy = Arg->getType();
-  Type *ParamTy =
-    (RetainRVFunc ? RetainRVFunc :
-     RetainFunc ? RetainFunc :
-     RetainBlockFunc)->arg_begin()->getType();
+  Type *ParamTy = PointerType::getUnqual(Type::getInt8Ty(ArgTy->getContext()));
 
   // Insert the new retain and release calls.
   for (SmallPtrSet<Instruction *, 2>::const_iterator
@@ -2581,7 +2594,7 @@
                    new BitCastInst(Arg, ParamTy, "", InsertPt);
     CallInst *Call =
       CallInst::Create(RetainsToMove.IsRetainBlock ?
-                         RetainBlockFunc : RetainFunc,
+                         getRetainBlockCallee(M) : getRetainCallee(M),
                        MyArg, "", InsertPt);
     Call->setDoesNotThrow();
     if (!RetainsToMove.IsRetainBlock)
@@ -2609,7 +2622,8 @@
       Instruction *InsertPt = *I;
       Value *MyArg = ArgTy == ParamTy ? Arg :
                      new BitCastInst(Arg, ParamTy, "", InsertPt);
-      CallInst *Call = CallInst::Create(ReleaseFunc, MyArg, "", InsertPt);
+      CallInst *Call = CallInst::Create(getReleaseCallee(M), MyArg,
+                                        "", InsertPt);
       // Attach a clang.imprecise_release metadata tag, if appropriate.
       if (MDNode *M = ReleasesToMove.ReleaseMetadata)
         Call->setMetadata(ImpreciseReleaseMDKind, M);
@@ -2640,7 +2654,8 @@
 ObjCARCOpt::PerformCodePlacement(DenseMap<const BasicBlock *, BBState>
                                    &BBStates,
                                  MapVector<Value *, RRInfo> &Retains,
-                                 DenseMap<Value *, RRInfo> &Releases) {
+                                 DenseMap<Value *, RRInfo> &Releases,
+                                 Module *M) {
   bool AnyPairsCompletelyEliminated = false;
   RRInfo RetainsToMove;
   RRInfo ReleasesToMove;
@@ -2814,7 +2829,8 @@
     Changed = true;
     AnyPairsCompletelyEliminated = NewCount == 0;
     NumRRs += OldCount - NewCount;
-    MoveCalls(Arg, RetainsToMove, ReleasesToMove, Retains, Releases, DeadInsts);
+    MoveCalls(Arg, RetainsToMove, ReleasesToMove,
+              Retains, Releases, DeadInsts, M);
 
   next_retain:
     NewReleases.clear();
@@ -2993,7 +3009,8 @@
   bool NestingDetected = Visit(F, BBStates, Retains, Releases);
 
   // Transform.
-  return PerformCodePlacement(BBStates, Retains, Releases) && NestingDetected;
+  return PerformCodePlacement(BBStates, Retains, Releases, F.getParent()) &&
+         NestingDetected;
 }
 
 /// OptimizeReturns - Look for this pattern:
@@ -3117,12 +3134,6 @@
   ImpreciseReleaseMDKind =
     M.getContext().getMDKindID("clang.imprecise_release");
 
-  // Identify the declarations for objc_retain and friends.
-  RetainFunc = M.getFunction("objc_retain");
-  RetainBlockFunc = M.getFunction("objc_retainBlock");
-  RetainRVFunc = M.getFunction("objc_retainAutoreleasedReturnValue");
-  ReleaseFunc = M.getFunction("objc_release");
-
   // Intuitively, objc_retain and others are nocapture, however in practice
   // they are not, because they return their argument value. And objc_release
   // calls finalizers.
@@ -3132,6 +3143,7 @@
   AutoreleaseRVCallee = 0;
   ReleaseCallee = 0;
   RetainCallee = 0;
+  RetainBlockCallee = 0;
   AutoreleaseCallee = 0;
 
   return false;

Modified: llvm/trunk/test/Transforms/ObjCARC/retain-not-declared.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ObjCARC/retain-not-declared.ll?rev=135821&r1=135820&r2=135821&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/ObjCARC/retain-not-declared.ll (original)
+++ llvm/trunk/test/Transforms/ObjCARC/retain-not-declared.ll Fri Jul 22 17:29:21 2011
@@ -1,21 +1,23 @@
 ; RUN: opt -S -objc-arc -objc-arc-contract < %s | FileCheck %s
 
-; Test that the optimizer can create an objc_retainAutoreleaseReturnValue
-; declaration even if no objc_retain declaration exists.
-; rdar://9401303
-
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
 declare i8* @objc_unretainedObject(i8*)
 declare i8* @objc_retainAutoreleasedReturnValue(i8*)
 declare i8* @objc_autoreleaseReturnValue(i8*)
+declare i8* @objc_msgSend(i8*, i8*, ...)
+declare void @objc_release(i8*)
+
+; Test that the optimizer can create an objc_retainAutoreleaseReturnValue
+; declaration even if no objc_retain declaration exists.
+; rdar://9401303
 
-; CHECK:      define i8* @foo(i8* %p) {
+; CHECK:      define i8* @test0(i8* %p) {
 ; CHECK-NEXT: entry:
 ; CHECK-NEXT:   %0 = tail call i8* @objc_retainAutoreleaseReturnValue(i8* %p) nounwind
 ; CHECK-NEXT:   ret i8* %0
 ; CHECK-NEXT: }
 
-define i8* @foo(i8* %p) {
+define i8* @test0(i8* %p) {
 entry:
   %call = tail call i8* @objc_unretainedObject(i8* %p)
   %0 = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %call) nounwind
@@ -23,3 +25,37 @@
   ret i8* %1
 }
 
+; Properly create the @objc_retain declaration when it doesn't already exist.
+; rdar://9825114
+
+; CHECK: @test1(
+; CHECK: @objc_retain(
+; CHECK: @objc_retain(
+; CHECK: @objc_release(
+; CHECK: @objc_release(
+; CHECK: }
+define void @test1(i8* %call88) nounwind {
+entry:
+  %tmp1 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call88) nounwind
+  %call94 = invoke i8* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to i8* (i8*)*)(i8* %tmp1)
+          to label %invoke.cont93 unwind label %lpad91
+
+invoke.cont93:                                    ; preds = %entry
+  %tmp2 = call i8* @objc_retainAutoreleasedReturnValue(i8* %call94) nounwind
+  call void @objc_release(i8* %tmp1) nounwind
+  invoke void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*)*)(i8* %tmp2)
+          to label %invoke.cont102 unwind label %lpad100
+
+invoke.cont102:                                   ; preds = %invoke.cont93
+  call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+  unreachable
+
+lpad91:                                           ; preds = %entry
+  unreachable
+
+lpad100:                                          ; preds = %invoke.cont93
+  call void @objc_release(i8* %tmp2) nounwind, !clang.imprecise_release !0
+  unreachable
+}
+
+!0 = metadata !{}





More information about the llvm-commits mailing list