Skip to content
ObjCARC.cpp 132 KiB
Newer Older
//===- ObjCARC.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.
//
//===----------------------------------------------------------------------===//
//
// This file defines ObjC ARC optimizations. ARC stands for
// Automatic Reference Counting and is a system for managing reference counts
// for objects in Objective C.
//
// The optimizations performed include elimination of redundant, partially
// redundant, and inconsequential reference count operations, elimination of
// redundant weak pointer operations, pattern-matching and replacement of
// low-level operations into higher-level operations, and numerous minor
// simplifications.
//
// This file also defines a simple ARC-aware AliasAnalysis.
//
// WARNING: This file knows about certain library functions. It recognizes them
// by name, and hardwires knowedge 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.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "objc-arc"
#include "llvm/Function.h"
#include "llvm/Intrinsics.h"
#include "llvm/GlobalVariable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Support/CallSite.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
using namespace llvm;

// A handy option to enable/disable all optimizations in this file.
static cl::opt<bool> EnableARCOpts("enable-objc-arc-opts", cl::init(true));

//===----------------------------------------------------------------------===//
// Misc. Utilities
//===----------------------------------------------------------------------===//

namespace {
  /// MapVector - An associative container with fast insertion-order
  /// (deterministic) iteration over its elements. Plus the special
  /// blot operation.
  template<class KeyT, class ValueT>
  class MapVector {
    /// Map - Map keys to indices in Vector.
    typedef DenseMap<KeyT, size_t> MapTy;
    MapTy Map;

    /// Vector - Keys and values.
    typedef std::vector<std::pair<KeyT, ValueT> > VectorTy;
    VectorTy Vector;

  public:
    typedef typename VectorTy::iterator iterator;
    typedef typename VectorTy::const_iterator const_iterator;
    iterator begin() { return Vector.begin(); }
    iterator end() { return Vector.end(); }
    const_iterator begin() const { return Vector.begin(); }
    const_iterator end() const { return Vector.end(); }

#ifdef XDEBUG
    ~MapVector() {
      assert(Vector.size() >= Map.size()); // May differ due to blotting.
      for (typename MapTy::const_iterator I = Map.begin(), E = Map.end();
           I != E; ++I) {
        assert(I->second < Vector.size());
        assert(Vector[I->second].first == I->first);
      }
      for (typename VectorTy::const_iterator I = Vector.begin(),
           E = Vector.end(); I != E; ++I)
        assert(!I->first ||
               (Map.count(I->first) &&
                Map[I->first] == size_t(I - Vector.begin())));
    }
#endif

    ValueT &operator[](KeyT Arg) {
      std::pair<typename MapTy::iterator, bool> Pair =
        Map.insert(std::make_pair(Arg, size_t(0)));
      if (Pair.second) {
        Pair.first->second = Vector.size();
        Vector.push_back(std::make_pair(Arg, ValueT()));
        return Vector.back().second;
      }
      return Vector[Pair.first->second].second;
    }

    std::pair<iterator, bool>
    insert(const std::pair<KeyT, ValueT> &InsertPair) {
      std::pair<typename MapTy::iterator, bool> Pair =
        Map.insert(std::make_pair(InsertPair.first, size_t(0)));
      if (Pair.second) {
        Pair.first->second = Vector.size();
        Vector.push_back(InsertPair);
        return std::make_pair(llvm::prior(Vector.end()), true);
      }
      return std::make_pair(Vector.begin() + Pair.first->second, false);
    }

    const_iterator find(KeyT Key) const {
      typename MapTy::const_iterator It = Map.find(Key);
      if (It == Map.end()) return Vector.end();
      return Vector.begin() + It->second;
    }

    /// blot - This is similar to erase, but instead of removing the element
    /// from the vector, it just zeros out the key in the vector. This leaves
    /// iterators intact, but clients must be prepared for zeroed-out keys when
    /// iterating.
    void blot(KeyT Key) {
      typename MapTy::iterator It = Map.find(Key);
      if (It == Map.end()) return;
      Vector[It->second].first = KeyT();
      Map.erase(It);
    }

    void clear() {
      Map.clear();
      Vector.clear();
    }
  };
}

