OSDN Git Service

[ObjC][ARC] Convert the retainRV marker that is passed as a named
authorAkira Hatanaka <ahatanaka@apple.com>
Wed, 10 Apr 2019 06:20:20 +0000 (06:20 +0000)
committerAkira Hatanaka <ahatanaka@apple.com>
Wed, 10 Apr 2019 06:20:20 +0000 (06:20 +0000)
metadata into a module flag in the auto-upgrader and make the ARC
contract pass read the marker as a module flag.

This is needed to fix a bug where ARC contract wasn't inserting the
retainRV marker when LTO was enabled, which caused objects returned
from a function to be auto-released.

rdar://problem/49464214

Differential Revision: https://reviews.llvm.org/D60303

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358047 91177308-0d34-0410-b5e6-96231b3b80d8

lib/IR/AutoUpgrade.cpp
lib/Transforms/ObjCARC/ObjCARCContract.cpp
test/Bitcode/upgrade-objcretainrelease.ll
test/Transforms/ObjCARC/contract-marker-funclet.ll
test/Transforms/ObjCARC/contract-marker.ll
test/Transforms/ObjCARC/contract-testcases.ll

index 2978d6a..4f0a32e 100644 (file)
@@ -3765,8 +3765,8 @@ bool llvm::UpgradeDebugInfo(Module &M) {
 
 bool llvm::UpgradeRetainReleaseMarker(Module &M) {
   bool Changed = false;
-  NamedMDNode *ModRetainReleaseMarker =
-      M.getNamedMetadata("clang.arc.retainAutoreleasedReturnValueMarker");
+  const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
+  NamedMDNode *ModRetainReleaseMarker = M.getNamedMetadata(MarkerKey);
   if (ModRetainReleaseMarker) {
     MDNode *Op = ModRetainReleaseMarker->getOperand(0);
     if (Op) {
@@ -3776,11 +3776,11 @@ bool llvm::UpgradeRetainReleaseMarker(Module &M) {
         ID->getString().split(ValueComp, "#");
         if (ValueComp.size() == 2) {
           std::string NewValue = ValueComp[0].str() + ";" + ValueComp[1].str();
-          Metadata *Ops[1] = {MDString::get(M.getContext(), NewValue)};
-          ModRetainReleaseMarker->setOperand(0,
-                                             MDNode::get(M.getContext(), Ops));
-          Changed = true;
+          ID = MDString::get(M.getContext(), NewValue);
         }
+        M.addModuleFlag(Module::Error, MarkerKey, ID);
+        M.eraseNamedMetadata(ModRetainReleaseMarker);
+        Changed = true;
       }
     }
   }
index 6613f6a..ff07cfe 100644 (file)
@@ -744,15 +744,8 @@ bool ObjCARCContract::doInitialization(Module &M) {
   EP.init(&M);
 
   // Initialize RVInstMarker.
-  RVInstMarker = nullptr;
-  if (NamedMDNode *NMD =
-          M.getNamedMetadata("clang.arc.retainAutoreleasedReturnValueMarker"))
-    if (NMD->getNumOperands() == 1) {
-      const MDNode *N = NMD->getOperand(0);
-      if (N->getNumOperands() == 1)
-        if (const MDString *S = dyn_cast<MDString>(N->getOperand(0)))
-          RVInstMarker = S;
-    }
+  const char *MarkerKey = "clang.arc.retainAutoreleasedReturnValueMarker";
+  RVInstMarker = dyn_cast_or_null<MDString>(M.getModuleFlag(MarkerKey));
 
   return false;
 }
index 5397327..2456eb4 100644 (file)
@@ -2,5 +2,5 @@
 ;
 ; RUN: llvm-dis < %s.bc | FileCheck %s
 
-; CHECK: "mov\09fp, fp\09\09; marker for objc_retainAutoreleaseReturnValue"
-
+; CHECK: !llvm.module.flags = !{!0}
+; CHECK: !0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov\09fp, fp\09\09; marker for objc_retainAutoreleaseReturnValue"}
index 462b24c..c0d6e00 100644 (file)
@@ -48,8 +48,9 @@ declare dllimport i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
 
 declare dllimport void @llvm.objc.release(i8*)
 
-!clang.arc.retainAutoreleasedReturnValueMarker = !{!0}
-!0 = !{!"movl\09%ebp, %ebp\09\09// marker for objc_retainAutoreleaseReturnValue"}
+!llvm.module.flags = !{!0}
+
+!0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"movl\09%ebp, %ebp\09\09// marker for objc_retainAutoreleaseReturnValue"}
 
 ; CHECK-LABEL: catch
 ; CHECK: call void asm sideeffect "movl{{.*}}%ebp, %ebp{{.*}}", ""() [ "funclet"(token %1) ]
index 6dc93fe..a93bbe3 100644 (file)
@@ -38,8 +38,8 @@ declare i8* @llvm.objc.retainAutoreleasedReturnValue(i8*)
 declare i8* @llvm.objc.unsafeClaimAutoreleasedReturnValue(i8*)
 declare void @bar(i8*)
 
-!clang.arc.retainAutoreleasedReturnValueMarker = !{!0}
+!llvm.module.flags = !{!0}
 
-!0 = !{!"mov\09r7, r7\09\09@ marker for return value optimization"}
+!0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov\09r7, r7\09\09@ marker for return value optimization"}
 
 ; CHECK: attributes [[NUW]] = { nounwind }
index 5715735..b529802 100644 (file)
@@ -87,9 +87,9 @@ lpad:                                             ; preds = %entry
   resume { i8*, i32 } undef
 }
 
-!clang.arc.retainAutoreleasedReturnValueMarker = !{!0}
+!llvm.module.flags = !{!0}
 
-!0 = !{!"mov\09r7, r7\09\09@ marker for objc_retainAutoreleaseReturnValue"}
+!0 = !{i32 1, !"clang.arc.retainAutoreleasedReturnValueMarker", !"mov\09r7, r7\09\09@ marker for objc_retainAutoreleaseReturnValue"}
 
 ; CHECK: attributes #0 = { optsize }
 ; CHECK: attributes [[NUW]] = { nounwind }