[llvm] r245541 - [ARC] Pull the ObjC ARC components that really serve the role of

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 20 01:06:03 PDT 2015


Author: chandlerc
Date: Thu Aug 20 03:06:03 2015
New Revision: 245541

URL: http://llvm.org/viewvc/llvm-project?rev=245541&view=rev
Log:
[ARC] Pull the ObjC ARC components that really serve the role of
analyses into LLVM's Analysis library rather than having them in
a Transforms library.

This is motivated by the need to have the core AliasAnalysis
infrastructure be aware of the ObjCARCAliasAnalysis. However, it also
seems like a nice and clean separation. Everything was very easy to move
and this doesn't create much clutter in the analysis library IMO.

Differential Revision: http://reviews.llvm.org/D12133

Added:
    llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h
      - copied, changed from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h
    llvm/trunk/include/llvm/Analysis/ObjCARCAnalysisUtils.h
      - copied, changed from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h
    llvm/trunk/include/llvm/Analysis/ObjCARCInstKind.h
      - copied, changed from r245535, llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h
    llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp
      - copied, changed from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp
    llvm/trunk/lib/Analysis/ObjCARCAnalysisUtils.cpp
      - copied, changed from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp
    llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp
      - copied, changed from r245535, llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp
Removed:
    llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp
    llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h
    llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp
    llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h
Modified:
    llvm/trunk/lib/Analysis/Analysis.cpp
    llvm/trunk/lib/Analysis/CMakeLists.txt
    llvm/trunk/lib/Transforms/ObjCARC/CMakeLists.txt
    llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp
    llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h
    llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
    llvm/trunk/lib/Transforms/ObjCARC/PtrState.h