//===----------------------------------------------------------------------===//
// ARC Utilities.
//===----------------------------------------------------------------------===//

namespace {
  /// InstructionClass - A simple classification for instructions.
  enum InstructionClass {
    IC_Retain,              ///< objc_retain
    IC_RetainRV,            ///< objc_retainAutoreleasedReturnValue
    IC_RetainBlock,         ///< objc_retainBlock
    IC_Release,             ///< objc_release
    IC_Autorelease,         ///< objc_autorelease
    IC_AutoreleaseRV,       ///< objc_autoreleaseReturnValue
    IC_AutoreleasepoolPush, ///< objc_autoreleasePoolPush
    IC_AutoreleasepoolPop,  ///< objc_autoreleasePoolPop
    IC_NoopCast,            ///< objc_retainedObject, etc.
    IC_FusedRetainAutorelease, ///< objc_retainAutorelease
    IC_FusedRetainAutoreleaseRV, ///< objc_retainAutoreleaseReturnValue
    IC_LoadWeakRetained,    ///< objc_loadWeakRetained (primitive)
    IC_StoreWeak,           ///< objc_storeWeak (primitive)
    IC_InitWeak,            ///< objc_initWeak (derived)
    IC_LoadWeak,            ///< objc_loadWeak (derived)
    IC_MoveWeak,            ///< objc_moveWeak (derived)
    IC_CopyWeak,            ///< objc_copyWeak (derived)
    IC_DestroyWeak,         ///< objc_destroyWeak (derived)
    IC_CallOrUser,          ///< could call objc_release and/or "use" pointers
    IC_Call,                ///< could call objc_release
    IC_User,                ///< could "use" a pointer
    IC_None                 ///< anything else
  };
}

/// IsPotentialUse - Test whether the given value is possible a
/// reference-counted pointer.
static bool IsPotentialUse(const Value *Op) {
  // Pointers to static or stack storage are not reference-counted pointers.
  if (isa<Constant>(Op) || isa<AllocaInst>(Op))
    return false;
  // Special arguments are not reference-counted.
  if (const Argument *Arg = dyn_cast<Argument>(Op))
    if (Arg->hasByValAttr() ||
        Arg->hasNestAttr() ||
        Arg->hasStructRetAttr())
      return false;
  // Only consider values with pointer types, and not function pointers.
  PointerType *Ty = dyn_cast<PointerType>(Op->getType());
  if (!Ty || isa<FunctionType>(Ty->getElementType()))
    return false;
  // Conservatively assume anything else is a potential use.
  return true;
}

/// GetCallSiteClass - Helper for GetInstructionClass. Determines what kind
/// of construct CS is.
static InstructionClass GetCallSiteClass(ImmutableCallSite CS) {
  for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
       I != E; ++I)
    if (IsPotentialUse(*I))
      return CS.onlyReadsMemory() ? IC_User : IC_CallOrUser;

  return CS.onlyReadsMemory() ? IC_None : IC_Call;
}

/// GetFunctionClass - Determine if F is one of the special known Functions.
/// If it isn't, return IC_CallOrUser.
static InstructionClass GetFunctionClass(const Function *F) {
  Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();

  // No arguments.
  if (AI == AE)
    return StringSwitch<InstructionClass>(F->getName())
      .Case("objc_autoreleasePoolPush",  IC_AutoreleasepoolPush)
      .Default(IC_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<InstructionClass>(F->getName())
          .Case("objc_retain",                IC_Retain)
          .Case("objc_retainAutoreleasedReturnValue", IC_RetainRV)
          .Case("objc_retainBlock",           IC_RetainBlock)
          .Case("objc_release",               IC_Release)
          .Case("objc_autorelease",           IC_Autorelease)
          .Case("objc_autoreleaseReturnValue", IC_AutoreleaseRV)
          .Case("objc_autoreleasePoolPop",    IC_AutoreleasepoolPop)
          .Case("objc_retainedObject",        IC_NoopCast)
          .Case("objc_unretainedObject",      IC_NoopCast)
          .Case("objc_unretainedPointer",     IC_NoopCast)
          .Case("objc_retain_autorelease",    IC_FusedRetainAutorelease)
          .Case("objc_retainAutorelease",     IC_FusedRetainAutorelease)
          .Case("objc_retainAutoreleaseReturnValue",IC_FusedRetainAutoreleaseRV)
          .Default(IC_CallOrUser);

      // Argument is i8**
      if (PointerType *Pte = dyn_cast<PointerType>(ETy))
        if (Pte->getElementType()->isIntegerTy(8))
          return StringSwitch<InstructionClass>(F->getName())
            .Case("objc_loadWeakRetained",      IC_LoadWeakRetained)
            .Case("objc_loadWeak",              IC_LoadWeak)
            .Case("objc_destroyWeak",           IC_DestroyWeak)
            .Default(IC_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<InstructionClass>(F->getName())
                     .Case("objc_storeWeak",             IC_StoreWeak)
                     .Case("objc_initWeak",              IC_InitWeak)
                     .Default(IC_CallOrUser);
            // Second argument is i8**.
            if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1))
              if (Pte1->getElementType()->isIntegerTy(8))
                return StringSwitch<InstructionClass>(F->getName())
                       .Case("objc_moveWeak",              IC_MoveWeak)
                       .Case("objc_copyWeak",              IC_CopyWeak)
                       .Default(IC_CallOrUser);
          }

  // Anything else.
  return IC_CallOrUser;
}

