[llvm] r232350 - [objc-arc] Treat memcpy, memove, memset as just using pointers, not decrementing them.

Michael Gottesman mgottesman at apple.com
Mon Mar 16 00:02:33 PDT 2015


Author: mgottesman
Date: Mon Mar 16 02:02:32 2015
New Revision: 232350

URL: http://llvm.org/viewvc/llvm-project?rev=232350&view=rev
Log:
[objc-arc] Treat memcpy, memove, memset as just using pointers, not decrementing them.

This will be tested in the next commit (which required it). The commit
is going to update a bunch of tests at the same time.

Modified:
    llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp

Modified: llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp?rev=232350&r1=232349&r2=232350&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp Mon Mar 16 02:02:32 2015
@@ -168,6 +168,60 @@ ARCInstKind llvm::objcarc::GetFunctionCl
   return ARCInstKind::CallOrUser;
 }
 
+// A whitelist of intrinsics that we know do not use objc pointers or decrement
+// ref counts.
+static bool isInertIntrinsic(unsigned ID) {
+  // TODO: Make this into a covered switch.
+  switch (ID) {
+  case Intrinsic::returnaddress:
+  case Intrinsic::frameaddress:
+  case Intrinsic::stacksave:
+  case Intrinsic::stackrestore:
+  case Intrinsic::vastart:
+  case Intrinsic::vacopy:
+  case Intrinsic::vaend:
+  case Intrinsic::objectsize:
+  case Intrinsic::prefetch:
+  case Intrinsic::stackprotector:
+  case Intrinsic::eh_return_i32:
+  case Intrinsic::eh_return_i64:
+  case Intrinsic::eh_typeid_for:
+  case Intrinsic::eh_dwarf_cfa:
+  case Intrinsic::eh_sjlj_lsda:
+  case Intrinsic::eh_sjlj_functioncontext:
+  case Intrinsic::init_trampoline:
+  case Intrinsic::adjust_trampoline:
+  case Intrinsic::lifetime_start:
+  case Intrinsic::lifetime_end:
+  case Intrinsic::invariant_start:
+  case Intrinsic::invariant_end:
+  // Don't let dbg info affect our results.
+  case Intrinsic::dbg_declare:
+  case Intrinsic::dbg_value:
+    // Short cut: Some intrinsics obviously don't use ObjC pointers.
+    return true;
+  default:
+    return false;
+  }
+}
+
+// A whitelist of intrinsics that we know do not use objc pointers or decrement
+// ref counts.
+static bool isUseOnlyIntrinsic(unsigned ID) {
+  // We are conservative and even though intrinsics are unlikely to touch
+  // reference counts, we white list them for safety.
+  //
+  // TODO: Expand this into a covered switch. There is a lot more here.
+  switch (ID) {
+  case Intrinsic::memcpy:
+  case Intrinsic::memmove:
+  case Intrinsic::memset:
+    return true;
+  default:
+    return false;
+  }
+}
+
 /// \brief Determine what kind of construct V is.
 ARCInstKind llvm::objcarc::GetARCInstKind(const Value *V) {
   if (const Instruction *I = dyn_cast<Instruction>(V)) {
@@ -180,49 +234,23 @@ ARCInstKind llvm::objcarc::GetARCInstKin
     switch (I->getOpcode()) {
     case Instruction::Call: {
       const CallInst *CI = cast<CallInst>(I);
-      // Check for calls to special functions.
+      // See if we have a function that we know something about.
       if (const Function *F = CI->getCalledFunction()) {
         ARCInstKind Class = GetFunctionClass(F);
         if (Class != ARCInstKind::CallOrUser)
           return Class;
-
-        // None of the intrinsic functions do objc_release. For intrinsics, the
-        // only question is whether or not they may be users.
-        switch (F->getIntrinsicID()) {
-        case Intrinsic::returnaddress:
-        case Intrinsic::frameaddress:
-        case Intrinsic::stacksave:
-        case Intrinsic::stackrestore:
-        case Intrinsic::vastart:
-        case Intrinsic::vacopy:
-        case Intrinsic::vaend:
-        case Intrinsic::objectsize:
-        case Intrinsic::prefetch:
-        case Intrinsic::stackprotector:
-        case Intrinsic::eh_return_i32:
-        case Intrinsic::eh_return_i64:
-        case Intrinsic::eh_typeid_for:
-        case Intrinsic::eh_dwarf_cfa:
-        case Intrinsic::eh_sjlj_lsda:
-        case Intrinsic::eh_sjlj_functioncontext:
-        case Intrinsic::init_trampoline:
-        case Intrinsic::adjust_trampoline:
-        case Intrinsic::lifetime_start:
-        case Intrinsic::lifetime_end:
-        case Intrinsic::invariant_start:
-        case Intrinsic::invariant_end:
-        // Don't let dbg info affect our results.
-        case Intrinsic::dbg_declare:
-        case Intrinsic::dbg_value:
-          // Short cut: Some intrinsics obviously don't use ObjC pointers.
+        unsigned ID = F->getIntrinsicID();
+        if (isInertIntrinsic(ID))
           return ARCInstKind::None;
-        default:
-          break;
-        }
+        if (isUseOnlyIntrinsic(ID))
+          return ARCInstKind::User;
       }
+
+      // Otherwise, be conservative.
       return GetCallSiteClass(CI);
     }
     case Instruction::Invoke:
+      // Otherwise, be conservative.
       return GetCallSiteClass(cast<InvokeInst>(I));
     case Instruction::BitCast:
     case Instruction::GetElementPtr:





More information about the llvm-commits mailing list