Copied: llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h (from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h?p2=llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h&p1=llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h&r1=245535&r2=245541&rev=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h (original)
+++ llvm/trunk/include/llvm/Analysis/ObjCARCAliasAnalysis.h Thu Aug 20 03:06:03 2015
@@ -1,4 +1,4 @@
-//===- ObjCARCAliasAnalysis.h - ObjC ARC Optimization -*- C++ -*-----------===//
+//===- ObjCARCAliasAnalysis.h - ObjC ARC Alias Analysis ---------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -20,8 +20,8 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARCALIASANALYSIS_H
-#define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARCALIASANALYSIS_H
+#ifndef LLVM_ANALYSIS_OBJCARCALIASANALYSIS_H
+#define LLVM_ANALYSIS_OBJCARCALIASANALYSIS_H
 
 #include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/Pass.h"

Copied: llvm/trunk/include/llvm/Analysis/ObjCARCAnalysisUtils.h (from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ObjCARCAnalysisUtils.h?p2=llvm/trunk/include/llvm/Analysis/ObjCARCAnalysisUtils.h&p1=llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h&r1=245535&r2=245541&rev=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h (original)
+++ llvm/trunk/include/llvm/Analysis/ObjCARCAnalysisUtils.h Thu Aug 20 03:06:03 2015
@@ -1,4 +1,4 @@
-//===- ObjCARC.h - ObjC ARC Optimization --------------*- C++ -*-----------===//
+//===- ObjCARCAnalysisUtils.h - ObjC ARC Analysis Utilities -----*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,9 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 /// \file
-/// This file defines common definitions/declarations used by the ObjC ARC
-/// Optimizer. ARC stands for Automatic Reference Counting and is a system for
-/// managing reference counts for objects in Objective C.
+/// This file defines common analysis utilities used by the ObjC ARC Optimizer.
+/// ARC stands for Automatic Reference Counting and is a system for managing
+/// reference counts for objects in Objective C.
 ///
 /// WARNING: This file knows about certain library functions. It recognizes them
 /// by name, and hardwires knowledge of their semantics.
@@ -20,12 +20,13 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H
-#define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARC_H
+#ifndef LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H
+#define LLVM_LIB_ANALYSIS_OBJCARCANALYSISUTILS_H
 
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/ObjCARCInstKind.h"
 #include "llvm/Analysis/Passes.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/CallSite.h"
@@ -34,7 +35,6 @@
 #include "llvm/Pass.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Utils/Local.h"
-#include "ARCInstKind.h"
 
 namespace llvm {
 class raw_ostream;
@@ -48,7 +48,7 @@ extern bool EnableARCOpts;
 
 /// \brief Test if the given module looks interesting to run ARC optimization
 /// on.
-static inline bool ModuleHasARC(const Module &M) {
+inline bool ModuleHasARC(const Module &M) {
   return
     M.getNamedValue("objc_retain") ||
     M.getNamedValue("objc_release") ||
@@ -73,7 +73,7 @@ static inline bool ModuleHasARC(const Mo
 /// \brief This is a wrapper around getUnderlyingObject which also knows how to
 /// look through objc_retain and objc_autorelease calls, which we know to return
 /// their argument verbatim.
-static inline const Value *GetUnderlyingObjCPtr(const Value *V,
+inline const Value *GetUnderlyingObjCPtr(const Value *V,
                                                 const DataLayout &DL) {
   for (;;) {
     V = GetUnderlyingObject(V, DL);
@@ -100,7 +100,7 @@ static inline const Value *GetUnderlying
 ///
 /// Thus this function strips off pointer casts and forwarding calls. *NOTE*
 /// This implies that two RCIdentical values must alias.
-static inline const Value *GetRCIdentityRoot(const Value *V) {
+inline const Value *GetRCIdentityRoot(const Value *V) {
   for (;;) {
     V = V->stripPointerCasts();
     if (!IsForwarding(GetBasicARCInstKind(V)))
@@ -114,56 +114,29 @@ static inline const Value *GetRCIdentity
 /// casts away the const of the result. For documentation about what an
 /// RCIdentityRoot (and by extension GetRCIdentityRoot is) look at that
 /// function.
-static inline Value *GetRCIdentityRoot(Value *V) {
+inline Value *GetRCIdentityRoot(Value *V) {
   return const_cast<Value *>(GetRCIdentityRoot((const Value *)V));
 }
 
 /// \brief Assuming the given instruction is one of the special calls such as
 /// objc_retain or objc_release, return the RCIdentity root of the argument of
 /// the call.
-static inline Value *GetArgRCIdentityRoot(Value *Inst) {
+inline Value *GetArgRCIdentityRoot(Value *Inst) {
   return GetRCIdentityRoot(cast<CallInst>(Inst)->getArgOperand(0));
 }
 
-static inline bool IsNullOrUndef(const Value *V) {
+inline bool IsNullOrUndef(const Value *V) {
   return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
 }
 
-static inline bool IsNoopInstruction(const Instruction *I) {
+inline bool IsNoopInstruction(const Instruction *I) {
   return isa<BitCastInst>(I) ||
     (isa<GetElementPtrInst>(I) &&
      cast<GetElementPtrInst>(I)->hasAllZeroIndices());
 }
 
-
-/// \brief Erase the given instruction.
-///
-/// Many ObjC calls return their argument verbatim,
-/// so if it's such a call and the return value has users, replace them with the
-/// argument value.
-///
-static inline void EraseInstruction(Instruction *CI) {
-  Value *OldArg = cast<CallInst>(CI)->getArgOperand(0);
-
-  bool Unused = CI->use_empty();
-
-  if (!Unused) {
-    // Replace the return value with the argument.
-    assert((IsForwarding(GetBasicARCInstKind(CI)) ||
-            (IsNoopOnNull(GetBasicARCInstKind(CI)) &&
-             isa<ConstantPointerNull>(OldArg))) &&
-           "Can't delete non-forwarding instruction with users!");
-    CI->replaceAllUsesWith(OldArg);
-  }
-
-  CI->eraseFromParent();
-
-  if (Unused)
-    RecursivelyDeleteTriviallyDeadInstructions(OldArg);
-}
-
 /// \brief Test whether the given value is possible a retainable object pointer.
-static inline bool IsPotentialRetainableObjPtr(const Value *Op) {
+inline bool IsPotentialRetainableObjPtr(const Value *Op) {
   // Pointers to static or stack storage are not valid retainable object
   // pointers.
   if (isa<Constant>(Op) || isa<AllocaInst>(Op))
@@ -188,7 +161,7 @@ static inline bool IsPotentialRetainable
   return true;
 }
 
-static inline bool IsPotentialRetainableObjPtr(const Value *Op,
+inline bool IsPotentialRetainableObjPtr(const Value *Op,
                                                AliasAnalysis &AA) {
   // First make the rudimentary check.
   if (!IsPotentialRetainableObjPtr(Op))
@@ -209,7 +182,7 @@ static inline bool IsPotentialRetainable
 
 /// \brief Helper for GetARCInstKind. Determines what kind of construct CS
 /// is.
-static inline ARCInstKind GetCallSiteClass(ImmutableCallSite CS) {
+inline ARCInstKind GetCallSiteClass(ImmutableCallSite CS) {
   for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
        I != E; ++I)
     if (IsPotentialRetainableObjPtr(*I))
@@ -223,7 +196,7 @@ static inline ARCInstKind GetCallSiteCla
 ///
 /// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses
 /// special knowledge of ObjC conventions.
-static inline bool IsObjCIdentifiedObject(const Value *V) {
+inline bool IsObjCIdentifiedObject(const Value *V) {
   // Assume that call results and arguments have their own "provenance".
   // Constants (including GlobalVariables) and Allocas are never
   // reference-counted.

Copied: llvm/trunk/include/llvm/Analysis/ObjCARCInstKind.h (from r245535, llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/ObjCARCInstKind.h?p2=llvm/trunk/include/llvm/Analysis/ObjCARCInstKind.h&p1=llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h&r1=245535&r2=245541&rev=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h (original)
+++ llvm/trunk/include/llvm/Analysis/ObjCARCInstKind.h Thu Aug 20 03:06:03 2015
@@ -1,4 +1,4 @@
-//===--- ARCInstKind.h - ARC instruction equivalence classes -*- C++ -*----===//
+//===- ObjCARCInstKind.h - ARC instruction equivalence classes --*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -7,8 +7,8 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_ARCINSTKIND_H
-#define LLVM_LIB_TRANSFORMS_OBJCARC_ARCINSTKIND_H
+#ifndef LLVM_ANALYSIS_OBJCARCINSTKIND_H
+#define LLVM_ANALYSIS_OBJCARCINSTKIND_H
 
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Function.h"
@@ -98,7 +98,7 @@ ARCInstKind GetFunctionClass(const Funct
 /// This is similar to GetARCInstKind except that it only detects objc
 /// runtime calls. This allows it to be faster.
 ///
-static inline ARCInstKind GetBasicARCInstKind(const Value *V) {
+inline ARCInstKind GetBasicARCInstKind(const Value *V) {
   if (const CallInst *CI = dyn_cast<CallInst>(V)) {
     if (const Function *F = CI->getCalledFunction())
       return GetFunctionClass(F);

Modified: llvm/trunk/lib/Analysis/Analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Analysis.cpp?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/Analysis.cpp (original)
+++ llvm/trunk/lib/Analysis/Analysis.cpp Thu Aug 20 03:06:03 2015
@@ -61,6 +61,7 @@ void llvm::initializeAnalysis(PassRegist
   initializeMemDerefPrinterPass(Registry);
   initializeMemoryDependenceAnalysisPass(Registry);
   initializeModuleDebugInfoPrinterPass(Registry);
+  initializeObjCARCAliasAnalysisPass(Registry);
   initializePostDominatorTreePass(Registry);
   initializeRegionInfoPassPass(Registry);
   initializeRegionViewerPass(Registry);

Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
+++ llvm/trunk/lib/Analysis/CMakeLists.txt Thu Aug 20 03:06:03 2015
@@ -49,6 +49,9 @@ add_llvm_library(LLVMAnalysis
   MemoryLocation.cpp
   ModuleDebugInfoPrinter.cpp
   NoAliasAnalysis.cpp
+  ObjCARCAliasAnalysis.cpp
+  ObjCARCAnalysisUtils.cpp
+  ObjCARCInstKind.cpp
   OrderedBasicBlock.cpp
   PHITransAddr.cpp
   PostDominators.cpp

Copied: llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp (from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp?p2=llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp&p1=llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp&r1=245535&r2=245541&rev=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Analysis/ObjCARCAliasAnalysis.cpp Thu Aug 20 03:06:03 2015
@@ -20,8 +20,8 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#include "ObjCARC.h"
-#include "ObjCARCAliasAnalysis.h"
+#include "llvm/Analysis/ObjCARCAliasAnalysis.h"
+#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/Value.h"

Copied: llvm/trunk/lib/Analysis/ObjCARCAnalysisUtils.cpp (from r245535, llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ObjCARCAnalysisUtils.cpp?p2=llvm/trunk/lib/Analysis/ObjCARCAnalysisUtils.cpp&p1=llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp&r1=245535&r2=245541&rev=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp (original)
+++ llvm/trunk/lib/Analysis/ObjCARCAnalysisUtils.cpp Thu Aug 20 03:06:03 2015
@@ -1,4 +1,4 @@
-//===-- ObjCARC.cpp -------------------------------------------------------===//
+//===- ObjCARCAnalysisUtils.cpp -------------------------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -13,16 +13,9 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "ObjCARC.h"
-#include "llvm-c/Core.h"
-#include "llvm-c/Initialization.h"
-#include "llvm/InitializePasses.h"
+#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
 #include "llvm/Support/CommandLine.h"
 
-namespace llvm {
-  class PassRegistry;
-}
-
 using namespace llvm;
 using namespace llvm::objcarc;
 
@@ -33,18 +26,3 @@ EnableARCOptimizations("enable-objc-arc-
                        cl::desc("enable/disable all ARC Optimizations"),
                        cl::location(EnableARCOpts),
                        cl::init(true));
-
-/// initializeObjCARCOptsPasses - Initialize all passes linked into the
-/// ObjCARCOpts library.
-void llvm::initializeObjCARCOpts(PassRegistry &Registry) {
-  initializeObjCARCAliasAnalysisPass(Registry);
-  initializeObjCARCAPElimPass(Registry);
-  initializeObjCARCExpandPass(Registry);
-  initializeObjCARCContractPass(Registry);
-  initializeObjCARCOptPass(Registry);
-  initializePAEvalPass(Registry);
-}
-
-void LLVMInitializeObjCARCOpts(LLVMPassRegistryRef R) {
-  initializeObjCARCOpts(*unwrap(R));
-}

Copied: llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp (from r245535, llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp?p2=llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp&p1=llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp&r1=245535&r2=245541&rev=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp (original)
+++ llvm/trunk/lib/Analysis/ObjCARCInstKind.cpp Thu Aug 20 03:06:03 2015
@@ -19,7 +19,9 @@
 ///
 //===----------------------------------------------------------------------===//
 
-#include "ObjCARC.h"
+#include "llvm/Analysis/ObjCARCInstKind.h"
+#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
+#include "llvm/ADT/StringSwitch.h"
 #include "llvm/IR/Intrinsics.h"
 
 using namespace llvm;

Removed: llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp?rev=245540&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.cpp (removed)
@@ -1,673 +0,0 @@
-//===- ARCInstKind.cpp - ObjC ARC Optimization ----------------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file defines several utility functions used by various ARC
-/// optimizations which are IMHO too big to be in a header file.
-///
-/// WARNING: This file knows about certain library functions. It recognizes them
-/// by name, and hardwires knowledge of their semantics.
-///
-/// WARNING: This file knows about how certain Objective-C library functions are
-/// used. Naive LLVM IR transformations which would otherwise be
-/// behavior-preserving may break these assumptions.
-///
-//===----------------------------------------------------------------------===//
-
-#include "ObjCARC.h"
-#include "llvm/IR/Intrinsics.h"
-
-using namespace llvm;
-using namespace llvm::objcarc;
-
-raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS,
-                                       const ARCInstKind Class) {
-  switch (Class) {
-  case ARCInstKind::Retain:
-    return OS << "ARCInstKind::Retain";
-  case ARCInstKind::RetainRV:
-    return OS << "ARCInstKind::RetainRV";
-  case ARCInstKind::RetainBlock:
-    return OS << "ARCInstKind::RetainBlock";
-  case ARCInstKind::Release:
-    return OS << "ARCInstKind::Release";
-  case ARCInstKind::Autorelease:
-    return OS << "ARCInstKind::Autorelease";
-  case ARCInstKind::AutoreleaseRV:
-    return OS << "ARCInstKind::AutoreleaseRV";
-  case ARCInstKind::AutoreleasepoolPush:
-    return OS << "ARCInstKind::AutoreleasepoolPush";
-  case ARCInstKind::AutoreleasepoolPop:
-    return OS << "ARCInstKind::AutoreleasepoolPop";
-  case ARCInstKind::NoopCast:
-    return OS << "ARCInstKind::NoopCast";
-  case ARCInstKind::FusedRetainAutorelease:
-    return OS << "ARCInstKind::FusedRetainAutorelease";
-  case ARCInstKind::FusedRetainAutoreleaseRV:
-    return OS << "ARCInstKind::FusedRetainAutoreleaseRV";
-  case ARCInstKind::LoadWeakRetained:
-    return OS << "ARCInstKind::LoadWeakRetained";
-  case ARCInstKind::StoreWeak:
-    return OS << "ARCInstKind::StoreWeak";
-  case ARCInstKind::InitWeak:
-    return OS << "ARCInstKind::InitWeak";
-  case ARCInstKind::LoadWeak:
-    return OS << "ARCInstKind::LoadWeak";
-  case ARCInstKind::MoveWeak:
-    return OS << "ARCInstKind::MoveWeak";
-  case ARCInstKind::CopyWeak:
-    return OS << "ARCInstKind::CopyWeak";
-  case ARCInstKind::DestroyWeak:
-    return OS << "ARCInstKind::DestroyWeak";
-  case ARCInstKind::StoreStrong:
-    return OS << "ARCInstKind::StoreStrong";
-  case ARCInstKind::CallOrUser:
-    return OS << "ARCInstKind::CallOrUser";
-  case ARCInstKind::Call:
-    return OS << "ARCInstKind::Call";
-  case ARCInstKind::User:
-    return OS << "ARCInstKind::User";
-  case ARCInstKind::IntrinsicUser:
-    return OS << "ARCInstKind::IntrinsicUser";
-  case ARCInstKind::None:
-    return OS << "ARCInstKind::None";
-  }
-  llvm_unreachable("Unknown instruction class!");
-}
-
-ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) {
-  Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
-
-  // No (mandatory) arguments.
-  if (AI == AE)
-    return StringSwitch<ARCInstKind>(F->getName())
-        .Case("objc_autoreleasePoolPush", ARCInstKind::AutoreleasepoolPush)
-        .Case("clang.arc.use", ARCInstKind::IntrinsicUser)
-        .Default(ARCInstKind::CallOrUser);
-
-  // One argument.
-  const Argument *A0 = AI++;
-  if (AI == AE)
-    // Argument is a pointer.
-    if (PointerType *PTy = dyn_cast<PointerType>(A0->getType())) {
-      Type *ETy = PTy->getElementType();
-      // Argument is i8*.
-      if (ETy->isIntegerTy(8))
-        return StringSwitch<ARCInstKind>(F->getName())
-            .Case("objc_retain", ARCInstKind::Retain)
-            .Case("objc_retainAutoreleasedReturnValue", ARCInstKind::RetainRV)
-            .Case("objc_retainBlock", ARCInstKind::RetainBlock)
-            .Case("objc_release", ARCInstKind::Release)
-            .Case("objc_autorelease", ARCInstKind::Autorelease)
-            .Case("objc_autoreleaseReturnValue", ARCInstKind::AutoreleaseRV)
-            .Case("objc_autoreleasePoolPop", ARCInstKind::AutoreleasepoolPop)
-            .Case("objc_retainedObject", ARCInstKind::NoopCast)
-            .Case("objc_unretainedObject", ARCInstKind::NoopCast)
-            .Case("objc_unretainedPointer", ARCInstKind::NoopCast)
-            .Case("objc_retain_autorelease",
-                  ARCInstKind::FusedRetainAutorelease)
-            .Case("objc_retainAutorelease", ARCInstKind::FusedRetainAutorelease)
-            .Case("objc_retainAutoreleaseReturnValue",
-                  ARCInstKind::FusedRetainAutoreleaseRV)
-            .Case("objc_sync_enter", ARCInstKind::User)
-            .Case("objc_sync_exit", ARCInstKind::User)
-            .Default(ARCInstKind::CallOrUser);
-
-      // Argument is i8**
-      if (PointerType *Pte = dyn_cast<PointerType>(ETy))
-        if (Pte->getElementType()->isIntegerTy(8))
-          return StringSwitch<ARCInstKind>(F->getName())
-              .Case("objc_loadWeakRetained", ARCInstKind::LoadWeakRetained)
-              .Case("objc_loadWeak", ARCInstKind::LoadWeak)
-              .Case("objc_destroyWeak", ARCInstKind::DestroyWeak)
-              .Default(ARCInstKind::CallOrUser);
-    }
-
-  // Two arguments, first is i8**.
-  const Argument *A1 = AI++;
-  if (AI == AE)
-    if (PointerType *PTy = dyn_cast<PointerType>(A0->getType()))
-      if (PointerType *Pte = dyn_cast<PointerType>(PTy->getElementType()))
-        if (Pte->getElementType()->isIntegerTy(8))
-          if (PointerType *PTy1 = dyn_cast<PointerType>(A1->getType())) {
-            Type *ETy1 = PTy1->getElementType();
-            // Second argument is i8*
-            if (ETy1->isIntegerTy(8))
-              return StringSwitch<ARCInstKind>(F->getName())
-                  .Case("objc_storeWeak", ARCInstKind::StoreWeak)
-                  .Case("objc_initWeak", ARCInstKind::InitWeak)
-                  .Case("objc_storeStrong", ARCInstKind::StoreStrong)
-                  .Default(ARCInstKind::CallOrUser);
-            // Second argument is i8**.
-            if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1))
-              if (Pte1->getElementType()->isIntegerTy(8))
-                return StringSwitch<ARCInstKind>(F->getName())
-                    .Case("objc_moveWeak", ARCInstKind::MoveWeak)
-                    .Case("objc_copyWeak", ARCInstKind::CopyWeak)
-                    // Ignore annotation calls. This is important to stop the
-                    // optimizer from treating annotations as uses which would
-                    // make the state of the pointers they are attempting to
-                    // elucidate to be incorrect.
-                    .Case("llvm.arc.annotation.topdown.bbstart",
-                          ARCInstKind::None)
-                    .Case("llvm.arc.annotation.topdown.bbend",
-                          ARCInstKind::None)
-                    .Case("llvm.arc.annotation.bottomup.bbstart",
-                          ARCInstKind::None)
-                    .Case("llvm.arc.annotation.bottomup.bbend",
-                          ARCInstKind::None)
-                    .Default(ARCInstKind::CallOrUser);
-          }
-
-  // Anything else.
-  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)) {
-    // Any instruction other than bitcast and gep with a pointer operand have a
-    // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer
-    // to a subsequent use, rather than using it themselves, in this sense.
-    // As a short cut, several other opcodes are known to have no pointer
-    // operands of interest. And ret is never followed by a release, so it's
-    // not interesting to examine.
-    switch (I->getOpcode()) {
-    case Instruction::Call: {
-      const CallInst *CI = cast<CallInst>(I);
-      // 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;
-        Intrinsic::ID ID = F->getIntrinsicID();
-        if (isInertIntrinsic(ID))
-          return ARCInstKind::None;
-        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:
-    case Instruction::Select:
-    case Instruction::PHI:
-    case Instruction::Ret:
-    case Instruction::Br:
-    case Instruction::Switch:
-    case Instruction::IndirectBr:
-    case Instruction::Alloca:
-    case Instruction::VAArg:
-    case Instruction::Add:
-    case Instruction::FAdd:
-    case Instruction::Sub:
-    case Instruction::FSub:
-    case Instruction::Mul:
-    case Instruction::FMul:
-    case Instruction::SDiv:
-    case Instruction::UDiv:
-    case Instruction::FDiv:
-    case Instruction::SRem:
-    case Instruction::URem:
-    case Instruction::FRem:
-    case Instruction::Shl:
-    case Instruction::LShr:
-    case Instruction::AShr:
-    case Instruction::And:
-    case Instruction::Or:
-    case Instruction::Xor:
-    case Instruction::SExt:
-    case Instruction::ZExt:
-    case Instruction::Trunc:
-    case Instruction::IntToPtr:
-    case Instruction::FCmp:
-    case Instruction::FPTrunc:
-    case Instruction::FPExt:
-    case Instruction::FPToUI:
-    case Instruction::FPToSI:
-    case Instruction::UIToFP:
-    case Instruction::SIToFP:
-    case Instruction::InsertElement:
-    case Instruction::ExtractElement:
-    case Instruction::ShuffleVector:
-    case Instruction::ExtractValue:
-      break;
-    case Instruction::ICmp:
-      // Comparing a pointer with null, or any other constant, isn't an
-      // interesting use, because we don't care what the pointer points to, or
-      // about the values of any other dynamic reference-counted pointers.
-      if (IsPotentialRetainableObjPtr(I->getOperand(1)))
-        return ARCInstKind::User;
-      break;
-    default:
-      // For anything else, check all the operands.
-      // Note that this includes both operands of a Store: while the first
-      // operand isn't actually being dereferenced, it is being stored to
-      // memory where we can no longer track who might read it and dereference
-      // it, so we have to consider it potentially used.
-      for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end();
-           OI != OE; ++OI)
-        if (IsPotentialRetainableObjPtr(*OI))
-          return ARCInstKind::User;
-    }
-  }
-
-  // Otherwise, it's totally inert for ARC purposes.
-  return ARCInstKind::None;
-}
-
-/// \brief Test if the given class is a kind of user.
-bool llvm::objcarc::IsUser(ARCInstKind Class) {
-  switch (Class) {
-  case ARCInstKind::User:
-  case ARCInstKind::CallOrUser:
-  case ARCInstKind::IntrinsicUser:
-    return true;
-  case ARCInstKind::Retain:
-  case ARCInstKind::RetainRV:
-  case ARCInstKind::RetainBlock:
-  case ARCInstKind::Release:
-  case ARCInstKind::Autorelease:
-  case ARCInstKind::AutoreleaseRV:
-  case ARCInstKind::AutoreleasepoolPush:
-  case ARCInstKind::AutoreleasepoolPop:
-  case ARCInstKind::NoopCast:
-  case ARCInstKind::FusedRetainAutorelease:
-  case ARCInstKind::FusedRetainAutoreleaseRV:
-  case ARCInstKind::LoadWeakRetained:
-  case ARCInstKind::StoreWeak:
-  case ARCInstKind::InitWeak:
-  case ARCInstKind::LoadWeak:
-  case ARCInstKind::MoveWeak:
-  case ARCInstKind::CopyWeak:
-  case ARCInstKind::DestroyWeak:
-  case ARCInstKind::StoreStrong:
-  case ARCInstKind::Call:
-  case ARCInstKind::None:
-    return false;
-  }
-  llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class is objc_retain or equivalent.
-bool llvm::objcarc::IsRetain(ARCInstKind Class) {
-  switch (Class) {
-  case ARCInstKind::Retain:
-  case ARCInstKind::RetainRV:
-    return true;
-  // I believe we treat retain block as not a retain since it can copy its
-  // block.
-  case ARCInstKind::RetainBlock:
-  case ARCInstKind::Release:
-  case ARCInstKind::Autorelease:
-  case ARCInstKind::AutoreleaseRV:
-  case ARCInstKind::AutoreleasepoolPush:
-  case ARCInstKind::AutoreleasepoolPop:
-  case ARCInstKind::NoopCast:
-  case ARCInstKind::FusedRetainAutorelease:
-  case ARCInstKind::FusedRetainAutoreleaseRV:
-  case ARCInstKind::LoadWeakRetained:
-  case ARCInstKind::StoreWeak:
-  case ARCInstKind::InitWeak:
-  case ARCInstKind::LoadWeak:
-  case ARCInstKind::MoveWeak:
-  case ARCInstKind::CopyWeak:
-  case ARCInstKind::DestroyWeak:
-  case ARCInstKind::StoreStrong:
-  case ARCInstKind::IntrinsicUser:
-  case ARCInstKind::CallOrUser:
-  case ARCInstKind::Call:
-  case ARCInstKind::User:
-  case ARCInstKind::None:
-    return false;
-  }
-  llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class is objc_autorelease or equivalent.
-bool llvm::objcarc::IsAutorelease(ARCInstKind Class) {
-  switch (Class) {
-  case ARCInstKind::Autorelease:
-  case ARCInstKind::AutoreleaseRV:
-    return true;
-  case ARCInstKind::Retain:
-  case ARCInstKind::RetainRV:
-  case ARCInstKind::RetainBlock:
-  case ARCInstKind::Release:
-  case ARCInstKind::AutoreleasepoolPush:
-  case ARCInstKind::AutoreleasepoolPop:
-  case ARCInstKind::NoopCast:
-  case ARCInstKind::FusedRetainAutorelease:
-  case ARCInstKind::FusedRetainAutoreleaseRV:
-  case ARCInstKind::LoadWeakRetained:
-  case ARCInstKind::StoreWeak:
-  case ARCInstKind::InitWeak:
-  case ARCInstKind::LoadWeak:
-  case ARCInstKind::MoveWeak:
-  case ARCInstKind::CopyWeak:
-  case ARCInstKind::DestroyWeak:
-  case ARCInstKind::StoreStrong:
-  case ARCInstKind::IntrinsicUser:
-  case ARCInstKind::CallOrUser:
-  case ARCInstKind::Call:
-  case ARCInstKind::User:
-  case ARCInstKind::None:
-    return false;
-  }
-  llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class represents instructions which return their
-/// argument verbatim.
-bool llvm::objcarc::IsForwarding(ARCInstKind Class) {
-  switch (Class) {
-  case ARCInstKind::Retain:
-  case ARCInstKind::RetainRV:
-  case ARCInstKind::Autorelease:
-  case ARCInstKind::AutoreleaseRV:
-  case ARCInstKind::NoopCast:
-    return true;
-  case ARCInstKind::RetainBlock:
-  case ARCInstKind::Release:
-  case ARCInstKind::AutoreleasepoolPush:
-  case ARCInstKind::AutoreleasepoolPop:
-  case ARCInstKind::FusedRetainAutorelease:
-  case ARCInstKind::FusedRetainAutoreleaseRV:
-  case ARCInstKind::LoadWeakRetained:
-  case ARCInstKind::StoreWeak:
-  case ARCInstKind::InitWeak:
-  case ARCInstKind::LoadWeak:
-  case ARCInstKind::MoveWeak:
-  case ARCInstKind::CopyWeak:
-  case ARCInstKind::DestroyWeak:
-  case ARCInstKind::StoreStrong:
-  case ARCInstKind::IntrinsicUser:
-  case ARCInstKind::CallOrUser:
-  case ARCInstKind::Call:
-  case ARCInstKind::User:
-  case ARCInstKind::None:
-    return false;
-  }
-  llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class represents instructions which do nothing if
-/// passed a null pointer.
-bool llvm::objcarc::IsNoopOnNull(ARCInstKind Class) {
-  switch (Class) {
-  case ARCInstKind::Retain:
-  case ARCInstKind::RetainRV:
-  case ARCInstKind::Release:
-  case ARCInstKind::Autorelease:
-  case ARCInstKind::AutoreleaseRV:
-  case ARCInstKind::RetainBlock:
-    return true;
-  case ARCInstKind::AutoreleasepoolPush:
-  case ARCInstKind::AutoreleasepoolPop:
-  case ARCInstKind::FusedRetainAutorelease:
-  case ARCInstKind::FusedRetainAutoreleaseRV:
-  case ARCInstKind::LoadWeakRetained:
-  case ARCInstKind::StoreWeak:
-  case ARCInstKind::InitWeak:
-  case ARCInstKind::LoadWeak:
-  case ARCInstKind::MoveWeak:
-  case ARCInstKind::CopyWeak:
-  case ARCInstKind::DestroyWeak:
-  case ARCInstKind::StoreStrong:
-  case ARCInstKind::IntrinsicUser:
-  case ARCInstKind::CallOrUser:
-  case ARCInstKind::Call:
-  case ARCInstKind::User:
-  case ARCInstKind::None:
-  case ARCInstKind::NoopCast:
-    return false;
-  }
-  llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class represents instructions which are always safe
-/// to mark with the "tail" keyword.
-bool llvm::objcarc::IsAlwaysTail(ARCInstKind Class) {
-  // ARCInstKind::RetainBlock may be given a stack argument.
-  switch (Class) {
-  case ARCInstKind::Retain:
-  case ARCInstKind::RetainRV:
-  case ARCInstKind::AutoreleaseRV:
-    return true;
-  case ARCInstKind::Release:
-  case ARCInstKind::Autorelease:
-  case ARCInstKind::RetainBlock:
-  case ARCInstKind::AutoreleasepoolPush:
-  case ARCInstKind::AutoreleasepoolPop:
-  case ARCInstKind::FusedRetainAutorelease:
-  case ARCInstKind::FusedRetainAutoreleaseRV:
-  case ARCInstKind::LoadWeakRetained:
-  case ARCInstKind::StoreWeak:
-  case ARCInstKind::InitWeak:
-  case ARCInstKind::LoadWeak:
-  case ARCInstKind::MoveWeak:
-  case ARCInstKind::CopyWeak:
-  case ARCInstKind::DestroyWeak:
-  case ARCInstKind::StoreStrong:
-  case ARCInstKind::IntrinsicUser:
-  case ARCInstKind::CallOrUser:
-  case ARCInstKind::Call:
-  case ARCInstKind::User:
-  case ARCInstKind::None:
-  case ARCInstKind::NoopCast:
-    return false;
-  }
-  llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class represents instructions which are never safe
-/// to mark with the "tail" keyword.
-bool llvm::objcarc::IsNeverTail(ARCInstKind Class) {
-  /// It is never safe to tail call objc_autorelease since by tail calling
-  /// objc_autorelease: fast autoreleasing causing our object to be potentially
-  /// reclaimed from the autorelease pool which violates the semantics of
-  /// __autoreleasing types in ARC.
-  switch (Class) {
-  case ARCInstKind::Autorelease:
-    return true;
-  case ARCInstKind::Retain:
-  case ARCInstKind::RetainRV:
-  case ARCInstKind::AutoreleaseRV:
-  case ARCInstKind::Release:
-  case ARCInstKind::RetainBlock:
-  case ARCInstKind::AutoreleasepoolPush:
-  case ARCInstKind::AutoreleasepoolPop:
-  case ARCInstKind::FusedRetainAutorelease:
-  case ARCInstKind::FusedRetainAutoreleaseRV:
-  case ARCInstKind::LoadWeakRetained:
-  case ARCInstKind::StoreWeak:
-  case ARCInstKind::InitWeak:
-  case ARCInstKind::LoadWeak:
-  case ARCInstKind::MoveWeak:
-  case ARCInstKind::CopyWeak:
-  case ARCInstKind::DestroyWeak:
-  case ARCInstKind::StoreStrong:
-  case ARCInstKind::IntrinsicUser:
-  case ARCInstKind::CallOrUser:
-  case ARCInstKind::Call:
-  case ARCInstKind::User:
-  case ARCInstKind::None:
-  case ARCInstKind::NoopCast:
-    return false;
-  }
-  llvm_unreachable("covered switch isn't covered?");
-}
-
-/// \brief Test if the given class represents instructions which are always safe
-/// to mark with the nounwind attribute.
-bool llvm::objcarc::IsNoThrow(ARCInstKind Class) {
-  // objc_retainBlock is not nounwind because it calls user copy constructors
-  // which could theoretically throw.
-  switch (Class) {
-  case ARCInstKind::Retain:
-  case ARCInstKind::RetainRV:
-  case ARCInstKind::Release:
-  case ARCInstKind::Autorelease:
-  case ARCInstKind::AutoreleaseRV:
-  case ARCInstKind::AutoreleasepoolPush:
-  case ARCInstKind::AutoreleasepoolPop:
-    return true;
-  case ARCInstKind::RetainBlock:
-  case ARCInstKind::FusedRetainAutorelease:
-  case ARCInstKind::FusedRetainAutoreleaseRV:
-  case ARCInstKind::LoadWeakRetained:
-  case ARCInstKind::StoreWeak:
-  case ARCInstKind::InitWeak:
-  case ARCInstKind::LoadWeak:
-  case ARCInstKind::MoveWeak:
-  case ARCInstKind::CopyWeak:
-  case ARCInstKind::DestroyWeak:
-  case ARCInstKind::StoreStrong:
-  case ARCInstKind::IntrinsicUser:
-  case ARCInstKind::CallOrUser:
-  case ARCInstKind::Call:
-  case ARCInstKind::User:
-  case ARCInstKind::None:
-  case ARCInstKind::NoopCast:
-    return false;
-  }
-  llvm_unreachable("covered switch isn't covered?");
-}
-
-/// Test whether the given instruction can autorelease any pointer or cause an
-/// autoreleasepool pop.
-///
-/// This means that it *could* interrupt the RV optimization.
-bool llvm::objcarc::CanInterruptRV(ARCInstKind Class) {
-  switch (Class) {
-  case ARCInstKind::AutoreleasepoolPop:
-  case ARCInstKind::CallOrUser:
-  case ARCInstKind::Call:
-  case ARCInstKind::Autorelease:
-  case ARCInstKind::AutoreleaseRV:
-  case ARCInstKind::FusedRetainAutorelease:
-  case ARCInstKind::FusedRetainAutoreleaseRV:
-    return true;
-  case ARCInstKind::Retain:
-  case ARCInstKind::RetainRV:
-  case ARCInstKind::Release:
-  case ARCInstKind::AutoreleasepoolPush:
-  case ARCInstKind::RetainBlock:
-  case ARCInstKind::LoadWeakRetained:
-  case ARCInstKind::StoreWeak:
-  case ARCInstKind::InitWeak:
-  case ARCInstKind::LoadWeak:
-  case ARCInstKind::MoveWeak:
-  case ARCInstKind::CopyWeak:
-  case ARCInstKind::DestroyWeak:
-  case ARCInstKind::StoreStrong:
-  case ARCInstKind::IntrinsicUser:
-  case ARCInstKind::User:
-  case ARCInstKind::None:
-  case ARCInstKind::NoopCast:
-    return false;
-  }
-  llvm_unreachable("covered switch isn't covered?");
-}
-
-bool llvm::objcarc::CanDecrementRefCount(ARCInstKind Kind) {
-  switch (Kind) {
-  case ARCInstKind::Retain:
-  case ARCInstKind::RetainRV:
-  case ARCInstKind::Autorelease:
-  case ARCInstKind::AutoreleaseRV:
-  case ARCInstKind::NoopCast:
-  case ARCInstKind::FusedRetainAutorelease:
-  case ARCInstKind::FusedRetainAutoreleaseRV:
-  case ARCInstKind::IntrinsicUser:
-  case ARCInstKind::User:
-  case ARCInstKind::None:
-    return false;
-
-  // The cases below are conservative.
-
-  // RetainBlock can result in user defined copy constructors being called
-  // implying releases may occur.
-  case ARCInstKind::RetainBlock:
-  case ARCInstKind::Release:
-  case ARCInstKind::AutoreleasepoolPush:
-  case ARCInstKind::AutoreleasepoolPop:
-  case ARCInstKind::LoadWeakRetained:
-  case ARCInstKind::StoreWeak:
-  case ARCInstKind::InitWeak:
-  case ARCInstKind::LoadWeak:
-  case ARCInstKind::MoveWeak:
-  case ARCInstKind::CopyWeak:
-  case ARCInstKind::DestroyWeak:
-  case ARCInstKind::StoreStrong:
-  case ARCInstKind::CallOrUser:
-  case ARCInstKind::Call:
-    return true;
-  }
-
-  llvm_unreachable("covered switch isn't covered?");
-}

Removed: llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h?rev=245540&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ARCInstKind.h (removed)
@@ -1,123 +0,0 @@
-//===--- ARCInstKind.h - ARC instruction equivalence classes -*- C++ -*----===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_ARCINSTKIND_H
-#define LLVM_LIB_TRANSFORMS_OBJCARC_ARCINSTKIND_H
-
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Function.h"
-
-namespace llvm {
-namespace objcarc {
-
-/// \enum ARCInstKind
-///
-/// \brief Equivalence classes of instructions in the ARC Model.
-///
-/// Since we do not have "instructions" to represent ARC concepts in LLVM IR,
-/// we instead operate on equivalence classes of instructions.
-///
-/// TODO: This should be split into two enums: a runtime entry point enum
-/// (possibly united with the ARCRuntimeEntrypoint class) and an enum that deals
-/// with effects of instructions in the ARC model (which would handle the notion
-/// of a User or CallOrUser).
-enum class ARCInstKind {
-  Retain,                   ///< objc_retain
-  RetainRV,                 ///< objc_retainAutoreleasedReturnValue
-  RetainBlock,              ///< objc_retainBlock
-  Release,                  ///< objc_release
-  Autorelease,              ///< objc_autorelease
-  AutoreleaseRV,            ///< objc_autoreleaseReturnValue
-  AutoreleasepoolPush,      ///< objc_autoreleasePoolPush
-  AutoreleasepoolPop,       ///< objc_autoreleasePoolPop
-  NoopCast,                 ///< objc_retainedObject, etc.
-  FusedRetainAutorelease,   ///< objc_retainAutorelease
-  FusedRetainAutoreleaseRV, ///< objc_retainAutoreleaseReturnValue
-  LoadWeakRetained,         ///< objc_loadWeakRetained (primitive)
-  StoreWeak,                ///< objc_storeWeak (primitive)
-  InitWeak,                 ///< objc_initWeak (derived)
-  LoadWeak,                 ///< objc_loadWeak (derived)
-  MoveWeak,                 ///< objc_moveWeak (derived)
-  CopyWeak,                 ///< objc_copyWeak (derived)
-  DestroyWeak,              ///< objc_destroyWeak (derived)
-  StoreStrong,              ///< objc_storeStrong (derived)
-  IntrinsicUser,            ///< clang.arc.use
-  CallOrUser,               ///< could call objc_release and/or "use" pointers
-  Call,                     ///< could call objc_release
-  User,                     ///< could "use" a pointer
-  None                      ///< anything that is inert from an ARC perspective.
-};
-
-raw_ostream &operator<<(raw_ostream &OS, const ARCInstKind Class);
-
-/// \brief Test if the given class is a kind of user.
-bool IsUser(ARCInstKind Class);
-
-/// \brief Test if the given class is objc_retain or equivalent.
-bool IsRetain(ARCInstKind Class);
-
-/// \brief Test if the given class is objc_autorelease or equivalent.
-bool IsAutorelease(ARCInstKind Class);
-
-/// \brief Test if the given class represents instructions which return their
-/// argument verbatim.
-bool IsForwarding(ARCInstKind Class);
-
-/// \brief Test if the given class represents instructions which do nothing if
-/// passed a null pointer.
-bool IsNoopOnNull(ARCInstKind Class);
-
-/// \brief Test if the given class represents instructions which are always safe
-/// to mark with the "tail" keyword.
-bool IsAlwaysTail(ARCInstKind Class);
-
-/// \brief Test if the given class represents instructions which are never safe
-/// to mark with the "tail" keyword.
-bool IsNeverTail(ARCInstKind Class);
-
-/// \brief Test if the given class represents instructions which are always safe
-/// to mark with the nounwind attribute.
-bool IsNoThrow(ARCInstKind Class);
-
-/// Test whether the given instruction can autorelease any pointer or cause an
-/// autoreleasepool pop.
-bool CanInterruptRV(ARCInstKind Class);
-
-/// \brief Determine if F is one of the special known Functions.  If it isn't,
-/// return ARCInstKind::CallOrUser.
-ARCInstKind GetFunctionClass(const Function *F);
-
-/// \brief Determine which objc runtime call instruction class V belongs to.
-///
-/// This is similar to GetARCInstKind except that it only detects objc
-/// runtime calls. This allows it to be faster.
-///
-static inline ARCInstKind GetBasicARCInstKind(const Value *V) {
-  if (const CallInst *CI = dyn_cast<CallInst>(V)) {
-    if (const Function *F = CI->getCalledFunction())
-      return GetFunctionClass(F);
-    // Otherwise, be conservative.
-    return ARCInstKind::CallOrUser;
-  }
-
-  // Otherwise, be conservative.
-  return isa<InvokeInst>(V) ? ARCInstKind::CallOrUser : ARCInstKind::User;
-}
-
-/// Map V to its ARCInstKind equivalence class.
-ARCInstKind GetARCInstKind(const Value *V);
-
-/// Returns false if conservatively we can prove that any instruction mapped to
-/// this kind can not decrement ref counts. Returns true otherwise.
-bool CanDecrementRefCount(ARCInstKind Kind);
-
-} // end namespace objcarc
-} // end namespace llvm
-
-#endif

Modified: llvm/trunk/lib/Transforms/ObjCARC/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/CMakeLists.txt?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/CMakeLists.txt (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/CMakeLists.txt Thu Aug 20 03:06:03 2015
@@ -3,8 +3,6 @@ add_llvm_library(LLVMObjCARCOpts
   ObjCARCOpts.cpp
   ObjCARCExpand.cpp
   ObjCARCAPElim.cpp
-  ObjCARCAliasAnalysis.cpp
-  ARCInstKind.cpp
   ObjCARCContract.cpp
   DependencyAnalysis.cpp
   ProvenanceAnalysis.cpp

Modified: llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.cpp Thu Aug 20 03:06:03 2015
@@ -26,14 +26,6 @@ namespace llvm {
 using namespace llvm;
 using namespace llvm::objcarc;
 
-/// \brief A handy option to enable/disable all ARC Optimizations.
-bool llvm::objcarc::EnableARCOpts;
-static cl::opt<bool, true>
-EnableARCOptimizations("enable-objc-arc-opts",
-                       cl::desc("enable/disable all ARC Optimizations"),
-                       cl::location(EnableARCOpts),
-                       cl::init(true));
-
 /// initializeObjCARCOptsPasses - Initialize all passes linked into the
 /// ObjCARCOpts library.
 void llvm::initializeObjCARCOpts(PassRegistry &Registry) {

Modified: llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARC.h Thu Aug 20 03:06:03 2015
@@ -26,6 +26,8 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/ObjCARCAnalysisUtils.h"
+#include "llvm/Analysis/ObjCARCInstKind.h"
 #include "llvm/Analysis/Passes.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/CallSite.h"
@@ -34,7 +36,6 @@
 #include "llvm/Pass.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Utils/Local.h"
-#include "ARCInstKind.h"
 
 namespace llvm {
 class raw_ostream;
@@ -43,99 +44,6 @@ class raw_ostream;
 namespace llvm {
 namespace objcarc {
 
-/// \brief A handy option to enable/disable all ARC Optimizations.
-extern bool EnableARCOpts;
-
-/// \brief Test if the given module looks interesting to run ARC optimization
-/// on.
-static inline bool ModuleHasARC(const Module &M) {
-  return
-    M.getNamedValue("objc_retain") ||
-    M.getNamedValue("objc_release") ||
-    M.getNamedValue("objc_autorelease") ||
-    M.getNamedValue("objc_retainAutoreleasedReturnValue") ||
-    M.getNamedValue("objc_retainBlock") ||
-    M.getNamedValue("objc_autoreleaseReturnValue") ||
-    M.getNamedValue("objc_autoreleasePoolPush") ||
-    M.getNamedValue("objc_loadWeakRetained") ||
-    M.getNamedValue("objc_loadWeak") ||
-    M.getNamedValue("objc_destroyWeak") ||
-    M.getNamedValue("objc_storeWeak") ||
-    M.getNamedValue("objc_initWeak") ||
-    M.getNamedValue("objc_moveWeak") ||
-    M.getNamedValue("objc_copyWeak") ||
-    M.getNamedValue("objc_retainedObject") ||
-    M.getNamedValue("objc_unretainedObject") ||
-    M.getNamedValue("objc_unretainedPointer") ||
-    M.getNamedValue("clang.arc.use");
-}
-
-/// \brief This is a wrapper around getUnderlyingObject which also knows how to
-/// look through objc_retain and objc_autorelease calls, which we know to return
-/// their argument verbatim.
-static inline const Value *GetUnderlyingObjCPtr(const Value *V,
-                                                const DataLayout &DL) {
-  for (;;) {
-    V = GetUnderlyingObject(V, DL);
-    if (!IsForwarding(GetBasicARCInstKind(V)))
-      break;
-    V = cast<CallInst>(V)->getArgOperand(0);
-  }
-
-  return V;
-}
-
-/// The RCIdentity root of a value \p V is a dominating value U for which
-/// retaining or releasing U is equivalent to retaining or releasing V. In other
-/// words, ARC operations on \p V are equivalent to ARC operations on \p U.
-///
-/// We use this in the ARC optimizer to make it easier to match up ARC
-/// operations by always mapping ARC operations to RCIdentityRoots instead of
-/// pointers themselves.
-///
-/// The two ways that we see RCIdentical values in ObjC are via:
-///
-///   1. PointerCasts
-///   2. Forwarding Calls that return their argument verbatim.
-///
-/// Thus this function strips off pointer casts and forwarding calls. *NOTE*
-/// This implies that two RCIdentical values must alias.
-static inline const Value *GetRCIdentityRoot(const Value *V) {
-  for (;;) {
-    V = V->stripPointerCasts();
-    if (!IsForwarding(GetBasicARCInstKind(V)))
-      break;
-    V = cast<CallInst>(V)->getArgOperand(0);
-  }
-  return V;
-}
-
-/// Helper which calls const Value *GetRCIdentityRoot(const Value *V) and just
-/// casts away the const of the result. For documentation about what an
-/// RCIdentityRoot (and by extension GetRCIdentityRoot is) look at that
-/// function.
-static inline Value *GetRCIdentityRoot(Value *V) {
-  return const_cast<Value *>(GetRCIdentityRoot((const Value *)V));
-}
-
-/// \brief Assuming the given instruction is one of the special calls such as
-/// objc_retain or objc_release, return the RCIdentity root of the argument of
-/// the call.
-static inline Value *GetArgRCIdentityRoot(Value *Inst) {
-  return GetRCIdentityRoot(cast<CallInst>(Inst)->getArgOperand(0));
-}
-
-static inline bool IsNullOrUndef(const Value *V) {
-  return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
-}
-
-static inline bool IsNoopInstruction(const Instruction *I) {
-  return isa<BitCastInst>(I) ||
-    (isa<GetElementPtrInst>(I) &&
-     cast<GetElementPtrInst>(I)->hasAllZeroIndices());
-}
-
-
 /// \brief Erase the given instruction.
 ///
 /// Many ObjC calls return their argument verbatim,
@@ -162,152 +70,6 @@ static inline void EraseInstruction(Inst
     RecursivelyDeleteTriviallyDeadInstructions(OldArg);
 }
 
-/// \brief Test whether the given value is possible a retainable object pointer.
-static inline bool IsPotentialRetainableObjPtr(const Value *Op) {
-  // Pointers to static or stack storage are not valid retainable object
-  // pointers.
-  if (isa<Constant>(Op) || isa<AllocaInst>(Op))
-    return false;
-  // Special arguments can not be a valid retainable object pointer.
-  if (const Argument *Arg = dyn_cast<Argument>(Op))
-    if (Arg->hasByValAttr() ||
-        Arg->hasInAllocaAttr() ||
-        Arg->hasNestAttr() ||
-        Arg->hasStructRetAttr())
-      return false;
-  // Only consider values with pointer types.
-  //
-  // It seemes intuitive to exclude function pointer types as well, since
-  // functions are never retainable object pointers, however clang occasionally
-  // bitcasts retainable object pointers to function-pointer type temporarily.
-  PointerType *Ty = dyn_cast<PointerType>(Op->getType());
-  if (!Ty)
-    return false;
-  // Conservatively assume anything else is a potential retainable object
-  // pointer.
-  return true;
-}
-
-static inline bool IsPotentialRetainableObjPtr(const Value *Op,
-                                               AliasAnalysis &AA) {
-  // First make the rudimentary check.
-  if (!IsPotentialRetainableObjPtr(Op))
-    return false;
-
-  // Objects in constant memory are not reference-counted.
-  if (AA.pointsToConstantMemory(Op))
-    return false;
-
-  // Pointers in constant memory are not pointing to reference-counted objects.
-  if (const LoadInst *LI = dyn_cast<LoadInst>(Op))
-    if (AA.pointsToConstantMemory(LI->getPointerOperand()))
-      return false;
-
-  // Otherwise assume the worst.
-  return true;
-}
-
-/// \brief Helper for GetARCInstKind. Determines what kind of construct CS
-/// is.
-static inline ARCInstKind GetCallSiteClass(ImmutableCallSite CS) {
-  for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
-       I != E; ++I)
-    if (IsPotentialRetainableObjPtr(*I))
-      return CS.onlyReadsMemory() ? ARCInstKind::User : ARCInstKind::CallOrUser;
-
-  return CS.onlyReadsMemory() ? ARCInstKind::None : ARCInstKind::Call;
-}
-
-/// \brief Return true if this value refers to a distinct and identifiable
-/// object.
-///
-/// This is similar to AliasAnalysis's isIdentifiedObject, except that it uses
-/// special knowledge of ObjC conventions.
-static inline bool IsObjCIdentifiedObject(const Value *V) {
-  // Assume that call results and arguments have their own "provenance".
-  // Constants (including GlobalVariables) and Allocas are never
-  // reference-counted.
-  if (isa<CallInst>(V) || isa<InvokeInst>(V) ||
-      isa<Argument>(V) || isa<Constant>(V) ||
-      isa<AllocaInst>(V))
-    return true;
-
-  if (const LoadInst *LI = dyn_cast<LoadInst>(V)) {
-    const Value *Pointer =
-      GetRCIdentityRoot(LI->getPointerOperand());
-    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) {
-      // A constant pointer can't be pointing to an object on the heap. It may
-      // be reference-counted, but it won't be deleted.
-      if (GV->isConstant())
-        return true;
-      StringRef Name = GV->getName();
-      // These special variables are known to hold values which are not
-      // reference-counted pointers.
-      if (Name.startswith("\01l_objc_msgSend_fixup_"))
-        return true;
-
-      StringRef Section = GV->getSection();
-      if (Section.find("__message_refs") != StringRef::npos ||
-          Section.find("__objc_classrefs") != StringRef::npos ||
-          Section.find("__objc_superrefs") != StringRef::npos ||
-          Section.find("__objc_methname") != StringRef::npos ||
-          Section.find("__cstring") != StringRef::npos)
-        return true;
-    }
-  }
-
-  return false;
-}
-
-enum class ARCMDKindID {
-  ImpreciseRelease,
-  CopyOnEscape,
-  NoObjCARCExceptions,
-};
-
-/// A cache of MDKinds used by various ARC optimizations.
-class ARCMDKindCache {
-  Module *M;
-
-  /// The Metadata Kind for clang.imprecise_release metadata.
-  llvm::Optional<unsigned> ImpreciseReleaseMDKind;
-
-  /// The Metadata Kind for clang.arc.copy_on_escape metadata.
-  llvm::Optional<unsigned> CopyOnEscapeMDKind;
-
-  /// The Metadata Kind for clang.arc.no_objc_arc_exceptions metadata.
-  llvm::Optional<unsigned> NoObjCARCExceptionsMDKind;
-
-public:
-  void init(Module *Mod) {
-    M = Mod;
-    ImpreciseReleaseMDKind = NoneType::None;
-    CopyOnEscapeMDKind = NoneType::None;
-    NoObjCARCExceptionsMDKind = NoneType::None;
-  }
-
-  unsigned get(ARCMDKindID ID) {
-    switch (ID) {
-    case ARCMDKindID::ImpreciseRelease:
-      if (!ImpreciseReleaseMDKind)
-        ImpreciseReleaseMDKind =
-            M->getContext().getMDKindID("clang.imprecise_release");
-      return *ImpreciseReleaseMDKind;
-    case ARCMDKindID::CopyOnEscape:
-      if (!CopyOnEscapeMDKind)
-        CopyOnEscapeMDKind =
-            M->getContext().getMDKindID("clang.arc.copy_on_escape");
-      return *CopyOnEscapeMDKind;
-    case ARCMDKindID::NoObjCARCExceptions:
-      if (!NoObjCARCExceptionsMDKind)
-        NoObjCARCExceptionsMDKind =
-            M->getContext().getMDKindID("clang.arc.no_objc_arc_exceptions");
-      return *NoObjCARCExceptionsMDKind;
-    }
-    llvm_unreachable("Covered switch isn't covered?!");
-  }
-};
-
 } // end namespace objcarc
 } // end namespace llvm
 

Removed: llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp?rev=245540&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.cpp (removed)
@@ -1,162 +0,0 @@
-//===- ObjCARCAliasAnalysis.cpp - ObjC ARC Optimization -------------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file defines a simple ARC-aware AliasAnalysis using special knowledge
-/// of Objective C to enhance other optimization passes which rely on the Alias
-/// Analysis infrastructure.
-///
-/// WARNING: This file knows about certain library functions. It recognizes them
-/// by name, and hardwires knowledge of their semantics.
-///
-/// WARNING: This file knows about how certain Objective-C library functions are
-/// used. Naive LLVM IR transformations which would otherwise be
-/// behavior-preserving may break these assumptions.
-///
-//===----------------------------------------------------------------------===//
-
-#include "ObjCARC.h"
-#include "ObjCARCAliasAnalysis.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Value.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/PassAnalysisSupport.h"
-#include "llvm/PassSupport.h"
-
-#define DEBUG_TYPE "objc-arc-aa"
-
-using namespace llvm;
-using namespace llvm::objcarc;
-
-// Register this pass...
-char ObjCARCAliasAnalysis::ID = 0;
-INITIALIZE_AG_PASS(ObjCARCAliasAnalysis, AliasAnalysis, "objc-arc-aa",
-                   "ObjC-ARC-Based Alias Analysis", false, true, false)
-
-ImmutablePass *llvm::createObjCARCAliasAnalysisPass() {
-  return new ObjCARCAliasAnalysis();
-}
-
-bool ObjCARCAliasAnalysis::doInitialization(Module &M) {
-  InitializeAliasAnalysis(this, &M.getDataLayout());
-  return true;
-}
-
-void ObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
-  AU.setPreservesAll();
-  AliasAnalysis::getAnalysisUsage(AU);
-}
-
-AliasResult ObjCARCAliasAnalysis::alias(const MemoryLocation &LocA,
-                                        const MemoryLocation &LocB) {
-  if (!EnableARCOpts)
-    return AliasAnalysis::alias(LocA, LocB);
-
-  // First, strip off no-ops, including ObjC-specific no-ops, and try making a
-  // precise alias query.
-  const Value *SA = GetRCIdentityRoot(LocA.Ptr);
-  const Value *SB = GetRCIdentityRoot(LocB.Ptr);
-  AliasResult Result =
-      AliasAnalysis::alias(MemoryLocation(SA, LocA.Size, LocA.AATags),
-                           MemoryLocation(SB, LocB.Size, LocB.AATags));
-  if (Result != MayAlias)
-    return Result;
-
-  // If that failed, climb to the underlying object, including climbing through
-  // ObjC-specific no-ops, and try making an imprecise alias query.
-  const Value *UA = GetUnderlyingObjCPtr(SA, *DL);
-  const Value *UB = GetUnderlyingObjCPtr(SB, *DL);
-  if (UA != SA || UB != SB) {
-    Result = AliasAnalysis::alias(MemoryLocation(UA), MemoryLocation(UB));
-    // We can't use MustAlias or PartialAlias results here because
-    // GetUnderlyingObjCPtr may return an offsetted pointer value.
-    if (Result == NoAlias)
-      return NoAlias;
-  }
-
-  // If that failed, fail. We don't need to chain here, since that's covered
-  // by the earlier precise query.
-  return MayAlias;
-}
-
-bool ObjCARCAliasAnalysis::pointsToConstantMemory(const MemoryLocation &Loc,
-                                                  bool OrLocal) {
-  if (!EnableARCOpts)
-    return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
-
-  // First, strip off no-ops, including ObjC-specific no-ops, and try making
-  // a precise alias query.
-  const Value *S = GetRCIdentityRoot(Loc.Ptr);
-  if (AliasAnalysis::pointsToConstantMemory(
-          MemoryLocation(S, Loc.Size, Loc.AATags), OrLocal))
-    return true;
-
-  // If that failed, climb to the underlying object, including climbing through
-  // ObjC-specific no-ops, and try making an imprecise alias query.
-  const Value *U = GetUnderlyingObjCPtr(S, *DL);
-  if (U != S)
-    return AliasAnalysis::pointsToConstantMemory(MemoryLocation(U), OrLocal);
-
-  // If that failed, fail. We don't need to chain here, since that's covered
-  // by the earlier precise query.
-  return false;
-}
-
-FunctionModRefBehavior
-ObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
-  // We have nothing to do. Just chain to the next AliasAnalysis.
-  return AliasAnalysis::getModRefBehavior(CS);
-}
-
-FunctionModRefBehavior
-ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
-  if (!EnableARCOpts)
-    return AliasAnalysis::getModRefBehavior(F);
-
-  switch (GetFunctionClass(F)) {
-  case ARCInstKind::NoopCast:
-    return FMRB_DoesNotAccessMemory;
-  default:
-    break;
-  }
-
-  return AliasAnalysis::getModRefBehavior(F);
-}
-
-ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS,
-                                               const MemoryLocation &Loc) {
-  if (!EnableARCOpts)
-    return AliasAnalysis::getModRefInfo(CS, Loc);
-
-  switch (GetBasicARCInstKind(CS.getInstruction())) {
-  case ARCInstKind::Retain:
-  case ARCInstKind::RetainRV:
-  case ARCInstKind::Autorelease:
-  case ARCInstKind::AutoreleaseRV:
-  case ARCInstKind::NoopCast:
-  case ARCInstKind::AutoreleasepoolPush:
-  case ARCInstKind::FusedRetainAutorelease:
-  case ARCInstKind::FusedRetainAutoreleaseRV:
-    // These functions don't access any memory visible to the compiler.
-    // Note that this doesn't include objc_retainBlock, because it updates
-    // pointers when it copies block data.
-    return MRI_NoModRef;
-  default:
-    break;
-  }
-
-  return AliasAnalysis::getModRefInfo(CS, Loc);
-}
-
-ModRefInfo ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
-                                               ImmutableCallSite CS2) {
-  // TODO: Theoretically we could check for dependencies between objc_* calls
-  // and FMRB_OnlyAccessesArgumentPointees calls or other well-behaved calls.
-  return AliasAnalysis::getModRefInfo(CS1, CS2);
-}

Removed: llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h?rev=245540&view=auto
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARCAliasAnalysis.h (removed)
@@ -1,72 +0,0 @@
-//===- ObjCARCAliasAnalysis.h - ObjC ARC Optimization -*- C++ -*-----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-/// \file
-/// This file declares a simple ARC-aware AliasAnalysis using special knowledge
-/// of Objective C to enhance other optimization passes which rely on the Alias
-/// Analysis infrastructure.
-///
-/// WARNING: This file knows about certain library functions. It recognizes them
-/// by name, and hardwires knowledge of their semantics.
-///
-/// WARNING: This file knows about how certain Objective-C library functions are
-/// used. Naive LLVM IR transformations which would otherwise be
-/// behavior-preserving may break these assumptions.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARCALIASANALYSIS_H
-#define LLVM_LIB_TRANSFORMS_OBJCARC_OBJCARCALIASANALYSIS_H
-
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Pass.h"
-
-namespace llvm {
-namespace objcarc {
-
-/// \brief This is a simple alias analysis implementation that uses knowledge
-/// of ARC constructs to answer queries.
-///
-/// TODO: This class could be generalized to know about other ObjC-specific
-/// tricks. Such as knowing that ivars in the non-fragile ABI are non-aliasing
-/// even though their offsets are dynamic.
-class ObjCARCAliasAnalysis : public ImmutablePass, public AliasAnalysis {
-public:
-  static char ID; // Class identification, replacement for typeinfo
-  ObjCARCAliasAnalysis() : ImmutablePass(ID) {
-    initializeObjCARCAliasAnalysisPass(*PassRegistry::getPassRegistry());
-  }
-
-private:
-  bool doInitialization(Module &M) override;
-
-  /// This method is used when a pass implements an analysis interface through
-  /// multiple inheritance.  If needed, it should override this to adjust the
-  /// this pointer as needed for the specified pass info.
-  void *getAdjustedAnalysisPointer(const void *PI) override {
-    if (PI == &AliasAnalysis::ID)
-      return static_cast<AliasAnalysis *>(this);
-    return this;
-  }
-
-  void getAnalysisUsage(AnalysisUsage &AU) const override;
-  AliasResult alias(const MemoryLocation &LocA,
-                    const MemoryLocation &LocB) override;
-  bool pointsToConstantMemory(const MemoryLocation &Loc, bool OrLocal) override;
-  FunctionModRefBehavior getModRefBehavior(ImmutableCallSite CS) override;
-  FunctionModRefBehavior getModRefBehavior(const Function *F) override;
-  ModRefInfo getModRefInfo(ImmutableCallSite CS,
-                           const MemoryLocation &Loc) override;
-  ModRefInfo getModRefInfo(ImmutableCallSite CS1,
-                           ImmutableCallSite CS2) override;
-};
-
-} // namespace objcarc
-} // namespace llvm
-
-#endif

Modified: llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARCOpts.cpp Thu Aug 20 03:06:03 2015
@@ -28,7 +28,6 @@
 #include "ARCRuntimeEntryPoints.h"
 #include "BlotMapVector.h"
 #include "DependencyAnalysis.h"
-#include "ObjCARCAliasAnalysis.h"
 #include "ProvenanceAnalysis.h"
 #include "PtrState.h"
 #include "llvm/ADT/DenseMap.h"
@@ -36,6 +35,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/ObjCARCAliasAnalysis.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/LLVMContext.h"

Modified: llvm/trunk/lib/Transforms/ObjCARC/PtrState.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/ObjCARC/PtrState.h?rev=245541&r1=245540&r2=245541&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/PtrState.h (original)
+++ llvm/trunk/lib/Transforms/ObjCARC/PtrState.h Thu Aug 20 03:06:03 2015
@@ -17,8 +17,8 @@
 #ifndef LLVM_LIB_TRANSFORMS_OBJCARC_PTRSTATE_H
 #define LLVM_LIB_TRANSFORMS_OBJCARC_PTRSTATE_H
 
-#include "ARCInstKind.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Analysis/ObjCARCInstKind.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/Value.h"
 #include "llvm/Support/raw_ostream.h"




More information about the llvm-commits mailing list