/// GetInstructionClass - Determine what kind of construct V is.
static InstructionClass GetInstructionClass(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);
      // Check for calls to special functions.
      if (const Function *F = CI->getCalledFunction()) {
        InstructionClass Class = GetFunctionClass(F);
        if (Class != IC_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 0: break;
        case Intrinsic::bswap: case Intrinsic::ctpop:
        case Intrinsic::ctlz: case Intrinsic::cttz:
        case Intrinsic::returnaddress: case Intrinsic::frameaddress:
        case Intrinsic::stacksave: case Intrinsic::stackrestore:
        case Intrinsic::vastart: case Intrinsic::vacopy: case Intrinsic::vaend:
        // 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 IC_None;
        default:
          for (Function::const_arg_iterator AI = F->arg_begin(),
               AE = F->arg_end(); AI != AE; ++AI)
            if (IsPotentialUse(AI))
              return IC_User;
          return IC_None;
        }
      }
      return GetCallSiteClass(CI);
    }
    case Instruction::Invoke:
      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 (IsPotentialUse(I->getOperand(1)))
        return IC_User;
      break;
    default:
      // For anything else, check all the operands.
Dan Gohman's avatar
Dan Gohman committed
      // 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 (IsPotentialUse(*OI))
          return IC_User;
    }
  }

  // Otherwise, it's totally inert for ARC purposes.
  return IC_None;
}

/// GetBasicInstructionClass - Determine what kind of construct V is. This is
/// similar to GetInstructionClass except that it only detects objc runtine
/// calls. This allows it to be faster.
static InstructionClass GetBasicInstructionClass(const Value *V) {
  if (const CallInst *CI = dyn_cast<CallInst>(V)) {
    if (const Function *F = CI->getCalledFunction())
      return GetFunctionClass(F);
    // Otherwise, be conservative.
    return IC_CallOrUser;
  }

  // Otherwise, be conservative.
  return IC_User;
}

/// IsRetain - Test if the the given class is objc_retain or
/// equivalent.
static bool IsRetain(InstructionClass Class) {
  return Class == IC_Retain ||
         Class == IC_RetainRV;
}

/// IsAutorelease - Test if the the given class is objc_autorelease or
/// equivalent.
static bool IsAutorelease(InstructionClass Class) {
  return Class == IC_Autorelease ||
         Class == IC_AutoreleaseRV;
}

/// IsForwarding - Test if the given class represents instructions which return
/// their argument verbatim.
static bool IsForwarding(InstructionClass Class) {
  // objc_retainBlock technically doesn't always return its argument
  // verbatim, but it doesn't matter for our purposes here.
  return Class == IC_Retain ||
         Class == IC_RetainRV ||
         Class == IC_Autorelease ||
         Class == IC_AutoreleaseRV ||
         Class == IC_RetainBlock ||
         Class == IC_NoopCast;
}

/// IsNoopOnNull - Test if the given class represents instructions which do
/// nothing if passed a null pointer.
static bool IsNoopOnNull(InstructionClass Class) {
  return Class == IC_Retain ||
         Class == IC_RetainRV ||
         Class == IC_Release ||
         Class == IC_Autorelease ||
         Class == IC_AutoreleaseRV ||
         Class == IC_RetainBlock;
}

/// IsAlwaysTail - Test if the given class represents instructions which are
/// always safe to mark with the "tail" keyword.
static bool IsAlwaysTail(InstructionClass Class) {
  // IC_RetainBlock may be given a stack argument.
  return Class == IC_Retain ||
         Class == IC_RetainRV ||
         Class == IC_Autorelease ||
         Class == IC_AutoreleaseRV;
}

/// IsNoThrow - Test if the given class represents instructions which are always
/// safe to mark with the nounwind attribute..
static bool IsNoThrow(InstructionClass Class) {
  // objc_retainBlock is not nounwind because it calls user copy constructors
  // which could theoretically throw.
  return Class == IC_Retain ||
         Class == IC_RetainRV ||
         Class == IC_Release ||
         Class == IC_Autorelease ||
         Class == IC_AutoreleaseRV ||
         Class == IC_AutoreleasepoolPush ||
         Class == IC_AutoreleasepoolPop;
}

/// EraseInstruction - Erase the given instruction. 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 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(GetBasicInstructionClass(CI)) &&
           "Can't delete non-forwarding instruction with users!");
    CI->replaceAllUsesWith(OldArg);
  }

  CI->eraseFromParent();

  if (Unused)
    RecursivelyDeleteTriviallyDeadInstructions(OldArg);
}

/// GetUnderlyingObjCPtr - 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 const Value *GetUnderlyingObjCPtr(const Value *V) {
  for (;;) {
    V = GetUnderlyingObject(V);
    if (!IsForwarding(GetBasicInstructionClass(V)))
      break;
    V = cast<CallInst>(V)->getArgOperand(0);
  }

  return V;
}

/// StripPointerCastsAndObjCCalls - This is a wrapper around
/// Value::stripPointerCasts which also knows how to look through objc_retain
/// and objc_autorelease calls, which we know to return their argument verbatim.
static const Value *StripPointerCastsAndObjCCalls(const Value *V) {
  for (;;) {
    V = V->stripPointerCasts();
    if (!IsForwarding(GetBasicInstructionClass(V)))
      break;
    V = cast<CallInst>(V)->getArgOperand(0);
  }
  return V;
}

/// StripPointerCastsAndObjCCalls - This is a wrapper around
/// Value::stripPointerCasts which also knows how to look through objc_retain
/// and objc_autorelease calls, which we know to return their argument verbatim.
static Value *StripPointerCastsAndObjCCalls(Value *V) {
  for (;;) {
    V = V->stripPointerCasts();
    if (!IsForwarding(GetBasicInstructionClass(V)))
      break;
    V = cast<CallInst>(V)->getArgOperand(0);
  }
  return V;
}

/// GetObjCArg - Assuming the given instruction is one of the special calls such
/// as objc_retain or objc_release, return the argument value, stripped of no-op
/// casts and forwarding calls.
static Value *GetObjCArg(Value *Inst) {
  return StripPointerCastsAndObjCCalls(cast<CallInst>(Inst)->getArgOperand(0));
}

/// IsObjCIdentifiedObject - This is similar to AliasAnalysis'
/// isObjCIdentifiedObject, except that it uses special knowledge of
/// ObjC conventions...
static 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 =
      StripPointerCastsAndObjCCalls(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_SELECTOR_REFERENCES_") ||
          Name.startswith("\01L_OBJC_CLASSLIST_REFERENCES_") ||
          Name.startswith("\01L_OBJC_CLASSLIST_SUP_REFS_$_") ||
          Name.startswith("\01L_OBJC_METH_VAR_NAME_") ||
          Name.startswith("\01l_objc_msgSend_fixup_"))
        return true;
    }
  }

  return false;
}

/// FindSingleUseIdentifiedObject - This is similar to
/// StripPointerCastsAndObjCCalls but it stops as soon as it finds a value
/// with multiple uses.
static const Value *FindSingleUseIdentifiedObject(const Value *Arg) {
  if (Arg->hasOneUse()) {
    if (const BitCastInst *BC = dyn_cast<BitCastInst>(Arg))
      return FindSingleUseIdentifiedObject(BC->getOperand(0));
    if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Arg))
      if (GEP->hasAllZeroIndices())
        return FindSingleUseIdentifiedObject(GEP->getPointerOperand());
    if (IsForwarding(GetBasicInstructionClass(Arg)))
      return FindSingleUseIdentifiedObject(
               cast<CallInst>(Arg)->getArgOperand(0));
    if (!IsObjCIdentifiedObject(Arg))
      return 0;
    return Arg;
  }

  // If we found an identifiable object but it has multiple uses, but they
  // are trivial uses, we can still consider this to be a single-use
  // value.
  if (IsObjCIdentifiedObject(Arg)) {
    for (Value::const_use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
         UI != UE; ++UI) {
      const User *U = *UI;
      if (!U->use_empty() || StripPointerCastsAndObjCCalls(U) != Arg)
         return 0;
    }

    return Arg;
  }

  return 0;
}

/// ModuleHasARC - Test if the given module looks interesting to run ARC
/// optimization on.
static 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");
}

//===----------------------------------------------------------------------===//
// ARC AliasAnalysis.
//===----------------------------------------------------------------------===//

#include "llvm/Pass.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/Passes.h"

namespace {
  /// ObjCARCAliasAnalysis - 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:
    virtual void initializePass() {
      InitializeAliasAnalysis(this);
    }

    /// getAdjustedAnalysisPointer - 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.
    virtual void *getAdjustedAnalysisPointer(const void *PI) {
      if (PI == &AliasAnalysis::ID)
        return (AliasAnalysis*)this;
      return this;
    }

    virtual void getAnalysisUsage(AnalysisUsage &AU) const;
    virtual AliasResult alias(const Location &LocA, const Location &LocB);
    virtual bool pointsToConstantMemory(const Location &Loc, bool OrLocal);
    virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
    virtual ModRefBehavior getModRefBehavior(const Function *F);
    virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
                                       const Location &Loc);
    virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
                                       ImmutableCallSite CS2);
  };
}  // End of anonymous namespace

// 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();
}

void
ObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  AliasAnalysis::getAnalysisUsage(AU);
}

AliasAnalysis::AliasResult
ObjCARCAliasAnalysis::alias(const Location &LocA, const Location &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 = StripPointerCastsAndObjCCalls(LocA.Ptr);
  const Value *SB = StripPointerCastsAndObjCCalls(LocB.Ptr);
  AliasResult Result =
    AliasAnalysis::alias(Location(SA, LocA.Size, LocA.TBAATag),
                         Location(SB, LocB.Size, LocB.TBAATag));
  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);
  const Value *UB = GetUnderlyingObjCPtr(SB);
  if (UA != SA || UB != SB) {
    Result = AliasAnalysis::alias(Location(UA), Location(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 Location &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 = StripPointerCastsAndObjCCalls(Loc.Ptr);
  if (AliasAnalysis::pointsToConstantMemory(Location(S, Loc.Size, Loc.TBAATag),
                                            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);
  if (U != S)
    return AliasAnalysis::pointsToConstantMemory(Location(U), OrLocal);

  // If that failed, fail. We don't need to chain here, since that's covered
  // by the earlier precise query.
  return false;
}

AliasAnalysis::ModRefBehavior
ObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
  // We have nothing to do. Just chain to the next AliasAnalysis.
  return AliasAnalysis::getModRefBehavior(CS);
}

AliasAnalysis::ModRefBehavior
ObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
  if (!EnableARCOpts)
    return AliasAnalysis::getModRefBehavior(F);

  switch (GetFunctionClass(F)) {
  case IC_NoopCast:
    return DoesNotAccessMemory;
  default:
    break;
  }

  return AliasAnalysis::getModRefBehavior(F);
}

AliasAnalysis::ModRefResult
ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const Location &Loc) {
  if (!EnableARCOpts)
    return AliasAnalysis::getModRefInfo(CS, Loc);

  switch (GetBasicInstructionClass(CS.getInstruction())) {
  case IC_Retain:
  case IC_RetainRV:
  case IC_Autorelease:
  case IC_AutoreleaseRV:
  case IC_NoopCast:
  case IC_AutoreleasepoolPush:
  case IC_FusedRetainAutorelease:
  case IC_FusedRetainAutoreleaseRV:
    // These functions don't access any memory visible to the compiler.
    // Note that this doesn't include objc_retainBlock, becuase it updates
    // pointers when it copies block data.
    return NoModRef;
  default:
    break;
  }

  return AliasAnalysis::getModRefInfo(CS, Loc);
}

AliasAnalysis::ModRefResult
ObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
                                    ImmutableCallSite CS2) {
  // TODO: Theoretically we could check for dependencies between objc_* calls
  // and OnlyAccessesArgumentPointees calls or other well-behaved calls.
  return AliasAnalysis::getModRefInfo(CS1, CS2);
}

//===----------------------------------------------------------------------===//
// ARC expansion.
//===----------------------------------------------------------------------===//

#include "llvm/Support/InstIterator.h"
#include "llvm/Transforms/Scalar.h"

namespace {
  /// ObjCARCExpand - Early ARC transformations.
  class ObjCARCExpand : public FunctionPass {
    virtual void getAnalysisUsage(AnalysisUsage &AU) const;
    virtual bool doInitialization(Module &M);
    virtual bool runOnFunction(Function &F);

    /// Run - A flag indicating whether this optimization pass should run.
    bool Run;

  public:
    static char ID;
    ObjCARCExpand() : FunctionPass(ID) {
      initializeObjCARCExpandPass(*PassRegistry::getPassRegistry());
    }
  };
}

char ObjCARCExpand::ID = 0;
INITIALIZE_PASS(ObjCARCExpand,
                "objc-arc-expand", "ObjC ARC expansion", false, false)

Pass *llvm::createObjCARCExpandPass() {
  return new ObjCARCExpand();
}

void ObjCARCExpand::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesCFG();
}

bool ObjCARCExpand::doInitialization(Module &M) {
  Run = ModuleHasARC(M);
  return false;
}

bool ObjCARCExpand::runOnFunction(Function &F) {
  if (!EnableARCOpts)
    return false;

  // If nothing in the Module uses ARC, don't do anything.
  if (!Run)
    return false;

  bool Changed = false;

  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ++I) {
    Instruction *Inst = &*I;

    switch (GetBasicInstructionClass(Inst)) {
    case IC_Retain:
    case IC_RetainRV:
    case IC_Autorelease:
    case IC_AutoreleaseRV:
    case IC_FusedRetainAutorelease:
    case IC_FusedRetainAutoreleaseRV:
      // These calls return their argument verbatim, as a low-level
      // optimization. However, this makes high-level optimizations
      // harder. Undo any uses of this optimization that the front-end
      // emitted here. We'll redo them in a later pass.
      Changed = true;
      Inst->replaceAllUsesWith(cast<CallInst>(Inst)->getArgOperand(0));
      break;
    default:
      break;
    }
  }

  return Changed;
}

//===----------------------------------------------------------------------===//
// ARC optimization.
//===----------------------------------------------------------------------===//

// TODO: On code like this:
//
// objc_retain(%x)
// stuff_that_cannot_release()
// objc_autorelease(%x)
// stuff_that_cannot_release()
// objc_retain(%x)
// stuff_that_cannot_release()
// objc_autorelease(%x)
//
// The second retain and autorelease can be deleted.

// TODO: It should be possible to delete
// objc_autoreleasePoolPush and objc_autoreleasePoolPop
// pairs if nothing is actually autoreleased between them. Also, autorelease
// calls followed by objc_autoreleasePoolPop calls (perhaps in ObjC++ code
// after inlining) can be turned into plain release calls.

// TODO: Critical-edge splitting. If the optimial insertion point is
// a critical edge, the current algorithm has to fail, because it doesn't
// know how to split edges. It should be possible to make the optimizer
// think in terms of edges, rather than blocks, and then split critical
// edges on demand.

// TODO: OptimizeSequences could generalized to be Interprocedural.

// TODO: Recognize that a bunch of other objc runtime calls have
// non-escaping arguments and non-releasing arguments, and may be
// non-autoreleasing.

// TODO: Sink autorelease calls as far as possible. Unfortunately we
// usually can't sink them past other calls, which would be the main
// case where it would be useful.

// TODO: The pointer returned from objc_loadWeakRetained is retained.

// TODO: Delete release+retain pairs (rare).
#include "llvm/GlobalAlias.h"
#include "llvm/Constants.h"
#include "llvm/LLVMContext.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/CFG.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/Statistic.h"

STATISTIC(NumNoops,       "Number of no-op objc calls eliminated");
STATISTIC(NumPartialNoops, "Number of partially no-op objc calls eliminated");
STATISTIC(NumAutoreleases,"Number of autoreleases converted to releases");
STATISTIC(NumRets,        "Number of return value forwarding "
                          "retain+autoreleaes eliminated");
STATISTIC(NumRRs,         "Number of retain+release paths eliminated");
STATISTIC(NumPeeps,       "Number of calls peephole-optimized");

namespace {
  /// ProvenanceAnalysis - This is similar to BasicAliasAnalysis, and it
  /// uses many of the same techniques, except it uses special ObjC-specific
  /// reasoning about pointer relationships.
  class ProvenanceAnalysis {
    AliasAnalysis *AA;

    typedef std::pair<const Value *, const Value *> ValuePairTy;
    typedef DenseMap<ValuePairTy, bool> CachedResultsTy;
    CachedResultsTy CachedResults;

    bool relatedCheck(const Value *A, const Value *B);
    bool relatedSelect(const SelectInst *A, const Value *B);
    bool relatedPHI(const PHINode *A, const Value *B);

    // Do not implement.
    void operator=(const ProvenanceAnalysis &);
    ProvenanceAnalysis(const ProvenanceAnalysis &);

  public:
    ProvenanceAnalysis() {}

    void setAA(AliasAnalysis *aa) { AA = aa; }

    AliasAnalysis *getAA() const { return AA; }

    bool related(const Value *A, const Value *B);

    void clear() {
      CachedResults.clear();
    }
  };
}

bool ProvenanceAnalysis::relatedSelect(const SelectInst *A, const Value *B) {
  // If the values are Selects with the same condition, we can do a more precise
  // check: just check for relations between the values on corresponding arms.
  if (const SelectInst *SB = dyn_cast<SelectInst>(B))
    if (A->getCondition() == SB->getCondition()) {
      if (related(A->getTrueValue(), SB->getTrueValue()))
        return true;
      if (related(A->getFalseValue(), SB->getFalseValue()))
        return true;
      return false;
    }

  // Check both arms of the Select node individually.
  if (related(A->getTrueValue(), B))
    return true;
  if (related(A->getFalseValue(), B))
    return true;

  // The arms both checked out.
  return false;
}

bool ProvenanceAnalysis::relatedPHI(const PHINode *A, const Value *B) {
  // If the values are PHIs in the same block, we can do a more precise as well
  // as efficient check: just check for relations between the values on
  // corresponding edges.
  if (const PHINode *PNB = dyn_cast<PHINode>(B))
    if (PNB->getParent() == A->getParent()) {
      for (unsigned i = 0, e = A->getNumIncomingValues(); i != e; ++i)
        if (related(A->getIncomingValue(i),
                    PNB->getIncomingValueForBlock(A->getIncomingBlock(i))))
          return true;
      return false;
    }

  // Check each unique source of the PHI node against B.
  SmallPtrSet<const Value *, 4> UniqueSrc;
  for (unsigned i = 0, e = A->getNumIncomingValues(); i != e; ++i) {
    const Value *PV1 = A->getIncomingValue(i);
    if (UniqueSrc.insert(PV1) && related(PV1, B))
      return true;
  }

  // All of the arms checked out.
  return false;
}

/// isStoredObjCPointer - Test if the value of P, or any value covered by its
/// provenance, is ever stored within the function (not counting callees).
static bool isStoredObjCPointer(const Value *P) {
  SmallPtrSet<const Value *, 8> Visited;
  SmallVector<const Value *, 8> Worklist;
  Worklist.push_back(P);
  Visited.insert(P);
  do {
    P = Worklist.pop_back_val();
    for (Value::const_use_iterator UI = P->use_begin(), UE = P->use_end();