119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===- ObjCARC.cpp - ObjC ARC Optimization --------------------------------===//
219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//                     The LLVM Compiler Infrastructure
419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file is distributed under the University of Illinois Open Source
619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// License. See LICENSE.TXT for details.
719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file defines ObjC ARC optimizations. ARC stands for
1119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Automatic Reference Counting and is a system for managing reference counts
1219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// for objects in Objective C.
1319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// The optimizations performed include elimination of redundant, partially
1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// redundant, and inconsequential reference count operations, elimination of
1619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// redundant weak pointer operations, pattern-matching and replacement of
1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// low-level operations into higher-level operations, and numerous minor
1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// simplifications.
1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
2019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// This file also defines a simple ARC-aware AliasAnalysis.
2119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// WARNING: This file knows about certain library functions. It recognizes them
2319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// by name, and hardwires knowedge of their semantics.
2419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// WARNING: This file knows about how certain Objective-C library functions are
2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// used. Naive LLVM IR transformations which would otherwise be
2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// behavior-preserving may break these assumptions.
2819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
2919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
3019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
3119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define DEBUG_TYPE "objc-arc"
3219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Function.h"
3319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Intrinsics.h"
3419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/GlobalVariable.h"
3519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/DerivedTypes.h"
3619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Module.h"
3719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Analysis/ValueTracking.h"
3819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Transforms/Utils/Local.h"
3919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/CallSite.h"
4019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/CommandLine.h"
4119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/StringSwitch.h"
4219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/DenseMap.h"
4319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/STLExtras.h"
4419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanusing namespace llvm;
4519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// A handy option to enable/disable all optimizations in this file.
4719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic cl::opt<bool> EnableARCOpts("enable-objc-arc-opts", cl::init(true));
4819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
4919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
5019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Misc. Utilities
5119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
5219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
5319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
5419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// MapVector - An associative container with fast insertion-order
5519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// (deterministic) iteration over its elements. Plus the special
5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// blot operation.
5719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  template<class KeyT, class ValueT>
5819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class MapVector {
5919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// Map - Map keys to indices in Vector.
6019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    typedef DenseMap<KeyT, size_t> MapTy;
6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MapTy Map;
6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// Vector - Keys and values.
6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    typedef std::vector<std::pair<KeyT, ValueT> > VectorTy;
6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    VectorTy Vector;
6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  public:
6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    typedef typename VectorTy::iterator iterator;
6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    typedef typename VectorTy::const_iterator const_iterator;
7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    iterator begin() { return Vector.begin(); }
7119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    iterator end() { return Vector.end(); }
7219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const_iterator begin() const { return Vector.begin(); }
7319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const_iterator end() const { return Vector.end(); }
7419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
7519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#ifdef XDEBUG
7619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ~MapVector() {
7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(Vector.size() >= Map.size()); // May differ due to blotting.
7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (typename MapTy::const_iterator I = Map.begin(), E = Map.end();
7919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           I != E; ++I) {
8019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        assert(I->second < Vector.size());
8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        assert(Vector[I->second].first == I->first);
8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
8319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (typename VectorTy::const_iterator I = Vector.begin(),
8419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           E = Vector.end(); I != E; ++I)
8519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        assert(!I->first ||
8619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               (Map.count(I->first) &&
8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                Map[I->first] == size_t(I - Vector.begin())));
8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
8919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#endif
9019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
9119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ValueT &operator[](KeyT Arg) {
9219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      std::pair<typename MapTy::iterator, bool> Pair =
9319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Map.insert(std::make_pair(Arg, size_t(0)));
9419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Pair.second) {
9519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Pair.first->second = Vector.size();
9619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Vector.push_back(std::make_pair(Arg, ValueT()));
9719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return Vector.back().second;
9819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
9919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Vector[Pair.first->second].second;
10019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
10119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
10219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::pair<iterator, bool>
10319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    insert(const std::pair<KeyT, ValueT> &InsertPair) {
10419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      std::pair<typename MapTy::iterator, bool> Pair =
10519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Map.insert(std::make_pair(InsertPair.first, size_t(0)));
10619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Pair.second) {
10719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Pair.first->second = Vector.size();
10819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Vector.push_back(InsertPair);
10919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return std::make_pair(llvm::prior(Vector.end()), true);
11019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
11119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return std::make_pair(Vector.begin() + Pair.first->second, false);
11219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
11319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
11419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const_iterator find(KeyT Key) const {
11519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      typename MapTy::const_iterator It = Map.find(Key);
11619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (It == Map.end()) return Vector.end();
11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Vector.begin() + It->second;
11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
12019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// blot - This is similar to erase, but instead of removing the element
12119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// from the vector, it just zeros out the key in the vector. This leaves
12219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// iterators intact, but clients must be prepared for zeroed-out keys when
12319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// iterating.
12419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void blot(KeyT Key) {
12519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      typename MapTy::iterator It = Map.find(Key);
12619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (It == Map.end()) return;
12719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Vector[It->second].first = KeyT();
12819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Map.erase(It);
12919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
13019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void clear() {
13219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Map.clear();
13319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Vector.clear();
13419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
13519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
13619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
13719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
13819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
13919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// ARC Utilities.
14019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
14119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
14219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
14319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// InstructionClass - A simple classification for instructions.
14419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  enum InstructionClass {
14519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_Retain,              ///< objc_retain
14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_RetainRV,            ///< objc_retainAutoreleasedReturnValue
14719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_RetainBlock,         ///< objc_retainBlock
14819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_Release,             ///< objc_release
14919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_Autorelease,         ///< objc_autorelease
15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_AutoreleaseRV,       ///< objc_autoreleaseReturnValue
15119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_AutoreleasepoolPush, ///< objc_autoreleasePoolPush
15219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_AutoreleasepoolPop,  ///< objc_autoreleasePoolPop
15319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_NoopCast,            ///< objc_retainedObject, etc.
15419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_FusedRetainAutorelease, ///< objc_retainAutorelease
15519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_FusedRetainAutoreleaseRV, ///< objc_retainAutoreleaseReturnValue
15619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_LoadWeakRetained,    ///< objc_loadWeakRetained (primitive)
15719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_StoreWeak,           ///< objc_storeWeak (primitive)
15819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_InitWeak,            ///< objc_initWeak (derived)
15919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_LoadWeak,            ///< objc_loadWeak (derived)
16019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_MoveWeak,            ///< objc_moveWeak (derived)
16119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_CopyWeak,            ///< objc_copyWeak (derived)
16219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_DestroyWeak,         ///< objc_destroyWeak (derived)
16319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_CallOrUser,          ///< could call objc_release and/or "use" pointers
16419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_Call,                ///< could call objc_release
16519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_User,                ///< could "use" a pointer
16619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    IC_None                 ///< anything else
16719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
16819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
16919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
17019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// IsPotentialUse - Test whether the given value is possible a
17119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// reference-counted pointer.
17219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool IsPotentialUse(const Value *Op) {
17319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Pointers to static or stack storage are not reference-counted pointers.
17419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (isa<Constant>(Op) || isa<AllocaInst>(Op))
17519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
17619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Special arguments are not reference-counted.
17719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (const Argument *Arg = dyn_cast<Argument>(Op))
17819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Arg->hasByValAttr() ||
17919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Arg->hasNestAttr() ||
18019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Arg->hasStructRetAttr())
18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
18219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Only consider values with pointer types, and not function pointers.
18319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  PointerType *Ty = dyn_cast<PointerType>(Op->getType());
18419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Ty || isa<FunctionType>(Ty->getElementType()))
18519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
18619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Conservatively assume anything else is a potential use.
18719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
18819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
18919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
19019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// GetCallSiteClass - Helper for GetInstructionClass. Determines what kind
19119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// of construct CS is.
19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic InstructionClass GetCallSiteClass(ImmutableCallSite CS) {
19319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       I != E; ++I)
19519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IsPotentialUse(*I))
19619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return CS.onlyReadsMemory() ? IC_User : IC_CallOrUser;
19719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
19819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return CS.onlyReadsMemory() ? IC_None : IC_Call;
19919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
20019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// GetFunctionClass - Determine if F is one of the special known Functions.
20219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// If it isn't, return IC_CallOrUser.
20319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic InstructionClass GetFunctionClass(const Function *F) {
20419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
20519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
20619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // No arguments.
20719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (AI == AE)
20819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return StringSwitch<InstructionClass>(F->getName())
20919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      .Case("objc_autoreleasePoolPush",  IC_AutoreleasepoolPush)
21019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      .Default(IC_CallOrUser);
21119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
21219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // One argument.
21319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const Argument *A0 = AI++;
21419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (AI == AE)
21519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Argument is a pointer.
21619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (PointerType *PTy = dyn_cast<PointerType>(A0->getType())) {
21719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Type *ETy = PTy->getElementType();
21819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Argument is i8*.
21919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (ETy->isIntegerTy(8))
22019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return StringSwitch<InstructionClass>(F->getName())
22119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_retain",                IC_Retain)
22219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_retainAutoreleasedReturnValue", IC_RetainRV)
22319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_retainBlock",           IC_RetainBlock)
22419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_release",               IC_Release)
22519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_autorelease",           IC_Autorelease)
22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_autoreleaseReturnValue", IC_AutoreleaseRV)
22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_autoreleasePoolPop",    IC_AutoreleasepoolPop)
22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_retainedObject",        IC_NoopCast)
22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_unretainedObject",      IC_NoopCast)
23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_unretainedPointer",     IC_NoopCast)
23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_retain_autorelease",    IC_FusedRetainAutorelease)
23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_retainAutorelease",     IC_FusedRetainAutorelease)
23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Case("objc_retainAutoreleaseReturnValue",IC_FusedRetainAutoreleaseRV)
23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          .Default(IC_CallOrUser);
23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
23619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Argument is i8**
23719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (PointerType *Pte = dyn_cast<PointerType>(ETy))
23819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Pte->getElementType()->isIntegerTy(8))
23919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return StringSwitch<InstructionClass>(F->getName())
24019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            .Case("objc_loadWeakRetained",      IC_LoadWeakRetained)
24119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            .Case("objc_loadWeak",              IC_LoadWeak)
24219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            .Case("objc_destroyWeak",           IC_DestroyWeak)
24319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            .Default(IC_CallOrUser);
24419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
24519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
24619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Two arguments, first is i8**.
24719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const Argument *A1 = AI++;
24819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (AI == AE)
24919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (PointerType *PTy = dyn_cast<PointerType>(A0->getType()))
25019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (PointerType *Pte = dyn_cast<PointerType>(PTy->getElementType()))
25119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Pte->getElementType()->isIntegerTy(8))
25219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (PointerType *PTy1 = dyn_cast<PointerType>(A1->getType())) {
25319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Type *ETy1 = PTy1->getElementType();
25419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            // Second argument is i8*
25519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (ETy1->isIntegerTy(8))
25619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              return StringSwitch<InstructionClass>(F->getName())
25719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     .Case("objc_storeWeak",             IC_StoreWeak)
25819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     .Case("objc_initWeak",              IC_InitWeak)
25919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     .Default(IC_CallOrUser);
26019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            // Second argument is i8**.
26119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1))
26219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              if (Pte1->getElementType()->isIntegerTy(8))
26319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                return StringSwitch<InstructionClass>(F->getName())
26419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       .Case("objc_moveWeak",              IC_MoveWeak)
26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       .Case("objc_copyWeak",              IC_CopyWeak)
26619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       .Default(IC_CallOrUser);
26719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          }
26819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
26919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Anything else.
27019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return IC_CallOrUser;
27119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
27219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
27319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// GetInstructionClass - Determine what kind of construct V is.
27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic InstructionClass GetInstructionClass(const Value *V) {
27519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (const Instruction *I = dyn_cast<Instruction>(V)) {
27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Any instruction other than bitcast and gep with a pointer operand have a
27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer
27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // to a subsequent use, rather than using it themselves, in this sense.
27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // As a short cut, several other opcodes are known to have no pointer
28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // operands of interest. And ret is never followed by a release, so it's
28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // not interesting to examine.
28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (I->getOpcode()) {
28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::Call: {
28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const CallInst *CI = cast<CallInst>(I);
28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Check for calls to special functions.
28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (const Function *F = CI->getCalledFunction()) {
28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        InstructionClass Class = GetFunctionClass(F);
28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Class != IC_CallOrUser)
28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return Class;
29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // None of the intrinsic functions do objc_release. For intrinsics, the
29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // only question is whether or not they may be users.
29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        switch (F->getIntrinsicID()) {
29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case 0: break;
29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case Intrinsic::bswap: case Intrinsic::ctpop:
29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case Intrinsic::ctlz: case Intrinsic::cttz:
29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case Intrinsic::returnaddress: case Intrinsic::frameaddress:
29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case Intrinsic::stacksave: case Intrinsic::stackrestore:
29919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case Intrinsic::vastart: case Intrinsic::vacopy: case Intrinsic::vaend:
30019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Don't let dbg info affect our results.
30119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case Intrinsic::dbg_declare: case Intrinsic::dbg_value:
30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // Short cut: Some intrinsics obviously don't use ObjC pointers.
30319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return IC_None;
30419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        default:
30519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          for (Function::const_arg_iterator AI = F->arg_begin(),
30619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               AE = F->arg_end(); AI != AE; ++AI)
30719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (IsPotentialUse(AI))
30819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              return IC_User;
30919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return IC_None;
31019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
31119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
31219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return GetCallSiteClass(CI);
31319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
31419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::Invoke:
31519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return GetCallSiteClass(cast<InvokeInst>(I));
31619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::BitCast:
31719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::GetElementPtr:
31819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::Select: case Instruction::PHI:
31919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::Ret: case Instruction::Br:
32019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::Switch: case Instruction::IndirectBr:
32119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::Alloca: case Instruction::VAArg:
32219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::Add: case Instruction::FAdd:
32319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::Sub: case Instruction::FSub:
32419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::Mul: case Instruction::FMul:
32519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::SDiv: case Instruction::UDiv: case Instruction::FDiv:
32619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::SRem: case Instruction::URem: case Instruction::FRem:
32719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::Shl: case Instruction::LShr: case Instruction::AShr:
32819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::And: case Instruction::Or: case Instruction::Xor:
32919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::SExt: case Instruction::ZExt: case Instruction::Trunc:
33019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::IntToPtr: case Instruction::FCmp:
33119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::FPTrunc: case Instruction::FPExt:
33219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::FPToUI: case Instruction::FPToSI:
33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::UIToFP: case Instruction::SIToFP:
33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::InsertElement: case Instruction::ExtractElement:
33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::ShuffleVector:
33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::ExtractValue:
33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case Instruction::ICmp:
33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Comparing a pointer with null, or any other constant, isn't an
34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // interesting use, because we don't care what the pointer points to, or
34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // about the values of any other dynamic reference-counted pointers.
34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (IsPotentialUse(I->getOperand(1)))
34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return IC_User;
34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // For anything else, check all the operands.
34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Note that this includes both operands of a Store: while the first
34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // operand isn't actually being dereferenced, it is being stored to
34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // memory where we can no longer track who might read it and dereference
35019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // it, so we have to consider it potentially used.
35119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end();
35219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           OI != OE; ++OI)
35319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (IsPotentialUse(*OI))
35419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return IC_User;
35519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
35619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
35719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
35819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Otherwise, it's totally inert for ARC purposes.
35919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return IC_None;
36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// GetBasicInstructionClass - Determine what kind of construct V is. This is
36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// similar to GetInstructionClass except that it only detects objc runtine
36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// calls. This allows it to be faster.
36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic InstructionClass GetBasicInstructionClass(const Value *V) {
36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (const CallInst *CI = dyn_cast<CallInst>(V)) {
36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (const Function *F = CI->getCalledFunction())
36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return GetFunctionClass(F);
36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Otherwise, be conservative.
37019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return IC_CallOrUser;
37119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
37219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Otherwise, be conservative.
37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return IC_User;
37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
37719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// IsRetain - Test if the the given class is objc_retain or
37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// equivalent.
37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool IsRetain(InstructionClass Class) {
38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Class == IC_Retain ||
38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_RetainRV;
38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// IsAutorelease - Test if the the given class is objc_autorelease or
38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// equivalent.
38619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool IsAutorelease(InstructionClass Class) {
38719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Class == IC_Autorelease ||
38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_AutoreleaseRV;
38919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
39019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// IsForwarding - Test if the given class represents instructions which return
39219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// their argument verbatim.
39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool IsForwarding(InstructionClass Class) {
39419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // objc_retainBlock technically doesn't always return its argument
39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // verbatim, but it doesn't matter for our purposes here.
39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Class == IC_Retain ||
39719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_RetainRV ||
39819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_Autorelease ||
39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_AutoreleaseRV ||
40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_RetainBlock ||
40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_NoopCast;
40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// IsNoopOnNull - Test if the given class represents instructions which do
40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// nothing if passed a null pointer.
40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool IsNoopOnNull(InstructionClass Class) {
40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Class == IC_Retain ||
40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_RetainRV ||
40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_Release ||
41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_Autorelease ||
41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_AutoreleaseRV ||
41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_RetainBlock;
41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// IsAlwaysTail - Test if the given class represents instructions which are
41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// always safe to mark with the "tail" keyword.
41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool IsAlwaysTail(InstructionClass Class) {
41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // IC_RetainBlock may be given a stack argument.
41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Class == IC_Retain ||
42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_RetainRV ||
42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_Autorelease ||
42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_AutoreleaseRV;
42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// IsNoThrow - Test if the given class represents instructions which are always
42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// safe to mark with the nounwind attribute..
42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool IsNoThrow(InstructionClass Class) {
42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // objc_retainBlock is not nounwind because it calls user copy constructors
42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // which could theoretically throw.
43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Class == IC_Retain ||
43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_RetainRV ||
43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_Release ||
43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_Autorelease ||
43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_AutoreleaseRV ||
43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_AutoreleasepoolPush ||
43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Class == IC_AutoreleasepoolPop;
43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// EraseInstruction - Erase the given instruction. ObjC calls return their
44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// argument verbatim, so if it's such a call and the return value has users,
44119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// replace them with the argument value.
44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void EraseInstruction(Instruction *CI) {
44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Value *OldArg = cast<CallInst>(CI)->getArgOperand(0);
44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool Unused = CI->use_empty();
44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Unused) {
44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Replace the return value with the argument.
44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    assert(IsForwarding(GetBasicInstructionClass(CI)) &&
45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           "Can't delete non-forwarding instruction with users!");
45119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CI->replaceAllUsesWith(OldArg);
45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CI->eraseFromParent();
45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Unused)
45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RecursivelyDeleteTriviallyDeadInstructions(OldArg);
45819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
45919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
46019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// GetUnderlyingObjCPtr - This is a wrapper around getUnderlyingObject which
46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// also knows how to look through objc_retain and objc_autorelease calls, which
46219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// we know to return their argument verbatim.
46319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic const Value *GetUnderlyingObjCPtr(const Value *V) {
46419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (;;) {
46519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    V = GetUnderlyingObject(V);
46619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!IsForwarding(GetBasicInstructionClass(V)))
46719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
46819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    V = cast<CallInst>(V)->getArgOperand(0);
46919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
47019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
47119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return V;
47219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// StripPointerCastsAndObjCCalls - This is a wrapper around
47519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// Value::stripPointerCasts which also knows how to look through objc_retain
47619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// and objc_autorelease calls, which we know to return their argument verbatim.
47719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic const Value *StripPointerCastsAndObjCCalls(const Value *V) {
47819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (;;) {
47919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    V = V->stripPointerCasts();
48019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!IsForwarding(GetBasicInstructionClass(V)))
48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
48219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    V = cast<CallInst>(V)->getArgOperand(0);
48319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
48419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return V;
48519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
48619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// StripPointerCastsAndObjCCalls - This is a wrapper around
48819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// Value::stripPointerCasts which also knows how to look through objc_retain
48919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// and objc_autorelease calls, which we know to return their argument verbatim.
49019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic Value *StripPointerCastsAndObjCCalls(Value *V) {
49119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (;;) {
49219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    V = V->stripPointerCasts();
49319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!IsForwarding(GetBasicInstructionClass(V)))
49419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
49519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    V = cast<CallInst>(V)->getArgOperand(0);
49619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
49719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return V;
49819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
49919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
50019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// GetObjCArg - Assuming the given instruction is one of the special calls such
50119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// as objc_retain or objc_release, return the argument value, stripped of no-op
50219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// casts and forwarding calls.
50319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic Value *GetObjCArg(Value *Inst) {
50419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return StripPointerCastsAndObjCCalls(cast<CallInst>(Inst)->getArgOperand(0));
50519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
50619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
50719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// IsObjCIdentifiedObject - This is similar to AliasAnalysis'
50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// isObjCIdentifiedObject, except that it uses special knowledge of
50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ObjC conventions...
51019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool IsObjCIdentifiedObject(const Value *V) {
51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Assume that call results and arguments have their own "provenance".
51219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Constants (including GlobalVariables) and Allocas are never
51319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // reference-counted.
51419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (isa<CallInst>(V) || isa<InvokeInst>(V) ||
51519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      isa<Argument>(V) || isa<Constant>(V) ||
51619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      isa<AllocaInst>(V))
51719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
51819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (const LoadInst *LI = dyn_cast<LoadInst>(V)) {
52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const Value *Pointer =
52119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      StripPointerCastsAndObjCCalls(LI->getPointerOperand());
52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Pointer)) {
52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // A constant pointer can't be pointing to an object on the heap. It may
52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // be reference-counted, but it won't be deleted.
52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (GV->isConstant())
52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return true;
52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      StringRef Name = GV->getName();
52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // These special variables are known to hold values which are not
52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // reference-counted pointers.
53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Name.startswith("\01L_OBJC_SELECTOR_REFERENCES_") ||
53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Name.startswith("\01L_OBJC_CLASSLIST_REFERENCES_") ||
53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Name.startswith("\01L_OBJC_CLASSLIST_SUP_REFS_$_") ||
53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Name.startswith("\01L_OBJC_METH_VAR_NAME_") ||
53419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Name.startswith("\01l_objc_msgSend_fixup_"))
53519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return true;
53619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
53719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
53819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
53919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
54019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
54119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// FindSingleUseIdentifiedObject - This is similar to
54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// StripPointerCastsAndObjCCalls but it stops as soon as it finds a value
54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// with multiple uses.
54519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic const Value *FindSingleUseIdentifiedObject(const Value *Arg) {
54619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Arg->hasOneUse()) {
54719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (const BitCastInst *BC = dyn_cast<BitCastInst>(Arg))
54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return FindSingleUseIdentifiedObject(BC->getOperand(0));
54919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Arg))
55019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (GEP->hasAllZeroIndices())
55119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return FindSingleUseIdentifiedObject(GEP->getPointerOperand());
55219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IsForwarding(GetBasicInstructionClass(Arg)))
55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return FindSingleUseIdentifiedObject(
55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               cast<CallInst>(Arg)->getArgOperand(0));
55519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!IsObjCIdentifiedObject(Arg))
55619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return 0;
55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Arg;
55819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If we found an identifiable object but it has multiple uses, but they
56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // are trivial uses, we can still consider this to be a single-use
56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // value.
56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (IsObjCIdentifiedObject(Arg)) {
56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (Value::const_use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         UI != UE; ++UI) {
56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const User *U = *UI;
56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!U->use_empty() || StripPointerCastsAndObjCCalls(U) != Arg)
56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         return 0;
56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Arg;
57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return 0;
57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
57719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ModuleHasARC - Test if the given module looks interesting to run ARC
57819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// optimization on.
57919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool ModuleHasARC(const Module &M) {
58019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return
58119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_retain") ||
58219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_release") ||
58319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_autorelease") ||
58419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_retainAutoreleasedReturnValue") ||
58519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_retainBlock") ||
58619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_autoreleaseReturnValue") ||
58719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_autoreleasePoolPush") ||
58819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_loadWeakRetained") ||
58919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_loadWeak") ||
59019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_destroyWeak") ||
59119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_storeWeak") ||
59219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_initWeak") ||
59319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_moveWeak") ||
59419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_copyWeak") ||
59519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_retainedObject") ||
59619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_unretainedObject") ||
59719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getNamedValue("objc_unretainedPointer");
59819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
60119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// ARC AliasAnalysis.
60219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
60319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Pass.h"
60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Analysis/AliasAnalysis.h"
60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Analysis/Passes.h"
60719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
60819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// ObjCARCAliasAnalysis - This is a simple alias analysis
61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// implementation that uses knowledge of ARC constructs to answer queries.
61119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ///
61219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// TODO: This class could be generalized to know about other ObjC-specific
61319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// tricks. Such as knowing that ivars in the non-fragile ABI are non-aliasing
61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// even though their offsets are dynamic.
61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class ObjCARCAliasAnalysis : public ImmutablePass,
61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               public AliasAnalysis {
61719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  public:
61819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static char ID; // Class identification, replacement for typeinfo
61919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ObjCARCAliasAnalysis() : ImmutablePass(ID) {
62019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      initializeObjCARCAliasAnalysisPass(*PassRegistry::getPassRegistry());
62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
62319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  private:
62419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual void initializePass() {
62519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InitializeAliasAnalysis(this);
62619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
62719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
62819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// getAdjustedAnalysisPointer - This method is used when a pass implements
62919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// an analysis interface through multiple inheritance.  If needed, it
63019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// should override this to adjust the this pointer as needed for the
63119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// specified pass info.
63219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual void *getAdjustedAnalysisPointer(const void *PI) {
63319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (PI == &AliasAnalysis::ID)
63419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return (AliasAnalysis*)this;
63519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return this;
63619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
63719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
63819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual void getAnalysisUsage(AnalysisUsage &AU) const;
63919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual AliasResult alias(const Location &LocA, const Location &LocB);
64019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual bool pointsToConstantMemory(const Location &Loc, bool OrLocal);
64119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
64219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual ModRefBehavior getModRefBehavior(const Function *F);
64319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
64419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       const Location &Loc);
64519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
64619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       ImmutableCallSite CS2);
64719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
64819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}  // End of anonymous namespace
64919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
65019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Register this pass...
65119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanchar ObjCARCAliasAnalysis::ID = 0;
65219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_AG_PASS(ObjCARCAliasAnalysis, AliasAnalysis, "objc-arc-aa",
65319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   "ObjC-ARC-Based Alias Analysis", false, true, false)
65419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
65519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanImmutablePass *llvm::createObjCARCAliasAnalysisPass() {
65619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return new ObjCARCAliasAnalysis();
65719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
65819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
65919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid
66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCAliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
66119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AU.setPreservesAll();
66219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AliasAnalysis::getAnalysisUsage(AU);
66319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
66419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
66519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanAliasAnalysis::AliasResult
66619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCAliasAnalysis::alias(const Location &LocA, const Location &LocB) {
66719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!EnableARCOpts)
66819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return AliasAnalysis::alias(LocA, LocB);
66919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
67019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // First, strip off no-ops, including ObjC-specific no-ops, and try making a
67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // precise alias query.
67219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const Value *SA = StripPointerCastsAndObjCCalls(LocA.Ptr);
67319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const Value *SB = StripPointerCastsAndObjCCalls(LocB.Ptr);
67419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AliasResult Result =
67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AliasAnalysis::alias(Location(SA, LocA.Size, LocA.TBAATag),
67619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         Location(SB, LocB.Size, LocB.TBAATag));
67719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Result != MayAlias)
67819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Result;
67919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
68019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If that failed, climb to the underlying object, including climbing through
68119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // ObjC-specific no-ops, and try making an imprecise alias query.
68219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const Value *UA = GetUnderlyingObjCPtr(SA);
68319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const Value *UB = GetUnderlyingObjCPtr(SB);
68419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (UA != SA || UB != SB) {
68519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Result = AliasAnalysis::alias(Location(UA), Location(UB));
68619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // We can't use MustAlias or PartialAlias results here because
68719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // GetUnderlyingObjCPtr may return an offsetted pointer value.
68819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Result == NoAlias)
68919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return NoAlias;
69019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
69119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
69219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If that failed, fail. We don't need to chain here, since that's covered
69319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // by the earlier precise query.
69419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return MayAlias;
69519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
69619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
69719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool
69819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCAliasAnalysis::pointsToConstantMemory(const Location &Loc,
69919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                             bool OrLocal) {
70019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!EnableARCOpts)
70119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
70219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
70319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // First, strip off no-ops, including ObjC-specific no-ops, and try making
70419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // a precise alias query.
70519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const Value *S = StripPointerCastsAndObjCCalls(Loc.Ptr);
70619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (AliasAnalysis::pointsToConstantMemory(Location(S, Loc.Size, Loc.TBAATag),
70719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                            OrLocal))
70819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
70919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
71019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If that failed, climb to the underlying object, including climbing through
71119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // ObjC-specific no-ops, and try making an imprecise alias query.
71219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const Value *U = GetUnderlyingObjCPtr(S);
71319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (U != S)
71419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return AliasAnalysis::pointsToConstantMemory(Location(U), OrLocal);
71519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
71619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If that failed, fail. We don't need to chain here, since that's covered
71719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // by the earlier precise query.
71819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
71919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
72019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
72119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanAliasAnalysis::ModRefBehavior
72219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCAliasAnalysis::getModRefBehavior(ImmutableCallSite CS) {
72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // We have nothing to do. Just chain to the next AliasAnalysis.
72419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return AliasAnalysis::getModRefBehavior(CS);
72519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
72619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
72719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanAliasAnalysis::ModRefBehavior
72819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCAliasAnalysis::getModRefBehavior(const Function *F) {
72919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!EnableARCOpts)
73019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return AliasAnalysis::getModRefBehavior(F);
73119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
73219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (GetFunctionClass(F)) {
73319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_NoopCast:
73419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return DoesNotAccessMemory;
73519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
73619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
73719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
73819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
73919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return AliasAnalysis::getModRefBehavior(F);
74019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
74119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
74219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanAliasAnalysis::ModRefResult
74319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS, const Location &Loc) {
74419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!EnableARCOpts)
74519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return AliasAnalysis::getModRefInfo(CS, Loc);
74619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
74719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (GetBasicInstructionClass(CS.getInstruction())) {
74819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_Retain:
74919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_RetainRV:
75019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_Autorelease:
75119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_AutoreleaseRV:
75219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_NoopCast:
75319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_AutoreleasepoolPush:
75419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_FusedRetainAutorelease:
75519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_FusedRetainAutoreleaseRV:
75619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // These functions don't access any memory visible to the compiler.
75719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Note that this doesn't include objc_retainBlock, becuase it updates
75819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // pointers when it copies block data.
75919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return NoModRef;
76019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
76119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
76219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
76319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
76419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return AliasAnalysis::getModRefInfo(CS, Loc);
76519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
76619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
76719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanAliasAnalysis::ModRefResult
76819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCAliasAnalysis::getModRefInfo(ImmutableCallSite CS1,
76919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                    ImmutableCallSite CS2) {
77019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // TODO: Theoretically we could check for dependencies between objc_* calls
77119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // and OnlyAccessesArgumentPointees calls or other well-behaved calls.
77219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return AliasAnalysis::getModRefInfo(CS1, CS2);
77319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
77519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
77619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// ARC expansion.
77719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
77819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
77919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/InstIterator.h"
78019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Transforms/Scalar.h"
78119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
78219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
78319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// ObjCARCExpand - Early ARC transformations.
78419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class ObjCARCExpand : public FunctionPass {
78519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual void getAnalysisUsage(AnalysisUsage &AU) const;
78619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual bool doInitialization(Module &M);
78719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual bool runOnFunction(Function &F);
78819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
78919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// Run - A flag indicating whether this optimization pass should run.
79019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool Run;
79119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
79219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  public:
79319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static char ID;
79419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ObjCARCExpand() : FunctionPass(ID) {
79519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      initializeObjCARCExpandPass(*PassRegistry::getPassRegistry());
79619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
79719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
79819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
79919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanchar ObjCARCExpand::ID = 0;
80119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS(ObjCARCExpand,
80219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                "objc-arc-expand", "ObjC ARC expansion", false, false)
80319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanPass *llvm::createObjCARCExpandPass() {
80519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return new ObjCARCExpand();
80619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
80719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
80819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ObjCARCExpand::getAnalysisUsage(AnalysisUsage &AU) const {
80919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AU.setPreservesCFG();
81019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
81119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
81219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ObjCARCExpand::doInitialization(Module &M) {
81319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Run = ModuleHasARC(M);
81419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
81519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
81619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
81719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ObjCARCExpand::runOnFunction(Function &F) {
81819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!EnableARCOpts)
81919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
82019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
82119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If nothing in the Module uses ARC, don't do anything.
82219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Run)
82319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
82419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
82519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool Changed = false;
82619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
82719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ++I) {
82819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *Inst = &*I;
82919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
83019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (GetBasicInstructionClass(Inst)) {
83119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_Retain:
83219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_RetainRV:
83319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_Autorelease:
83419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_AutoreleaseRV:
83519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_FusedRetainAutorelease:
83619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_FusedRetainAutoreleaseRV:
83719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // These calls return their argument verbatim, as a low-level
83819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // optimization. However, this makes high-level optimizations
83919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // harder. Undo any uses of this optimization that the front-end
84019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // emitted here. We'll redo them in a later pass.
84119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Changed = true;
84219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Inst->replaceAllUsesWith(cast<CallInst>(Inst)->getArgOperand(0));
84319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
84419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
84519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
84619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
84719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
84819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
84919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Changed;
85019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
85119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
85219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
85319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// ARC optimization.
85419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
85519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
85619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// TODO: On code like this:
85719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
85819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// objc_retain(%x)
85919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// stuff_that_cannot_release()
86019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// objc_autorelease(%x)
86119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// stuff_that_cannot_release()
86219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// objc_retain(%x)
86319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// stuff_that_cannot_release()
86419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// objc_autorelease(%x)
86519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//
86619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// The second retain and autorelease can be deleted.
86719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
86819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// TODO: It should be possible to delete
86919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// objc_autoreleasePoolPush and objc_autoreleasePoolPop
87019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// pairs if nothing is actually autoreleased between them. Also, autorelease
87119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// calls followed by objc_autoreleasePoolPop calls (perhaps in ObjC++ code
87219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// after inlining) can be turned into plain release calls.
87319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
87419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// TODO: Critical-edge splitting. If the optimial insertion point is
87519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// a critical edge, the current algorithm has to fail, because it doesn't
87619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// know how to split edges. It should be possible to make the optimizer
87719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// think in terms of edges, rather than blocks, and then split critical
87819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// edges on demand.
87919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
88019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// TODO: OptimizeSequences could generalized to be Interprocedural.
88119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
88219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// TODO: Recognize that a bunch of other objc runtime calls have
88319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// non-escaping arguments and non-releasing arguments, and may be
88419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// non-autoreleasing.
88519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
88619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// TODO: Sink autorelease calls as far as possible. Unfortunately we
88719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// usually can't sink them past other calls, which would be the main
88819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// case where it would be useful.
88919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
89019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// TODO: The pointer returned from objc_loadWeakRetained is retained.
89119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
89219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// TODO: Delete release+retain pairs (rare).
89319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
89419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/GlobalAlias.h"
89519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Constants.h"
89619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/LLVMContext.h"
89719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/ErrorHandling.h"
89819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/CFG.h"
89919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/PostOrderIterator.h"
90019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/ADT/Statistic.h"
90119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
90219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumNoops,       "Number of no-op objc calls eliminated");
90319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumPartialNoops, "Number of partially no-op objc calls eliminated");
90419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumAutoreleases,"Number of autoreleases converted to releases");
90519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumRets,        "Number of return value forwarding "
90619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                          "retain+autoreleaes eliminated");
90719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumRRs,         "Number of retain+release paths eliminated");
90819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumPeeps,       "Number of calls peephole-optimized");
90919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
91019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
91119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// ProvenanceAnalysis - This is similar to BasicAliasAnalysis, and it
91219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// uses many of the same techniques, except it uses special ObjC-specific
91319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// reasoning about pointer relationships.
91419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class ProvenanceAnalysis {
91519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AliasAnalysis *AA;
91619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
91719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    typedef std::pair<const Value *, const Value *> ValuePairTy;
91819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    typedef DenseMap<ValuePairTy, bool> CachedResultsTy;
91919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CachedResultsTy CachedResults;
92019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
92119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool relatedCheck(const Value *A, const Value *B);
92219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool relatedSelect(const SelectInst *A, const Value *B);
92319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool relatedPHI(const PHINode *A, const Value *B);
92419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
92519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Do not implement.
92619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void operator=(const ProvenanceAnalysis &);
92719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ProvenanceAnalysis(const ProvenanceAnalysis &);
92819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
92919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  public:
93019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ProvenanceAnalysis() {}
93119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
93219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void setAA(AliasAnalysis *aa) { AA = aa; }
93319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
93419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AliasAnalysis *getAA() const { return AA; }
93519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
93619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool related(const Value *A, const Value *B);
93719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
93819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void clear() {
93919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      CachedResults.clear();
94019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
94119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
94219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
94319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
94419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ProvenanceAnalysis::relatedSelect(const SelectInst *A, const Value *B) {
94519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If the values are Selects with the same condition, we can do a more precise
94619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // check: just check for relations between the values on corresponding arms.
94719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (const SelectInst *SB = dyn_cast<SelectInst>(B))
94819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (A->getCondition() == SB->getCondition()) {
94919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (related(A->getTrueValue(), SB->getTrueValue()))
95019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return true;
95119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (related(A->getFalseValue(), SB->getFalseValue()))
95219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return true;
95319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
95419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
95519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
95619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Check both arms of the Select node individually.
95719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (related(A->getTrueValue(), B))
95819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
95919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (related(A->getFalseValue(), B))
96019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
96119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
96219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // The arms both checked out.
96319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
96419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
96519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
96619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ProvenanceAnalysis::relatedPHI(const PHINode *A, const Value *B) {
96719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If the values are PHIs in the same block, we can do a more precise as well
96819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // as efficient check: just check for relations between the values on
96919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // corresponding edges.
97019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (const PHINode *PNB = dyn_cast<PHINode>(B))
97119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (PNB->getParent() == A->getParent()) {
97219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (unsigned i = 0, e = A->getNumIncomingValues(); i != e; ++i)
97319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (related(A->getIncomingValue(i),
97419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                    PNB->getIncomingValueForBlock(A->getIncomingBlock(i))))
97519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return true;
97619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
97719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
97819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
97919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Check each unique source of the PHI node against B.
98019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallPtrSet<const Value *, 4> UniqueSrc;
98119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (unsigned i = 0, e = A->getNumIncomingValues(); i != e; ++i) {
98219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const Value *PV1 = A->getIncomingValue(i);
98319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (UniqueSrc.insert(PV1) && related(PV1, B))
98419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
98519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
98619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
98719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // All of the arms checked out.
98819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
98919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
99019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
99119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// isStoredObjCPointer - Test if the value of P, or any value covered by its
99219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// provenance, is ever stored within the function (not counting callees).
99319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool isStoredObjCPointer(const Value *P) {
99419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallPtrSet<const Value *, 8> Visited;
99519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<const Value *, 8> Worklist;
99619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Worklist.push_back(P);
99719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Visited.insert(P);
99819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  do {
99919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    P = Worklist.pop_back_val();
100019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (Value::const_use_iterator UI = P->use_begin(), UE = P->use_end();
100119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         UI != UE; ++UI) {
100219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const User *Ur = *UI;
100319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (isa<StoreInst>(Ur)) {
100419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (UI.getOperandNo() == 0)
100519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // The pointer is stored.
100619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          return true;
100719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // The pointed is stored through.
100819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
100919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
101019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (isa<CallInst>(Ur))
101119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // The pointer is passed as an argument, ignore this.
101219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
101319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (isa<PtrToIntInst>(P))
101419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Assume the worst.
101519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return true;
101619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Visited.insert(Ur))
101719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Worklist.push_back(Ur);
101819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
101919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } while (!Worklist.empty());
102019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
102119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Everything checked out.
102219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
102319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
102419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
102519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ProvenanceAnalysis::relatedCheck(const Value *A, const Value *B) {
102619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Skip past provenance pass-throughs.
102719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  A = GetUnderlyingObjCPtr(A);
102819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  B = GetUnderlyingObjCPtr(B);
102919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
103019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Quick check.
103119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (A == B)
103219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
103319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
103419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Ask regular AliasAnalysis, for a first approximation.
103519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (AA->alias(A, B)) {
103619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AliasAnalysis::NoAlias:
103719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
103819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AliasAnalysis::MustAlias:
103919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AliasAnalysis::PartialAlias:
104019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
104119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case AliasAnalysis::MayAlias:
104219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
104319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
104419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
104519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool AIsIdentified = IsObjCIdentifiedObject(A);
104619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool BIsIdentified = IsObjCIdentifiedObject(B);
104719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
104819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // An ObjC-Identified object can't alias a load if it is never locally stored.
104919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (AIsIdentified) {
105019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (BIsIdentified) {
105119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If both pointers have provenance, they can be directly compared.
105219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (A != B)
105319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return false;
105419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
105519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (isa<LoadInst>(B))
105619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return isStoredObjCPointer(A);
105719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
105819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
105919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (BIsIdentified && isa<LoadInst>(A))
106019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return isStoredObjCPointer(B);
106119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
106219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
106319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman   // Special handling for PHI and Select.
106419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (const PHINode *PN = dyn_cast<PHINode>(A))
106519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return relatedPHI(PN, B);
106619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (const PHINode *PN = dyn_cast<PHINode>(B))
106719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return relatedPHI(PN, A);
106819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (const SelectInst *S = dyn_cast<SelectInst>(A))
106919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return relatedSelect(S, B);
107019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (const SelectInst *S = dyn_cast<SelectInst>(B))
107119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return relatedSelect(S, A);
107219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
107319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Conservative.
107419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
107519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
107619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
107719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ProvenanceAnalysis::related(const Value *A, const Value *B) {
107819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Begin by inserting a conservative value into the map. If the insertion
107919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // fails, we have the answer already. If it succeeds, leave it there until we
108019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // compute the real answer to guard against recursive queries.
108119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (A > B) std::swap(A, B);
108219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  std::pair<CachedResultsTy::iterator, bool> Pair =
108319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CachedResults.insert(std::make_pair(ValuePairTy(A, B), true));
108419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Pair.second)
108519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return Pair.first->second;
108619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
108719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool Result = relatedCheck(A, B);
108819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CachedResults[ValuePairTy(A, B)] = Result;
108919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Result;
109019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
109119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
109219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
109319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Sequence - A sequence of states that a pointer may go through in which an
109419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // objc_retain and objc_release are actually needed.
109519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  enum Sequence {
109619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    S_None,
109719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    S_Retain,         ///< objc_retain(x)
109819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    S_CanRelease,     ///< foo(x) -- x could possibly see a ref count decrement
109919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    S_Use,            ///< any use of x
110019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    S_Stop,           ///< like S_Release, but code motion is stopped
110119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    S_Release,        ///< objc_release(x)
110219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    S_MovableRelease  ///< objc_release(x), !clang.imprecise_release
110319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
110419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
110519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
110619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic Sequence MergeSeqs(Sequence A, Sequence B, bool TopDown) {
110719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // The easy cases.
110819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (A == B)
110919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return A;
111019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (A == S_None || B == S_None)
111119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return S_None;
111219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
111319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (A > B) std::swap(A, B);
111419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (TopDown) {
111519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Choose the side which is further along in the sequence.
111619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if ((A == S_Retain || A == S_CanRelease) &&
111719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        (B == S_CanRelease || B == S_Use))
111819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return B;
111919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
112019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Choose the side which is further along in the sequence.
112119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if ((A == S_Use || A == S_CanRelease) &&
112219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        (B == S_Use || B == S_Release || B == S_Stop || B == S_MovableRelease))
112319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return A;
112419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // If both sides are releases, choose the more conservative one.
112519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (A == S_Stop && (B == S_Release || B == S_MovableRelease))
112619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return A;
112719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (A == S_Release && B == S_MovableRelease)
112819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return A;
112919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
113019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
113119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return S_None;
113219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
113319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
113419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
113519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// RRInfo - Unidirectional information about either a
113619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// retain-decrement-use-release sequence or release-use-decrement-retain
113719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// reverese sequence.
113819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  struct RRInfo {
113919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// KnownSafe - After an objc_retain, the reference count of the referenced
114019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// object is known to be positive. Similarly, before an objc_release, the
114119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// reference count of the referenced object is known to be positive. If
114219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// there are retain-release pairs in code regions where the retain count
114319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// is known to be positive, they can be eliminated, regardless of any side
114419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// effects between them.
114519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ///
114619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// Also, a retain+release pair nested within another retain+release
114719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// pair all on the known same pointer value can be eliminated, regardless
114819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// of any intervening side effects.
114919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ///
115019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// KnownSafe is true when either of these conditions is satisfied.
115119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool KnownSafe;
115219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
115319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// IsRetainBlock - True if the Calls are objc_retainBlock calls (as
115419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// opposed to objc_retain calls).
115519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool IsRetainBlock;
115619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
115719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// IsTailCallRelease - True of the objc_release calls are all marked
115819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// with the "tail" keyword.
115919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool IsTailCallRelease;
116019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
116119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// ReleaseMetadata - If the Calls are objc_release calls and they all have
116219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// a clang.imprecise_release tag, this is the metadata tag.
116319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MDNode *ReleaseMetadata;
116419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
116519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// Calls - For a top-down sequence, the set of objc_retains or
116619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// objc_retainBlocks. For bottom-up, the set of objc_releases.
116719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SmallPtrSet<Instruction *, 2> Calls;
116819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
116919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// ReverseInsertPts - The set of optimal insert positions for
117019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// moving calls in the opposite sequence.
117119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SmallPtrSet<Instruction *, 2> ReverseInsertPts;
117219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
117319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RRInfo() :
117419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      KnownSafe(false), IsRetainBlock(false), IsTailCallRelease(false),
117519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ReleaseMetadata(0) {}
117619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
117719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void clear();
117819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
117919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
118019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
118119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid RRInfo::clear() {
118219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  KnownSafe = false;
118319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  IsRetainBlock = false;
118419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  IsTailCallRelease = false;
118519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ReleaseMetadata = 0;
118619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Calls.clear();
118719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ReverseInsertPts.clear();
118819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
118919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
119019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
119119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// PtrState - This class summarizes several per-pointer runtime properties
119219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// which are propogated through the flow graph.
119319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class PtrState {
119419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// RefCount - The known minimum number of reference count increments.
119519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned RefCount;
119619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
119719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// NestCount - The known minimum level of retain+release nesting.
119819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned NestCount;
119919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
120019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// Seq - The current position in the sequence.
120119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Sequence Seq;
120219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
120319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  public:
120419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// RRI - Unidirectional information about the current sequence.
120519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// TODO: Encapsulate this better.
120619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RRInfo RRI;
120719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
120819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PtrState() : RefCount(0), NestCount(0), Seq(S_None) {}
120919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
121019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void SetAtLeastOneRefCount()  {
121119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (RefCount == 0) RefCount = 1;
121219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
121319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
121419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void IncrementRefCount() {
121519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (RefCount != UINT_MAX) ++RefCount;
121619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
121719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
121819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void DecrementRefCount() {
121919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (RefCount != 0) --RefCount;
122019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
122119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
122219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool IsKnownIncremented() const {
122319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return RefCount > 0;
122419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
122519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
122619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void IncrementNestCount() {
122719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (NestCount != UINT_MAX) ++NestCount;
122819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
122919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
123019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void DecrementNestCount() {
123119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (NestCount != 0) --NestCount;
123219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
123319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
123419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool IsKnownNested() const {
123519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return NestCount > 0;
123619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
123719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
123819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void SetSeq(Sequence NewSeq) {
123919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Seq = NewSeq;
124019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
124119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
124219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void SetSeqToRelease(MDNode *M) {
124319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Seq == S_None || Seq == S_Use) {
124419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Seq = M ? S_MovableRelease : S_Release;
124519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        RRI.ReleaseMetadata = M;
124619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      } else if (Seq != S_MovableRelease || RRI.ReleaseMetadata != M) {
124719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Seq = S_Release;
124819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        RRI.ReleaseMetadata = 0;
124919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
125019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
125119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
125219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Sequence GetSeq() const {
125319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return Seq;
125419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
125519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
125619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void ClearSequenceProgress() {
125719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Seq = S_None;
125819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      RRI.clear();
125919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
126019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
126119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void Merge(const PtrState &Other, bool TopDown);
126219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
126319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
126419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
126519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid
126619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanPtrState::Merge(const PtrState &Other, bool TopDown) {
126719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Seq = MergeSeqs(Seq, Other.Seq, TopDown);
126819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RefCount = std::min(RefCount, Other.RefCount);
126919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  NestCount = std::min(NestCount, Other.NestCount);
127019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
127119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // We can't merge a plain objc_retain with an objc_retainBlock.
127219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (RRI.IsRetainBlock != Other.RRI.IsRetainBlock)
127319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Seq = S_None;
127419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
127519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Seq == S_None) {
127619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RRI.clear();
127719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else {
127819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Conservatively merge the ReleaseMetadata information.
127919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (RRI.ReleaseMetadata != Other.RRI.ReleaseMetadata)
128019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      RRI.ReleaseMetadata = 0;
128119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
128219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RRI.KnownSafe = RRI.KnownSafe && Other.RRI.KnownSafe;
128319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RRI.IsTailCallRelease = RRI.IsTailCallRelease && Other.RRI.IsTailCallRelease;
128419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RRI.Calls.insert(Other.RRI.Calls.begin(), Other.RRI.Calls.end());
128519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RRI.ReverseInsertPts.insert(Other.RRI.ReverseInsertPts.begin(),
128619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                Other.RRI.ReverseInsertPts.end());
128719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
128819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
128919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
129019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
129119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// BBState - Per-BasicBlock state.
129219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class BBState {
129319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// TopDownPathCount - The number of unique control paths from the entry
129419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// which can reach this block.
129519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned TopDownPathCount;
129619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
129719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// BottomUpPathCount - The number of unique control paths to exits
129819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// from this block.
129919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned BottomUpPathCount;
130019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
130119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// MapTy - A type for PerPtrTopDown and PerPtrBottomUp.
130219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    typedef MapVector<const Value *, PtrState> MapTy;
130319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
130419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// PerPtrTopDown - The top-down traversal uses this to record information
130519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// known about a pointer at the bottom of each block.
130619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MapTy PerPtrTopDown;
130719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
130819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// PerPtrBottomUp - The bottom-up traversal uses this to record information
130919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// known about a pointer at the top of each block.
131019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MapTy PerPtrBottomUp;
131119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
131219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  public:
131319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BBState() : TopDownPathCount(0), BottomUpPathCount(0) {}
131419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
131519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    typedef MapTy::iterator ptr_iterator;
131619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    typedef MapTy::const_iterator ptr_const_iterator;
131719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
131819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ptr_iterator top_down_ptr_begin() { return PerPtrTopDown.begin(); }
131919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ptr_iterator top_down_ptr_end() { return PerPtrTopDown.end(); }
132019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ptr_const_iterator top_down_ptr_begin() const {
132119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return PerPtrTopDown.begin();
132219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
132319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ptr_const_iterator top_down_ptr_end() const {
132419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return PerPtrTopDown.end();
132519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
132619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
132719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ptr_iterator bottom_up_ptr_begin() { return PerPtrBottomUp.begin(); }
132819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ptr_iterator bottom_up_ptr_end() { return PerPtrBottomUp.end(); }
132919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ptr_const_iterator bottom_up_ptr_begin() const {
133019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return PerPtrBottomUp.begin();
133119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
133219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ptr_const_iterator bottom_up_ptr_end() const {
133319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return PerPtrBottomUp.end();
133419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
133519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
133619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// SetAsEntry - Mark this block as being an entry block, which has one
133719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// path from the entry by definition.
133819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void SetAsEntry() { TopDownPathCount = 1; }
133919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
134019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// SetAsExit - Mark this block as being an exit block, which has one
134119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// path to an exit by definition.
134219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void SetAsExit()  { BottomUpPathCount = 1; }
134319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
134419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PtrState &getPtrTopDownState(const Value *Arg) {
134519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return PerPtrTopDown[Arg];
134619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
134719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
134819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    PtrState &getPtrBottomUpState(const Value *Arg) {
134919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return PerPtrBottomUp[Arg];
135019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
135119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
135219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void clearBottomUpPointers() {
135319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PerPtrBottomUp.clear();
135419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
135519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
135619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void clearTopDownPointers() {
135719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PerPtrTopDown.clear();
135819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
135919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
136019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void InitFromPred(const BBState &Other);
136119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void InitFromSucc(const BBState &Other);
136219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void MergePred(const BBState &Other);
136319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void MergeSucc(const BBState &Other);
136419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
136519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// GetAllPathCount - Return the number of possible unique paths from an
136619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// entry to an exit which pass through this block. This is only valid
136719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// after both the top-down and bottom-up traversals are complete.
136819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned GetAllPathCount() const {
136919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return TopDownPathCount * BottomUpPathCount;
137019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
137119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
137219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// IsVisitedTopDown - Test whether the block for this BBState has been
137319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// visited by the top-down portion of the algorithm.
137419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool isVisitedTopDown() const {
137519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return TopDownPathCount != 0;
137619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
137719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
137819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
137919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
138019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid BBState::InitFromPred(const BBState &Other) {
138119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  PerPtrTopDown = Other.PerPtrTopDown;
138219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TopDownPathCount = Other.TopDownPathCount;
138319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
138419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
138519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid BBState::InitFromSucc(const BBState &Other) {
138619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  PerPtrBottomUp = Other.PerPtrBottomUp;
138719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BottomUpPathCount = Other.BottomUpPathCount;
138819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
138919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
139019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// MergePred - The top-down traversal uses this to merge information about
139119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// predecessors to form the initial state for a new block.
139219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid BBState::MergePred(const BBState &Other) {
139319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Other.TopDownPathCount can be 0, in which case it is either dead or a
139419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // loop backedge. Loop backedges are special.
139519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  TopDownPathCount += Other.TopDownPathCount;
139619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
139719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // For each entry in the other set, if our set has an entry with the same key,
139819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // merge the entries. Otherwise, copy the entry and merge it with an empty
139919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // entry.
140019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (ptr_const_iterator MI = Other.top_down_ptr_begin(),
140119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       ME = Other.top_down_ptr_end(); MI != ME; ++MI) {
140219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::pair<ptr_iterator, bool> Pair = PerPtrTopDown.insert(*MI);
140319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Pair.first->second.Merge(Pair.second ? PtrState() : MI->second,
140419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             /*TopDown=*/true);
140519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
140619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
140719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // For each entry in our set, if the other set doesn't have an entry with the
140819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // same key, force it to merge with an empty entry.
140919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (ptr_iterator MI = top_down_ptr_begin(),
141019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       ME = top_down_ptr_end(); MI != ME; ++MI)
141119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Other.PerPtrTopDown.find(MI->first) == Other.PerPtrTopDown.end())
141219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MI->second.Merge(PtrState(), /*TopDown=*/true);
141319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
141419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
141519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// MergeSucc - The bottom-up traversal uses this to merge information about
141619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// successors to form the initial state for a new block.
141719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid BBState::MergeSucc(const BBState &Other) {
141819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Other.BottomUpPathCount can be 0, in which case it is either dead or a
141919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // loop backedge. Loop backedges are special.
142019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BottomUpPathCount += Other.BottomUpPathCount;
142119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
142219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // For each entry in the other set, if our set has an entry with the
142319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // same key, merge the entries. Otherwise, copy the entry and merge
142419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // it with an empty entry.
142519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (ptr_const_iterator MI = Other.bottom_up_ptr_begin(),
142619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       ME = Other.bottom_up_ptr_end(); MI != ME; ++MI) {
142719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::pair<ptr_iterator, bool> Pair = PerPtrBottomUp.insert(*MI);
142819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Pair.first->second.Merge(Pair.second ? PtrState() : MI->second,
142919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             /*TopDown=*/false);
143019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
143119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
143219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // For each entry in our set, if the other set doesn't have an entry
143319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // with the same key, force it to merge with an empty entry.
143419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (ptr_iterator MI = bottom_up_ptr_begin(),
143519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       ME = bottom_up_ptr_end(); MI != ME; ++MI)
143619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Other.PerPtrBottomUp.find(MI->first) == Other.PerPtrBottomUp.end())
143719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MI->second.Merge(PtrState(), /*TopDown=*/false);
143819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
143919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
144019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
144119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// ObjCARCOpt - The main ARC optimization pass.
144219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class ObjCARCOpt : public FunctionPass {
144319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool Changed;
144419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ProvenanceAnalysis PA;
144519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
144619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// Run - A flag indicating whether this optimization pass should run.
144719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool Run;
144819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
144919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// RetainRVCallee, etc. - Declarations for ObjC runtime
145019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// functions, for use in creating calls to them. These are initialized
145119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// lazily to avoid cluttering up the Module with unused declarations.
145219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *RetainRVCallee, *AutoreleaseRVCallee, *ReleaseCallee,
145319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             *RetainCallee, *RetainBlockCallee, *AutoreleaseCallee;
145419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
145519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// UsedInThisFunciton - Flags which determine whether each of the
145619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// interesting runtine functions is in fact used in the current function.
145719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned UsedInThisFunction;
145819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
145919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// ImpreciseReleaseMDKind - The Metadata Kind for clang.imprecise_release
146019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// metadata.
146119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned ImpreciseReleaseMDKind;
146219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
146319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getRetainRVCallee(Module *M);
146419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getAutoreleaseRVCallee(Module *M);
146519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getReleaseCallee(Module *M);
146619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getRetainCallee(Module *M);
146719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getRetainBlockCallee(Module *M);
146819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getAutoreleaseCallee(Module *M);
146919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
147019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void OptimizeRetainCall(Function &F, Instruction *Retain);
147119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool OptimizeRetainRVCall(Function &F, Instruction *RetainRV);
147219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void OptimizeAutoreleaseRVCall(Function &F, Instruction *AutoreleaseRV);
147319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void OptimizeIndividualCalls(Function &F);
147419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
147519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void CheckForCFGHazards(const BasicBlock *BB,
147619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            DenseMap<const BasicBlock *, BBState> &BBStates,
147719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            BBState &MyStates) const;
147819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool VisitBottomUp(BasicBlock *BB,
147919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       DenseMap<const BasicBlock *, BBState> &BBStates,
148019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       MapVector<Value *, RRInfo> &Retains);
148119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool VisitTopDown(BasicBlock *BB,
148219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      DenseMap<const BasicBlock *, BBState> &BBStates,
148319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      DenseMap<Value *, RRInfo> &Releases);
148419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool Visit(Function &F,
148519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               DenseMap<const BasicBlock *, BBState> &BBStates,
148619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               MapVector<Value *, RRInfo> &Retains,
148719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               DenseMap<Value *, RRInfo> &Releases);
148819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
148919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void MoveCalls(Value *Arg, RRInfo &RetainsToMove, RRInfo &ReleasesToMove,
149019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   MapVector<Value *, RRInfo> &Retains,
149119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   DenseMap<Value *, RRInfo> &Releases,
149219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   SmallVectorImpl<Instruction *> &DeadInsts,
149319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   Module *M);
149419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
149519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool PerformCodePlacement(DenseMap<const BasicBlock *, BBState> &BBStates,
149619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                              MapVector<Value *, RRInfo> &Retains,
149719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                              DenseMap<Value *, RRInfo> &Releases,
149819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                              Module *M);
149919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
150019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void OptimizeWeakCalls(Function &F);
150119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
150219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool OptimizeSequences(Function &F);
150319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
150419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void OptimizeReturns(Function &F);
150519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
150619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual void getAnalysisUsage(AnalysisUsage &AU) const;
150719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual bool doInitialization(Module &M);
150819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual bool runOnFunction(Function &F);
150919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual void releaseMemory();
151019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
151119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  public:
151219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static char ID;
151319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ObjCARCOpt() : FunctionPass(ID) {
151419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      initializeObjCARCOptPass(*PassRegistry::getPassRegistry());
151519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
151619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
151719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
151819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
151919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanchar ObjCARCOpt::ID = 0;
152019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_BEGIN(ObjCARCOpt,
152119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      "objc-arc", "ObjC ARC optimization", false, false)
152219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_DEPENDENCY(ObjCARCAliasAnalysis)
152319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_END(ObjCARCOpt,
152419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                    "objc-arc", "ObjC ARC optimization", false, false)
152519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
152619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanPass *llvm::createObjCARCOptPass() {
152719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return new ObjCARCOpt();
152819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
152919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
153019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ObjCARCOpt::getAnalysisUsage(AnalysisUsage &AU) const {
153119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AU.addRequired<ObjCARCAliasAnalysis>();
153219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AU.addRequired<AliasAnalysis>();
153319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // ARC optimization doesn't currently split critical edges.
153419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AU.setPreservesCFG();
153519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
153619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
153719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *ObjCARCOpt::getRetainRVCallee(Module *M) {
153819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!RetainRVCallee) {
153919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LLVMContext &C = M->getContext();
154019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
154119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::vector<Type *> Params;
154219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Params.push_back(I8X);
154319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FunctionType *FTy =
154419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FunctionType::get(I8X, Params, /*isVarArg=*/false);
154519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AttrListPtr Attributes;
154619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Attributes.addAttr(~0u, Attribute::NoUnwind);
154719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RetainRVCallee =
154819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      M->getOrInsertFunction("objc_retainAutoreleasedReturnValue", FTy,
154919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             Attributes);
155019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
155119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return RetainRVCallee;
155219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
155319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
155419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *ObjCARCOpt::getAutoreleaseRVCallee(Module *M) {
155519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!AutoreleaseRVCallee) {
155619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LLVMContext &C = M->getContext();
155719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
155819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::vector<Type *> Params;
155919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Params.push_back(I8X);
156019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FunctionType *FTy =
156119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FunctionType::get(I8X, Params, /*isVarArg=*/false);
156219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AttrListPtr Attributes;
156319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Attributes.addAttr(~0u, Attribute::NoUnwind);
156419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AutoreleaseRVCallee =
156519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      M->getOrInsertFunction("objc_autoreleaseReturnValue", FTy,
156619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             Attributes);
156719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
156819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return AutoreleaseRVCallee;
156919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
157019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
157119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *ObjCARCOpt::getReleaseCallee(Module *M) {
157219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!ReleaseCallee) {
157319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LLVMContext &C = M->getContext();
157419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::vector<Type *> Params;
157519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Params.push_back(PointerType::getUnqual(Type::getInt8Ty(C)));
157619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AttrListPtr Attributes;
157719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Attributes.addAttr(~0u, Attribute::NoUnwind);
157819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ReleaseCallee =
157919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      M->getOrInsertFunction(
158019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        "objc_release",
158119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        FunctionType::get(Type::getVoidTy(C), Params, /*isVarArg=*/false),
158219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Attributes);
158319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
158419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return ReleaseCallee;
158519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
158619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
158719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *ObjCARCOpt::getRetainCallee(Module *M) {
158819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!RetainCallee) {
158919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LLVMContext &C = M->getContext();
159019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::vector<Type *> Params;
159119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Params.push_back(PointerType::getUnqual(Type::getInt8Ty(C)));
159219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AttrListPtr Attributes;
159319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Attributes.addAttr(~0u, Attribute::NoUnwind);
159419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RetainCallee =
159519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      M->getOrInsertFunction(
159619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        "objc_retain",
159719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        FunctionType::get(Params[0], Params, /*isVarArg=*/false),
159819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Attributes);
159919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
160019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return RetainCallee;
160119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
160219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
160319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *ObjCARCOpt::getRetainBlockCallee(Module *M) {
160419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!RetainBlockCallee) {
160519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LLVMContext &C = M->getContext();
160619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::vector<Type *> Params;
160719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Params.push_back(PointerType::getUnqual(Type::getInt8Ty(C)));
160819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AttrListPtr Attributes;
160919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // objc_retainBlock is not nounwind because it calls user copy constructors
161019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // which could theoretically throw.
161119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RetainBlockCallee =
161219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      M->getOrInsertFunction(
161319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        "objc_retainBlock",
161419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        FunctionType::get(Params[0], Params, /*isVarArg=*/false),
161519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Attributes);
161619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
161719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return RetainBlockCallee;
161819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
161919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
162019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *ObjCARCOpt::getAutoreleaseCallee(Module *M) {
162119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!AutoreleaseCallee) {
162219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LLVMContext &C = M->getContext();
162319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::vector<Type *> Params;
162419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Params.push_back(PointerType::getUnqual(Type::getInt8Ty(C)));
162519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AttrListPtr Attributes;
162619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Attributes.addAttr(~0u, Attribute::NoUnwind);
162719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AutoreleaseCallee =
162819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      M->getOrInsertFunction(
162919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        "objc_autorelease",
163019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        FunctionType::get(Params[0], Params, /*isVarArg=*/false),
163119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Attributes);
163219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
163319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return AutoreleaseCallee;
163419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
163519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
163619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// CanAlterRefCount - Test whether the given instruction can result in a
163719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// reference count modification (positive or negative) for the pointer's
163819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// object.
163919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool
164019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCanAlterRefCount(const Instruction *Inst, const Value *Ptr,
164119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 ProvenanceAnalysis &PA, InstructionClass Class) {
164219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (Class) {
164319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_Autorelease:
164419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_AutoreleaseRV:
164519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_User:
164619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // These operations never directly modify a reference count.
164719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
164819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default: break;
164919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
165019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
165119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ImmutableCallSite CS = static_cast<const Value *>(Inst);
165219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  assert(CS && "Only calls can alter reference counts!");
165319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
165419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // See if AliasAnalysis can help us with the call.
165519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AliasAnalysis::ModRefBehavior MRB = PA.getAA()->getModRefBehavior(CS);
165619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (AliasAnalysis::onlyReadsMemory(MRB))
165719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
165819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (AliasAnalysis::onlyAccessesArgPointees(MRB)) {
165919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
166019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         I != E; ++I) {
166119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const Value *Op = *I;
166219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (IsPotentialUse(Op) && PA.related(Ptr, Op))
166319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return true;
166419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
166519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
166619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
166719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
166819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Assume the worst.
166919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
167019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
167119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
167219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// CanUse - Test whether the given instruction can "use" the given pointer's
167319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// object in a way that requires the reference count to be positive.
167419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool
167519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCanUse(const Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA,
167619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       InstructionClass Class) {
167719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // IC_Call operations (as opposed to IC_CallOrUser) never "use" objc pointers.
167819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Class == IC_Call)
167919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
168019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
168119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Consider various instructions which may have pointer arguments which are
168219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // not "uses".
168319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (const ICmpInst *ICI = dyn_cast<ICmpInst>(Inst)) {
168419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Comparing a pointer with null, or any other constant, isn't really a use,
168519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // because we don't care what the pointer points to, or about the values
168619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // of any other dynamic reference-counted pointers.
168719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!IsPotentialUse(ICI->getOperand(1)))
168819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
168919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else if (ImmutableCallSite CS = static_cast<const Value *>(Inst)) {
169019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // For calls, just check the arguments (and not the callee operand).
169119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (ImmutableCallSite::arg_iterator OI = CS.arg_begin(),
169219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         OE = CS.arg_end(); OI != OE; ++OI) {
169319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const Value *Op = *OI;
169419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (IsPotentialUse(Op) && PA.related(Ptr, Op))
169519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return true;
169619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
169719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
169819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } else if (const StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
169919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Special-case stores, because we don't care about the stored value, just
170019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // the store address.
170119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const Value *Op = GetUnderlyingObjCPtr(SI->getPointerOperand());
170219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // If we can't tell what the underlying object was, assume there is a
170319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // dependence.
170419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return IsPotentialUse(Op) && PA.related(Op, Ptr);
170519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
170619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
170719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Check each operand for a match.
170819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (User::const_op_iterator OI = Inst->op_begin(), OE = Inst->op_end();
170919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       OI != OE; ++OI) {
171019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const Value *Op = *OI;
171119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IsPotentialUse(Op) && PA.related(Ptr, Op))
171219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
171319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
171419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
171519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
171619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
171719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// CanInterruptRV - Test whether the given instruction can autorelease
171819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// any pointer or cause an autoreleasepool pop.
171919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool
172019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanCanInterruptRV(InstructionClass Class) {
172119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (Class) {
172219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_AutoreleasepoolPop:
172319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_CallOrUser:
172419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_Call:
172519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_Autorelease:
172619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_AutoreleaseRV:
172719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_FusedRetainAutorelease:
172819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case IC_FusedRetainAutoreleaseRV:
172919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
173019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  default:
173119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
173219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
173319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
173419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
173519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
173619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// DependenceKind - There are several kinds of dependence-like concepts in
173719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// use here.
173819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  enum DependenceKind {
173919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NeedsPositiveRetainCount,
174019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CanChangeRetainCount,
174119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RetainAutoreleaseDep,       ///< Blocks objc_retainAutorelease.
174219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RetainAutoreleaseRVDep,     ///< Blocks objc_retainAutoreleaseReturnValue.
174319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RetainRVDep                 ///< Blocks objc_retainAutoreleasedReturnValue.
174419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
174519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
174619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
174719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// Depends - Test if there can be dependencies on Inst through Arg. This
174819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// function only tests dependencies relevant for removing pairs of calls.
174919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool
175019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanDepends(DependenceKind Flavor, Instruction *Inst, const Value *Arg,
175119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        ProvenanceAnalysis &PA) {
175219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If we've reached the definition of Arg, stop.
175319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Inst == Arg)
175419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return true;
175519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
175619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  switch (Flavor) {
175719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case NeedsPositiveRetainCount: {
175819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InstructionClass Class = GetInstructionClass(Inst);
175919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (Class) {
176019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_AutoreleasepoolPop:
176119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_AutoreleasepoolPush:
176219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_None:
176319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
176419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
176519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return CanUse(Inst, Arg, PA, Class);
176619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
176719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
176819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
176919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case CanChangeRetainCount: {
177019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InstructionClass Class = GetInstructionClass(Inst);
177119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (Class) {
177219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_AutoreleasepoolPop:
177319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Conservatively assume this can decrement any count.
177419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
177519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_AutoreleasepoolPush:
177619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_None:
177719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
177819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
177919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return CanAlterRefCount(Inst, Arg, PA, Class);
178019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
178119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
178219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
178319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case RetainAutoreleaseDep:
178419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (GetBasicInstructionClass(Inst)) {
178519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_AutoreleasepoolPop:
178619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Don't merge an objc_autorelease with an objc_retain inside a different
178719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // autoreleasepool scope.
178819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
178919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_Retain:
179019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_RetainRV:
179119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Check for a retain of the same pointer for merging.
179219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return GetObjCArg(Inst) == Arg;
179319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
179419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Nothing else matters for objc_retainAutorelease formation.
179519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return false;
179619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
179719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
179819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
179919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case RetainAutoreleaseRVDep: {
180019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InstructionClass Class = GetBasicInstructionClass(Inst);
180119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (Class) {
180219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_Retain:
180319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_RetainRV:
180419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Check for a retain of the same pointer for merging.
180519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return GetObjCArg(Inst) == Arg;
180619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
180719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Anything that can autorelease interrupts
180819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // retainAutoreleaseReturnValue formation.
180919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return CanInterruptRV(Class);
181019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
181119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    break;
181219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
181319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
181419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  case RetainRVDep:
181519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return CanInterruptRV(GetBasicInstructionClass(Inst));
181619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
181719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
181819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  llvm_unreachable("Invalid dependence flavor");
181919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
182019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
182119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
182219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// FindDependencies - Walk up the CFG from StartPos (which is in StartBB) and
182319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// find local and non-local dependencies on Arg.
182419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// TODO: Cache results?
182519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void
182619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanFindDependencies(DependenceKind Flavor,
182719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 const Value *Arg,
182819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 BasicBlock *StartBB, Instruction *StartInst,
182919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 SmallPtrSet<Instruction *, 4> &DependingInstructions,
183019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 SmallPtrSet<const BasicBlock *, 4> &Visited,
183119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                 ProvenanceAnalysis &PA) {
183219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock::iterator StartPos = StartInst;
183319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
183419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<std::pair<BasicBlock *, BasicBlock::iterator>, 4> Worklist;
183519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Worklist.push_back(std::make_pair(StartBB, StartPos));
183619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  do {
183719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::pair<BasicBlock *, BasicBlock::iterator> Pair =
183819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Worklist.pop_back_val();
183919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BasicBlock *LocalStartBB = Pair.first;
184019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BasicBlock::iterator LocalStartPos = Pair.second;
184119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BasicBlock::iterator StartBBBegin = LocalStartBB->begin();
184219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (;;) {
184319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (LocalStartPos == StartBBBegin) {
184419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        pred_iterator PI(LocalStartBB), PE(LocalStartBB, false);
184519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (PI == PE)
184619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // If we've reached the function entry, produce a null dependence.
184719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          DependingInstructions.insert(0);
184819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        else
184919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // Add the predecessors to the worklist.
185019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          do {
185119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            BasicBlock *PredBB = *PI;
185219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (Visited.insert(PredBB))
185319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              Worklist.push_back(std::make_pair(PredBB, PredBB->end()));
185419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          } while (++PI != PE);
185519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
185619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
185719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
185819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Instruction *Inst = --LocalStartPos;
185919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Depends(Flavor, Inst, Arg, PA)) {
186019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DependingInstructions.insert(Inst);
186119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
186219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
186319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
186419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } while (!Worklist.empty());
186519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
186619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Determine whether the original StartBB post-dominates all of the blocks we
186719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // visited. If not, insert a sentinal indicating that most optimizations are
186819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // not safe.
186919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (SmallPtrSet<const BasicBlock *, 4>::const_iterator I = Visited.begin(),
187019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       E = Visited.end(); I != E; ++I) {
187119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const BasicBlock *BB = *I;
187219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (BB == StartBB)
187319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
187419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const TerminatorInst *TI = cast<TerminatorInst>(&BB->back());
187519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (succ_const_iterator SI(TI), SE(TI, false); SI != SE; ++SI) {
187619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const BasicBlock *Succ = *SI;
187719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Succ != StartBB && !Visited.count(Succ)) {
187819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DependingInstructions.insert(reinterpret_cast<Instruction *>(-1));
187919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return;
188019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
188119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
188219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
188319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
188419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
188519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool isNullOrUndef(const Value *V) {
188619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return isa<ConstantPointerNull>(V) || isa<UndefValue>(V);
188719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
188819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
188919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool isNoopInstruction(const Instruction *I) {
189019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return isa<BitCastInst>(I) ||
189119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         (isa<GetElementPtrInst>(I) &&
189219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          cast<GetElementPtrInst>(I)->hasAllZeroIndices());
189319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
189419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
189519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// OptimizeRetainCall - Turn objc_retain into
189619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// objc_retainAutoreleasedReturnValue if the operand is a return value.
189719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid
189819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCOpt::OptimizeRetainCall(Function &F, Instruction *Retain) {
189919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CallSite CS(GetObjCArg(Retain));
190019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Instruction *Call = CS.getInstruction();
190119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Call) return;
190219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Call->getParent() != Retain->getParent()) return;
190319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
190419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Check that the call is next to the retain.
190519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock::iterator I = Call;
190619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++I;
190719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (isNoopInstruction(I)) ++I;
190819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (&*I != Retain)
190919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return;
191019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
191119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Turn it to an objc_retainAutoreleasedReturnValue..
191219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Changed = true;
191319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++NumPeeps;
191419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  cast<CallInst>(Retain)->setCalledFunction(getRetainRVCallee(F.getParent()));
191519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
191619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
191719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// OptimizeRetainRVCall - Turn objc_retainAutoreleasedReturnValue into
191819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// objc_retain if the operand is not a return value.  Or, if it can be
191919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// paired with an objc_autoreleaseReturnValue, delete the pair and
192019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// return true.
192119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool
192219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) {
192319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Check for the argument being from an immediately preceding call.
192419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Value *Arg = GetObjCArg(RetainRV);
192519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CallSite CS(Arg);
192619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Instruction *Call = CS.getInstruction())
192719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Call->getParent() == RetainRV->getParent()) {
192819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BasicBlock::iterator I = Call;
192919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ++I;
193019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      while (isNoopInstruction(I)) ++I;
193119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (&*I == RetainRV)
193219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return false;
193319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
193419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
193519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Check for being preceded by an objc_autoreleaseReturnValue on the same
193619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // pointer. In this case, we can delete the pair.
193719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock::iterator I = RetainRV, Begin = RetainRV->getParent()->begin();
193819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (I != Begin) {
193919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    do --I; while (I != Begin && isNoopInstruction(I));
194019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (GetBasicInstructionClass(I) == IC_AutoreleaseRV &&
194119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        GetObjCArg(I) == Arg) {
194219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Changed = true;
194319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ++NumPeeps;
194419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      EraseInstruction(I);
194519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      EraseInstruction(RetainRV);
194619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      return true;
194719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
194819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
194919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
195019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Turn it to a plain objc_retain.
195119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Changed = true;
195219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++NumPeeps;
195319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  cast<CallInst>(RetainRV)->setCalledFunction(getRetainCallee(F.getParent()));
195419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
195519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
195619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
195719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// OptimizeAutoreleaseRVCall - Turn objc_autoreleaseReturnValue into
195819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// objc_autorelease if the result is not used as a return value.
195919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid
196019bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCOpt::OptimizeAutoreleaseRVCall(Function &F, Instruction *AutoreleaseRV) {
196119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Check for a return of the pointer value.
196219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const Value *Ptr = GetObjCArg(AutoreleaseRV);
196319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<const Value *, 2> Users;
196419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Users.push_back(Ptr);
196519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  do {
196619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Ptr = Users.pop_back_val();
196719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (Value::const_use_iterator UI = Ptr->use_begin(), UE = Ptr->use_end();
196819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         UI != UE; ++UI) {
196919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const User *I = *UI;
197019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (isa<ReturnInst>(I) || GetBasicInstructionClass(I) == IC_RetainRV)
197119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        return;
197219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (isa<BitCastInst>(I))
197319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Users.push_back(I);
197419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
197519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  } while (!Users.empty());
197619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
197719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Changed = true;
197819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++NumPeeps;
197919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  cast<CallInst>(AutoreleaseRV)->
198019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    setCalledFunction(getAutoreleaseCallee(F.getParent()));
198119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
198219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
198319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// OptimizeIndividualCalls - Visit each call, one at a time, and make
198419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// simplifications without doing any additional analysis.
198519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
198619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Reset all the flags in preparation for recomputing them.
198719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  UsedInThisFunction = 0;
198819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
198919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Visit all objc_* calls in F.
199019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) {
199119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *Inst = &*I++;
199219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InstructionClass Class = GetBasicInstructionClass(Inst);
199319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
199419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (Class) {
199519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default: break;
199619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
199719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Delete no-op casts. These function calls have special semantics, but
199819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // the semantics are entirely implemented via lowering in the front-end,
199919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // so by the time they reach the optimizer, they are just no-op calls
200019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // which return their argument.
200119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    //
200219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // There are gray areas here, as the ability to cast reference-counted
200319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // pointers to raw void* and back allows code to break ARC assumptions,
200419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // however these are currently considered to be unimportant.
200519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_NoopCast:
200619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Changed = true;
200719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ++NumNoops;
200819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      EraseInstruction(Inst);
200919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
201019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
201119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // If the pointer-to-weak-pointer is null, it's undefined behavior.
201219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_StoreWeak:
201319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_LoadWeak:
201419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_LoadWeakRetained:
201519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_InitWeak:
201619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_DestroyWeak: {
201719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      CallInst *CI = cast<CallInst>(Inst);
201819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (isNullOrUndef(CI->getArgOperand(0))) {
201919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type *Ty = CI->getArgOperand(0)->getType();
202019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        new StoreInst(UndefValue::get(cast<PointerType>(Ty)->getElementType()),
202119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      Constant::getNullValue(Ty),
202219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      CI);
202319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CI->replaceAllUsesWith(UndefValue::get(CI->getType()));
202419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CI->eraseFromParent();
202519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
202619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
202719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
202819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
202919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_CopyWeak:
203019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_MoveWeak: {
203119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      CallInst *CI = cast<CallInst>(Inst);
203219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (isNullOrUndef(CI->getArgOperand(0)) ||
203319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          isNullOrUndef(CI->getArgOperand(1))) {
203419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Type *Ty = CI->getArgOperand(0)->getType();
203519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        new StoreInst(UndefValue::get(cast<PointerType>(Ty)->getElementType()),
203619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      Constant::getNullValue(Ty),
203719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      CI);
203819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CI->replaceAllUsesWith(UndefValue::get(CI->getType()));
203919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CI->eraseFromParent();
204019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
204119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
204219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
204319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
204419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_Retain:
204519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OptimizeRetainCall(F, Inst);
204619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
204719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_RetainRV:
204819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (OptimizeRetainRVCall(F, Inst))
204919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
205019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
205119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_AutoreleaseRV:
205219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      OptimizeAutoreleaseRVCall(F, Inst);
205319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
205419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
205519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
205619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // objc_autorelease(x) -> objc_release(x) if x is otherwise unused.
205719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IsAutorelease(Class) && Inst->use_empty()) {
205819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      CallInst *Call = cast<CallInst>(Inst);
205919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const Value *Arg = Call->getArgOperand(0);
206019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Arg = FindSingleUseIdentifiedObject(Arg);
206119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Arg) {
206219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Changed = true;
206319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        ++NumAutoreleases;
206419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
206519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Create the declaration lazily.
206619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        LLVMContext &C = Inst->getContext();
206719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CallInst *NewCall =
206819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          CallInst::Create(getReleaseCallee(F.getParent()),
206919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           Call->getArgOperand(0), "", Call);
207019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        NewCall->setMetadata(ImpreciseReleaseMDKind,
207119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             MDNode::get(C, ArrayRef<Value *>()));
207219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        EraseInstruction(Call);
207319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Inst = NewCall;
207419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Class = IC_Release;
207519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
207619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
207719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
207819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // For functions which can never be passed stack arguments, add
207919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // a tail keyword.
208019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IsAlwaysTail(Class)) {
208119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Changed = true;
208219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      cast<CallInst>(Inst)->setTailCall();
208319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
208419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
208519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Set nounwind as needed.
208619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (IsNoThrow(Class)) {
208719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Changed = true;
208819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      cast<CallInst>(Inst)->setDoesNotThrow();
208919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
209019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
209119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!IsNoopOnNull(Class)) {
209219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      UsedInThisFunction |= 1 << Class;
209319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
209419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
209519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
209619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const Value *Arg = GetObjCArg(Inst);
209719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
209819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // ARC calls with null are no-ops. Delete them.
209919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (isNullOrUndef(Arg)) {
210019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Changed = true;
210119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ++NumNoops;
210219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      EraseInstruction(Inst);
210319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
210419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
210519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
210619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Keep track of which of retain, release, autorelease, and retain_block
210719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // are actually present in this function.
210819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    UsedInThisFunction |= 1 << Class;
210919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
211019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // If Arg is a PHI, and one or more incoming values to the
211119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // PHI are null, and the call is control-equivalent to the PHI, and there
211219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // are no relevant side effects between the PHI and the call, the call
211319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // could be pushed up to just those paths with non-null incoming values.
211419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // For now, don't bother splitting critical edges for this.
211519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    SmallVector<std::pair<Instruction *, const Value *>, 4> Worklist;
211619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Worklist.push_back(std::make_pair(Inst, Arg));
211719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    do {
211819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      std::pair<Instruction *, const Value *> Pair = Worklist.pop_back_val();
211919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Inst = Pair.first;
212019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Arg = Pair.second;
212119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
212219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const PHINode *PN = dyn_cast<PHINode>(Arg);
212319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!PN) continue;
212419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
212519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Determine if the PHI has any null operands, or any incoming
212619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // critical edges.
212719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool HasNull = false;
212819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool HasCriticalEdges = false;
212919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
213019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Value *Incoming =
213119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          StripPointerCastsAndObjCCalls(PN->getIncomingValue(i));
213219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (isNullOrUndef(Incoming))
213319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          HasNull = true;
213419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        else if (cast<TerminatorInst>(PN->getIncomingBlock(i)->back())
213519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   .getNumSuccessors() != 1) {
213619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          HasCriticalEdges = true;
213719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
213819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
213919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
214019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If we have null operands and no critical edges, optimize.
214119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!HasCriticalEdges && HasNull) {
214219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        SmallPtrSet<Instruction *, 4> DependingInstructions;
214319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        SmallPtrSet<const BasicBlock *, 4> Visited;
214419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
214519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Check that there is nothing that cares about the reference
214619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // count between the call and the phi.
214719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        FindDependencies(NeedsPositiveRetainCount, Arg,
214819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         Inst->getParent(), Inst,
214919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         DependingInstructions, Visited, PA);
215019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (DependingInstructions.size() == 1 &&
215119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            *DependingInstructions.begin() == PN) {
215219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Changed = true;
215319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          ++NumPartialNoops;
215419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // Clone the call into each predecessor that has a non-null value.
215519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          CallInst *CInst = cast<CallInst>(Inst);
215619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Type *ParamTy = CInst->getArgOperand(0)->getType();
215719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
215819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Value *Incoming =
215919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              StripPointerCastsAndObjCCalls(PN->getIncomingValue(i));
216019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (!isNullOrUndef(Incoming)) {
216119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              CallInst *Clone = cast<CallInst>(CInst->clone());
216219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              Value *Op = PN->getIncomingValue(i);
216319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              Instruction *InsertPos = &PN->getIncomingBlock(i)->back();
216419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              if (Op->getType() != ParamTy)
216519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                Op = new BitCastInst(Op, ParamTy, "", InsertPos);
216619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              Clone->setArgOperand(0, Op);
216719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              Clone->insertBefore(InsertPos);
216819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              Worklist.push_back(std::make_pair(Clone, Incoming));
216919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            }
217019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          }
217119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // Erase the original call.
217219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          EraseInstruction(CInst);
217319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          continue;
217419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
217519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
217619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } while (!Worklist.empty());
217719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
217819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
217919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
218019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// CheckForCFGHazards - Check for critical edges, loop boundaries, irreducible
218119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// control flow, or other CFG structures where moving code across the edge
218219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// would result in it being executed more.
218319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid
218419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCOpt::CheckForCFGHazards(const BasicBlock *BB,
218519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               DenseMap<const BasicBlock *, BBState> &BBStates,
218619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               BBState &MyStates) const {
218719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If any top-down local-use or possible-dec has a succ which is earlier in
218819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // the sequence, forget it.
218919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (BBState::ptr_const_iterator I = MyStates.top_down_ptr_begin(),
219019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       E = MyStates.top_down_ptr_end(); I != E; ++I)
219119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (I->second.GetSeq()) {
219219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default: break;
219319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case S_Use: {
219419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const Value *Arg = I->first;
219519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const TerminatorInst *TI = cast<TerminatorInst>(&BB->back());
219619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool SomeSuccHasSame = false;
219719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool AllSuccsHaveSame = true;
219819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PtrState &S = MyStates.getPtrTopDownState(Arg);
219919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (succ_const_iterator SI(TI), SE(TI, false); SI != SE; ++SI) {
220019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        PtrState &SuccS = BBStates[*SI].getPtrBottomUpState(Arg);
220119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        switch (SuccS.GetSeq()) {
220219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_None:
220319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_CanRelease: {
220419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (!S.RRI.KnownSafe && !SuccS.RRI.KnownSafe)
220519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            S.ClearSequenceProgress();
220619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          continue;
220719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
220819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Use:
220919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          SomeSuccHasSame = true;
221019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
221119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Stop:
221219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Release:
221319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_MovableRelease:
221419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (!S.RRI.KnownSafe && !SuccS.RRI.KnownSafe)
221519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            AllSuccsHaveSame = false;
221619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
221719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Retain:
221819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          llvm_unreachable("bottom-up pointer in retain state!");
221919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
222019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
222119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If the state at the other end of any of the successor edges
222219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // matches the current state, require all edges to match. This
222319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // guards against loops in the middle of a sequence.
222419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (SomeSuccHasSame && !AllSuccsHaveSame)
222519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.ClearSequenceProgress();
222619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
222719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case S_CanRelease: {
222819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const Value *Arg = I->first;
222919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const TerminatorInst *TI = cast<TerminatorInst>(&BB->back());
223019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool SomeSuccHasSame = false;
223119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      bool AllSuccsHaveSame = true;
223219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PtrState &S = MyStates.getPtrTopDownState(Arg);
223319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (succ_const_iterator SI(TI), SE(TI, false); SI != SE; ++SI) {
223419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        PtrState &SuccS = BBStates[*SI].getPtrBottomUpState(Arg);
223519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        switch (SuccS.GetSeq()) {
223619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_None: {
223719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (!S.RRI.KnownSafe && !SuccS.RRI.KnownSafe)
223819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            S.ClearSequenceProgress();
223919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          continue;
224019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
224119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_CanRelease:
224219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          SomeSuccHasSame = true;
224319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
224419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Stop:
224519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Release:
224619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_MovableRelease:
224719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Use:
224819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (!S.RRI.KnownSafe && !SuccS.RRI.KnownSafe)
224919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            AllSuccsHaveSame = false;
225019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
225119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Retain:
225219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          llvm_unreachable("bottom-up pointer in retain state!");
225319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
225419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
225519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If the state at the other end of any of the successor edges
225619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // matches the current state, require all edges to match. This
225719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // guards against loops in the middle of a sequence.
225819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (SomeSuccHasSame && !AllSuccsHaveSame)
225919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.ClearSequenceProgress();
226019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
226119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
226219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
226319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
226419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool
226519bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCOpt::VisitBottomUp(BasicBlock *BB,
226619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                          DenseMap<const BasicBlock *, BBState> &BBStates,
226719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                          MapVector<Value *, RRInfo> &Retains) {
226819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool NestingDetected = false;
226919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBState &MyStates = BBStates[BB];
227019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
227119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Merge the states from each successor to compute the initial state
227219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // for the current block.
227319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const TerminatorInst *TI = cast<TerminatorInst>(&BB->back());
227419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  succ_const_iterator SI(TI), SE(TI, false);
227519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (SI == SE)
227619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MyStates.SetAsExit();
227719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else
227819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    do {
227919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const BasicBlock *Succ = *SI++;
228019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Succ == BB)
228119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
228219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      DenseMap<const BasicBlock *, BBState>::iterator I = BBStates.find(Succ);
228319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If we haven't seen this node yet, then we've found a CFG cycle.
228419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Be optimistic here; it's CheckForCFGHazards' job detect trouble.
228519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (I == BBStates.end())
228619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
228719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MyStates.InitFromSucc(I->second);
228819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      while (SI != SE) {
228919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Succ = *SI++;
229019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Succ != BB) {
229119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          I = BBStates.find(Succ);
229219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (I != BBStates.end())
229319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            MyStates.MergeSucc(I->second);
229419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
229519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
229619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
229719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } while (SI != SE);
229819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
229919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Visit all the instructions, bottom-up.
230019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (BasicBlock::iterator I = BB->end(), E = BB->begin(); I != E; --I) {
230119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *Inst = llvm::prior(I);
230219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InstructionClass Class = GetInstructionClass(Inst);
230319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const Value *Arg = 0;
230419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
230519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (Class) {
230619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_Release: {
230719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Arg = GetObjCArg(Inst);
230819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
230919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PtrState &S = MyStates.getPtrBottomUpState(Arg);
231019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
231119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If we see two releases in a row on the same pointer. If so, make
231219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // a note, and we'll cicle back to revisit it after we've
231319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // hopefully eliminated the second release, which may allow us to
231419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // eliminate the first release too.
231519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Theoretically we could implement removal of nested retain+release
231619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // pairs by making PtrState hold a stack of states, but this is
231719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // simple and avoids adding overhead for the non-nested case.
231819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (S.GetSeq() == S_Release || S.GetSeq() == S_MovableRelease)
231919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        NestingDetected = true;
232019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
232119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.SetSeqToRelease(Inst->getMetadata(ImpreciseReleaseMDKind));
232219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.RRI.clear();
232319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.RRI.KnownSafe = S.IsKnownNested() || S.IsKnownIncremented();
232419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.RRI.IsTailCallRelease = cast<CallInst>(Inst)->isTailCall();
232519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.RRI.Calls.insert(Inst);
232619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
232719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.IncrementRefCount();
232819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.IncrementNestCount();
232919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
233019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
233119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_RetainBlock:
233219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_Retain:
233319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_RetainRV: {
233419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Arg = GetObjCArg(Inst);
233519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
233619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PtrState &S = MyStates.getPtrBottomUpState(Arg);
233719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.DecrementRefCount();
233819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.SetAtLeastOneRefCount();
233919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.DecrementNestCount();
234019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
234119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // An objc_retainBlock call with just a use still needs to be kept,
234219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // because it may be copying a block from the stack to the heap.
234319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Class == IC_RetainBlock && S.GetSeq() == S_Use)
234419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.SetSeq(S_CanRelease);
234519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
234619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (S.GetSeq()) {
234719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Stop:
234819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Release:
234919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_MovableRelease:
235019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Use:
235119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.RRI.ReverseInsertPts.clear();
235219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // FALL THROUGH
235319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_CanRelease:
235419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Don't do retain+release tracking for IC_RetainRV, because it's
235519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // better to let it remain as the first instruction after a call.
235619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Class != IC_RetainRV) {
235719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          S.RRI.IsRetainBlock = Class == IC_RetainBlock;
235819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Retains[Inst] = S.RRI;
235919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
236019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.ClearSequenceProgress();
236119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
236219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_None:
236319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
236419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Retain:
236519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        llvm_unreachable("bottom-up pointer in retain state!");
236619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
236719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
236819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
236919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_AutoreleasepoolPop:
237019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Conservatively, clear MyStates for all known pointers.
237119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MyStates.clearBottomUpPointers();
237219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
237319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_AutoreleasepoolPush:
237419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_None:
237519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // These are irrelevant.
237619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
237719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
237819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
237919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
238019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
238119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Consider any other possible effects of this instruction on each
238219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // pointer being tracked.
238319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (BBState::ptr_iterator MI = MyStates.bottom_up_ptr_begin(),
238419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ME = MyStates.bottom_up_ptr_end(); MI != ME; ++MI) {
238519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const Value *Ptr = MI->first;
238619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Ptr == Arg)
238719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue; // Handled above.
238819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PtrState &S = MI->second;
238919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Sequence Seq = S.GetSeq();
239019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
239119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Check for possible releases.
239219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (CanAlterRefCount(Inst, Ptr, PA, Class)) {
239319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.DecrementRefCount();
239419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        switch (Seq) {
239519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Use:
239619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          S.SetSeq(S_CanRelease);
239719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          continue;
239819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_CanRelease:
239919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Release:
240019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_MovableRelease:
240119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Stop:
240219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_None:
240319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
240419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Retain:
240519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          llvm_unreachable("bottom-up pointer in retain state!");
240619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
240719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
240819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
240919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Check for possible direct uses.
241019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (Seq) {
241119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Release:
241219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_MovableRelease:
241319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (CanUse(Inst, Ptr, PA, Class)) {
241419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          assert(S.RRI.ReverseInsertPts.empty());
241519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          S.RRI.ReverseInsertPts.insert(Inst);
241619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          S.SetSeq(S_Use);
241719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        } else if (Seq == S_Release &&
241819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   (Class == IC_User || Class == IC_CallOrUser)) {
241919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // Non-movable releases depend on any possible objc pointer use.
242019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          S.SetSeq(S_Stop);
242119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          assert(S.RRI.ReverseInsertPts.empty());
242219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          S.RRI.ReverseInsertPts.insert(Inst);
242319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
242419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
242519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Stop:
242619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (CanUse(Inst, Ptr, PA, Class))
242719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          S.SetSeq(S_Use);
242819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
242919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_CanRelease:
243019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Use:
243119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_None:
243219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
243319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Retain:
243419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        llvm_unreachable("bottom-up pointer in retain state!");
243519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
243619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
243719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
243819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
243919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return NestingDetected;
244019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
244119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
244219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool
244319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCOpt::VisitTopDown(BasicBlock *BB,
244419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         DenseMap<const BasicBlock *, BBState> &BBStates,
244519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         DenseMap<Value *, RRInfo> &Releases) {
244619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool NestingDetected = false;
244719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BBState &MyStates = BBStates[BB];
244819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
244919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Merge the states from each predecessor to compute the initial state
245019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // for the current block.
245119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const_pred_iterator PI(BB), PE(BB, false);
245219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (PI == PE)
245319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MyStates.SetAsEntry();
245419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else
245519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    do {
245619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const BasicBlock *Pred = *PI++;
245719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Pred == BB)
245819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
245919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      DenseMap<const BasicBlock *, BBState>::iterator I = BBStates.find(Pred);
246019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      assert(I != BBStates.end());
246119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If we haven't seen this node yet, then we've found a CFG cycle.
246219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Be optimistic here; it's CheckForCFGHazards' job detect trouble.
246319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!I->second.isVisitedTopDown())
246419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
246519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MyStates.InitFromPred(I->second);
246619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      while (PI != PE) {
246719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Pred = *PI++;
246819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Pred != BB) {
246919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          I = BBStates.find(Pred);
247019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          assert(I != BBStates.end());
247119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (I->second.isVisitedTopDown())
247219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            MyStates.MergePred(I->second);
247319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
247419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
247519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
247619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } while (PI != PE);
247719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
247819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Visit all the instructions, top-down.
247919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
248019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *Inst = I;
248119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InstructionClass Class = GetInstructionClass(Inst);
248219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const Value *Arg = 0;
248319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
248419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (Class) {
248519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_RetainBlock:
248619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_Retain:
248719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_RetainRV: {
248819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Arg = GetObjCArg(Inst);
248919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
249019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PtrState &S = MyStates.getPtrTopDownState(Arg);
249119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
249219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Don't do retain+release tracking for IC_RetainRV, because it's
249319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // better to let it remain as the first instruction after a call.
249419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Class != IC_RetainRV) {
249519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // If we see two retains in a row on the same pointer. If so, make
249619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // a note, and we'll cicle back to revisit it after we've
249719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // hopefully eliminated the second retain, which may allow us to
249819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // eliminate the first retain too.
249919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Theoretically we could implement removal of nested retain+release
250019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // pairs by making PtrState hold a stack of states, but this is
250119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // simple and avoids adding overhead for the non-nested case.
250219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (S.GetSeq() == S_Retain)
250319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          NestingDetected = true;
250419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
250519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.SetSeq(S_Retain);
250619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.RRI.clear();
250719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.RRI.IsRetainBlock = Class == IC_RetainBlock;
250819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Don't check S.IsKnownIncremented() here because it's not
250919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // sufficient.
251019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.RRI.KnownSafe = S.IsKnownNested();
251119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.RRI.Calls.insert(Inst);
251219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
251319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
251419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.SetAtLeastOneRefCount();
251519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.IncrementRefCount();
251619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.IncrementNestCount();
251719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
251819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
251919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_Release: {
252019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Arg = GetObjCArg(Inst);
252119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
252219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PtrState &S = MyStates.getPtrTopDownState(Arg);
252319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.DecrementRefCount();
252419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      S.DecrementNestCount();
252519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
252619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (S.GetSeq()) {
252719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Retain:
252819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_CanRelease:
252919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.RRI.ReverseInsertPts.clear();
253019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // FALL THROUGH
253119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Use:
253219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.RRI.ReleaseMetadata = Inst->getMetadata(ImpreciseReleaseMDKind);
253319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.RRI.IsTailCallRelease = cast<CallInst>(Inst)->isTailCall();
253419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Releases[Inst] = S.RRI;
253519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.ClearSequenceProgress();
253619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
253719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_None:
253819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
253919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Stop:
254019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Release:
254119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_MovableRelease:
254219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        llvm_unreachable("top-down pointer in release state!");
254319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
254419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
254519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
254619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_AutoreleasepoolPop:
254719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Conservatively, clear MyStates for all known pointers.
254819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      MyStates.clearTopDownPointers();
254919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
255019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_AutoreleasepoolPush:
255119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_None:
255219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // These are irrelevant.
255319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
255419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
255519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
255619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
255719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
255819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Consider any other possible effects of this instruction on each
255919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // pointer being tracked.
256019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (BBState::ptr_iterator MI = MyStates.top_down_ptr_begin(),
256119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         ME = MyStates.top_down_ptr_end(); MI != ME; ++MI) {
256219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const Value *Ptr = MI->first;
256319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Ptr == Arg)
256419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue; // Handled above.
256519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      PtrState &S = MI->second;
256619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Sequence Seq = S.GetSeq();
256719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
256819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Check for possible releases.
256919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (CanAlterRefCount(Inst, Ptr, PA, Class)) {
257019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        S.DecrementRefCount();
257119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        switch (Seq) {
257219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Retain:
257319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          S.SetSeq(S_CanRelease);
257419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          assert(S.RRI.ReverseInsertPts.empty());
257519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          S.RRI.ReverseInsertPts.insert(Inst);
257619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
257719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // One call can't cause a transition from S_Retain to S_CanRelease
257819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // and S_CanRelease to S_Use. If we've made the first transition,
257919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // we're done.
258019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          continue;
258119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Use:
258219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_CanRelease:
258319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_None:
258419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
258519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Stop:
258619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_Release:
258719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case S_MovableRelease:
258819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          llvm_unreachable("top-down pointer in release state!");
258919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
259019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
259119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
259219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Check for possible direct uses.
259319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (Seq) {
259419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_CanRelease:
259519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (CanUse(Inst, Ptr, PA, Class))
259619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          S.SetSeq(S_Use);
259719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
259819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Retain:
259919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // An objc_retainBlock call may be responsible for copying the block
260019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // data from the stack to the heap. Model this by moving it straight
260119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // from S_Retain to S_Use.
260219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (S.RRI.IsRetainBlock &&
260319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            CanUse(Inst, Ptr, PA, Class)) {
260419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          assert(S.RRI.ReverseInsertPts.empty());
260519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          S.RRI.ReverseInsertPts.insert(Inst);
260619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          S.SetSeq(S_Use);
260719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
260819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
260919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Use:
261019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_None:
261119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
261219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Stop:
261319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_Release:
261419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case S_MovableRelease:
261519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        llvm_unreachable("top-down pointer in release state!");
261619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
261719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
261819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
261919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
262019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CheckForCFGHazards(BB, BBStates, MyStates);
262119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return NestingDetected;
262219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
262319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
262419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// Visit - Visit the function both top-down and bottom-up.
262519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool
262619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCOpt::Visit(Function &F,
262719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                  DenseMap<const BasicBlock *, BBState> &BBStates,
262819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                  MapVector<Value *, RRInfo> &Retains,
262919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                  DenseMap<Value *, RRInfo> &Releases) {
263019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Use reverse-postorder on the reverse CFG for bottom-up, because we
263119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // magically know that loops will be well behaved, i.e. they won't repeatedly
263219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // call retain on a single pointer without doing a release. We can't use
263319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // ReversePostOrderTraversal here because we want to walk up from each
263419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // function exit point.
263519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallPtrSet<BasicBlock *, 16> Visited;
263619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<std::pair<BasicBlock *, pred_iterator>, 16> Stack;
263719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<BasicBlock *, 16> Order;
263819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
263919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BasicBlock *BB = I;
264019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (BB->getTerminator()->getNumSuccessors() == 0)
264119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Stack.push_back(std::make_pair(BB, pred_begin(BB)));
264219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
264319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (!Stack.empty()) {
264419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    pred_iterator End = pred_end(Stack.back().first);
264519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    while (Stack.back().second != End) {
264619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BasicBlock *BB = *Stack.back().second++;
264719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (Visited.insert(BB))
264819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Stack.push_back(std::make_pair(BB, pred_begin(BB)));
264919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
265019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Order.push_back(Stack.pop_back_val().first);
265119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
265219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool BottomUpNestingDetected = false;
265319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (SmallVectorImpl<BasicBlock *>::const_reverse_iterator I =
265419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         Order.rbegin(), E = Order.rend(); I != E; ++I) {
265519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BasicBlock *BB = *I;
265619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BottomUpNestingDetected |= VisitBottomUp(BB, BBStates, Retains);
265719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
265819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
265919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Use regular reverse-postorder for top-down.
266019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool TopDownNestingDetected = false;
266119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  typedef ReversePostOrderTraversal<Function *> RPOTType;
266219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RPOTType RPOT(&F);
266319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (RPOTType::rpo_iterator I = RPOT.begin(), E = RPOT.end(); I != E; ++I) {
266419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BasicBlock *BB = *I;
266519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    TopDownNestingDetected |= VisitTopDown(BB, BBStates, Releases);
266619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
266719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
266819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return TopDownNestingDetected && BottomUpNestingDetected;
266919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
267019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
267119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// MoveCalls - Move the calls in RetainsToMove and ReleasesToMove.
267219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ObjCARCOpt::MoveCalls(Value *Arg,
267319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           RRInfo &RetainsToMove,
267419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           RRInfo &ReleasesToMove,
267519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           MapVector<Value *, RRInfo> &Retains,
267619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           DenseMap<Value *, RRInfo> &Releases,
267719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           SmallVectorImpl<Instruction *> &DeadInsts,
267819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                           Module *M) {
267919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Type *ArgTy = Arg->getType();
268019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Type *ParamTy = PointerType::getUnqual(Type::getInt8Ty(ArgTy->getContext()));
268119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
268219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Insert the new retain and release calls.
268319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (SmallPtrSet<Instruction *, 2>::const_iterator
268419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       PI = ReleasesToMove.ReverseInsertPts.begin(),
268519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       PE = ReleasesToMove.ReverseInsertPts.end(); PI != PE; ++PI) {
268619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *InsertPt = *PI;
268719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Value *MyArg = ArgTy == ParamTy ? Arg :
268819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   new BitCastInst(Arg, ParamTy, "", InsertPt);
268919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CallInst *Call =
269019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      CallInst::Create(RetainsToMove.IsRetainBlock ?
269119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         getRetainBlockCallee(M) : getRetainCallee(M),
269219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       MyArg, "", InsertPt);
269319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Call->setDoesNotThrow();
269419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!RetainsToMove.IsRetainBlock)
269519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Call->setTailCall();
269619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
269719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (SmallPtrSet<Instruction *, 2>::const_iterator
269819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       PI = RetainsToMove.ReverseInsertPts.begin(),
269919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       PE = RetainsToMove.ReverseInsertPts.end(); PI != PE; ++PI) {
270019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *LastUse = *PI;
270119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *InsertPts[] = { 0, 0, 0 };
270219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (InvokeInst *II = dyn_cast<InvokeInst>(LastUse)) {
270319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // We can't insert code immediately after an invoke instruction, so
270419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // insert code at the beginning of both successor blocks instead.
270519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // The invoke's return value isn't available in the unwind block,
270619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // but our releases will never depend on it, because they must be
270719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // paired with retains from before the invoke.
270819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InsertPts[0] = II->getNormalDest()->getFirstInsertionPt();
270919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InsertPts[1] = II->getUnwindDest()->getFirstInsertionPt();
271019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
271119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Insert code immediately after the last use.
271219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InsertPts[0] = llvm::next(BasicBlock::iterator(LastUse));
271319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
271419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
271519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (Instruction **I = InsertPts; *I; ++I) {
271619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Instruction *InsertPt = *I;
271719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Value *MyArg = ArgTy == ParamTy ? Arg :
271819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     new BitCastInst(Arg, ParamTy, "", InsertPt);
271919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      CallInst *Call = CallInst::Create(getReleaseCallee(M), MyArg,
272019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                        "", InsertPt);
272119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Attach a clang.imprecise_release metadata tag, if appropriate.
272219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (MDNode *M = ReleasesToMove.ReleaseMetadata)
272319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Call->setMetadata(ImpreciseReleaseMDKind, M);
272419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Call->setDoesNotThrow();
272519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (ReleasesToMove.IsTailCallRelease)
272619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Call->setTailCall();
272719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
272819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
272919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
273019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Delete the original retain and release calls.
273119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (SmallPtrSet<Instruction *, 2>::const_iterator
273219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       AI = RetainsToMove.Calls.begin(),
273319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       AE = RetainsToMove.Calls.end(); AI != AE; ++AI) {
273419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *OrigRetain = *AI;
273519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Retains.blot(OrigRetain);
273619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DeadInsts.push_back(OrigRetain);
273719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
273819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (SmallPtrSet<Instruction *, 2>::const_iterator
273919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       AI = ReleasesToMove.Calls.begin(),
274019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       AE = ReleasesToMove.Calls.end(); AI != AE; ++AI) {
274119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *OrigRelease = *AI;
274219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Releases.erase(OrigRelease);
274319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DeadInsts.push_back(OrigRelease);
274419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
274519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
274619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
274719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool
274819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCOpt::PerformCodePlacement(DenseMap<const BasicBlock *, BBState>
274919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                   &BBStates,
275019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 MapVector<Value *, RRInfo> &Retains,
275119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 DenseMap<Value *, RRInfo> &Releases,
275219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                 Module *M) {
275319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool AnyPairsCompletelyEliminated = false;
275419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RRInfo RetainsToMove;
275519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RRInfo ReleasesToMove;
275619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<Instruction *, 4> NewRetains;
275719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<Instruction *, 4> NewReleases;
275819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallVector<Instruction *, 8> DeadInsts;
275919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
276019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (MapVector<Value *, RRInfo>::const_iterator I = Retains.begin(),
276119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman       E = Retains.end(); I != E; ++I) {
276219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Value *V = I->first;
276319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!V) continue; // blotted
276419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
276519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *Retain = cast<Instruction>(V);
276619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Value *Arg = GetObjCArg(Retain);
276719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
276819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // If the object being released is in static storage, we know it's
276919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // not being managed by ObjC reference counting, so we can delete pairs
277019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // regardless of what possible decrements or uses lie between them.
277119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool KnownSafe = isa<Constant>(Arg);
277219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
277319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Same for stack storage, unless this is an objc_retainBlock call,
277419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // which is responsible for copying the block data from the stack to
277519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // the heap.
277619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!I->second.IsRetainBlock && isa<AllocaInst>(Arg))
277719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      KnownSafe = true;
277819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
277919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // A constant pointer can't be pointing to an object on the heap. It may
278019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // be reference-counted, but it won't be deleted.
278119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (const LoadInst *LI = dyn_cast<LoadInst>(Arg))
278219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (const GlobalVariable *GV =
278319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            dyn_cast<GlobalVariable>(
278419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              StripPointerCastsAndObjCCalls(LI->getPointerOperand())))
278519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (GV->isConstant())
278619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          KnownSafe = true;
278719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
278819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // If a pair happens in a region where it is known that the reference count
278919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // is already incremented, we can similarly ignore possible decrements.
279019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool KnownSafeTD = true, KnownSafeBU = true;
279119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
279219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Connect the dots between the top-down-collected RetainsToMove and
279319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // bottom-up-collected ReleasesToMove to form sets of related calls.
279419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // This is an iterative process so that we connect multiple releases
279519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // to multiple retains if needed.
279619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned OldDelta = 0;
279719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned NewDelta = 0;
279819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned OldCount = 0;
279919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    unsigned NewCount = 0;
280019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool FirstRelease = true;
280119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool FirstRetain = true;
280219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NewRetains.push_back(Retain);
280319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (;;) {
280419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (SmallVectorImpl<Instruction *>::const_iterator
280519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           NI = NewRetains.begin(), NE = NewRetains.end(); NI != NE; ++NI) {
280619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Instruction *NewRetain = *NI;
280719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        MapVector<Value *, RRInfo>::const_iterator It = Retains.find(NewRetain);
280819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        assert(It != Retains.end());
280919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        const RRInfo &NewRetainRRI = It->second;
281019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        KnownSafeTD &= NewRetainRRI.KnownSafe;
281119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        for (SmallPtrSet<Instruction *, 2>::const_iterator
281219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             LI = NewRetainRRI.Calls.begin(),
281319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             LE = NewRetainRRI.Calls.end(); LI != LE; ++LI) {
281419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Instruction *NewRetainRelease = *LI;
281519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          DenseMap<Value *, RRInfo>::const_iterator Jt =
281619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Releases.find(NewRetainRelease);
281719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (Jt == Releases.end())
281819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            goto next_retain;
281919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          const RRInfo &NewRetainReleaseRRI = Jt->second;
282019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          assert(NewRetainReleaseRRI.Calls.count(NewRetain));
282119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (ReleasesToMove.Calls.insert(NewRetainRelease)) {
282219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            OldDelta -=
282319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              BBStates[NewRetainRelease->getParent()].GetAllPathCount();
282419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
282519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            // Merge the ReleaseMetadata and IsTailCallRelease values.
282619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (FirstRelease) {
282719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              ReleasesToMove.ReleaseMetadata =
282819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                NewRetainReleaseRRI.ReleaseMetadata;
282919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              ReleasesToMove.IsTailCallRelease =
283019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                NewRetainReleaseRRI.IsTailCallRelease;
283119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              FirstRelease = false;
283219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            } else {
283319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              if (ReleasesToMove.ReleaseMetadata !=
283419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                    NewRetainReleaseRRI.ReleaseMetadata)
283519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                ReleasesToMove.ReleaseMetadata = 0;
283619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              if (ReleasesToMove.IsTailCallRelease !=
283719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                    NewRetainReleaseRRI.IsTailCallRelease)
283819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                ReleasesToMove.IsTailCallRelease = false;
283919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            }
284019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
284119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            // Collect the optimal insertion points.
284219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (!KnownSafe)
284319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              for (SmallPtrSet<Instruction *, 2>::const_iterator
284419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   RI = NewRetainReleaseRRI.ReverseInsertPts.begin(),
284519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   RE = NewRetainReleaseRRI.ReverseInsertPts.end();
284619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   RI != RE; ++RI) {
284719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                Instruction *RIP = *RI;
284819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                if (ReleasesToMove.ReverseInsertPts.insert(RIP))
284919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                  NewDelta -= BBStates[RIP->getParent()].GetAllPathCount();
285019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              }
285119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            NewReleases.push_back(NewRetainRelease);
285219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          }
285319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
285419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
285519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      NewRetains.clear();
285619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (NewReleases.empty()) break;
285719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
285819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Back the other way.
285919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (SmallVectorImpl<Instruction *>::const_iterator
286019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           NI = NewReleases.begin(), NE = NewReleases.end(); NI != NE; ++NI) {
286119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Instruction *NewRelease = *NI;
286219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DenseMap<Value *, RRInfo>::const_iterator It =
286319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Releases.find(NewRelease);
286419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        assert(It != Releases.end());
286519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        const RRInfo &NewReleaseRRI = It->second;
286619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        KnownSafeBU &= NewReleaseRRI.KnownSafe;
286719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        for (SmallPtrSet<Instruction *, 2>::const_iterator
286819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             LI = NewReleaseRRI.Calls.begin(),
286919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             LE = NewReleaseRRI.Calls.end(); LI != LE; ++LI) {
287019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Instruction *NewReleaseRetain = *LI;
287119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          MapVector<Value *, RRInfo>::const_iterator Jt =
287219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Retains.find(NewReleaseRetain);
287319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (Jt == Retains.end())
287419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            goto next_retain;
287519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          const RRInfo &NewReleaseRetainRRI = Jt->second;
287619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          assert(NewReleaseRetainRRI.Calls.count(NewRelease));
287719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (RetainsToMove.Calls.insert(NewReleaseRetain)) {
287819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            unsigned PathCount =
287919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              BBStates[NewReleaseRetain->getParent()].GetAllPathCount();
288019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            OldDelta += PathCount;
288119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            OldCount += PathCount;
288219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
288319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            // Merge the IsRetainBlock values.
288419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (FirstRetain) {
288519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              RetainsToMove.IsRetainBlock = NewReleaseRetainRRI.IsRetainBlock;
288619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              FirstRetain = false;
288719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            } else if (ReleasesToMove.IsRetainBlock !=
288819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       NewReleaseRetainRRI.IsRetainBlock)
288919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              // It's not possible to merge the sequences if one uses
289019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              // objc_retain and the other uses objc_retainBlock.
289119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              goto next_retain;
289219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
289319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            // Collect the optimal insertion points.
289419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (!KnownSafe)
289519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              for (SmallPtrSet<Instruction *, 2>::const_iterator
289619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   RI = NewReleaseRetainRRI.ReverseInsertPts.begin(),
289719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   RE = NewReleaseRetainRRI.ReverseInsertPts.end();
289819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   RI != RE; ++RI) {
289919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                Instruction *RIP = *RI;
290019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                if (RetainsToMove.ReverseInsertPts.insert(RIP)) {
290119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                  PathCount = BBStates[RIP->getParent()].GetAllPathCount();
290219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                  NewDelta += PathCount;
290319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                  NewCount += PathCount;
290419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                }
290519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              }
290619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            NewRetains.push_back(NewReleaseRetain);
290719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          }
290819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
290919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
291019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      NewReleases.clear();
291119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (NewRetains.empty()) break;
291219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
291319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
291419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // If the pointer is known incremented or nested, we can safely delete the
291519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // pair regardless of what's between them.
291619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (KnownSafeTD || KnownSafeBU) {
291719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      RetainsToMove.ReverseInsertPts.clear();
291819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ReleasesToMove.ReverseInsertPts.clear();
291919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      NewCount = 0;
292019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    } else {
292119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Determine whether the new insertion points we computed preserve the
292219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // balance of retain and release calls through the program.
292319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // TODO: If the fully aggressive solution isn't valid, try to find a
292419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // less aggressive solution which is.
292519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (NewDelta != 0)
292619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        goto next_retain;
292719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
292819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
292919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Determine whether the original call points are balanced in the retain and
293019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // release calls through the program. If not, conservatively don't touch
293119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // them.
293219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // TODO: It's theoretically possible to do code motion in this case, as
293319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // long as the existing imbalances are maintained.
293419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (OldDelta != 0)
293519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      goto next_retain;
293619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
293719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Ok, everything checks out and we're all set. Let's move some code!
293819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Changed = true;
293919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AnyPairsCompletelyEliminated = NewCount == 0;
294019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NumRRs += OldCount - NewCount;
294119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    MoveCalls(Arg, RetainsToMove, ReleasesToMove,
294219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              Retains, Releases, DeadInsts, M);
294319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
294419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  next_retain:
294519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NewReleases.clear();
294619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    NewRetains.clear();
294719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RetainsToMove.clear();
294819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ReleasesToMove.clear();
294919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
295019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
295119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Now that we're done moving everything, we can delete the newly dead
295219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // instructions, as we no longer need them as insert points.
295319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (!DeadInsts.empty())
295419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    EraseInstruction(DeadInsts.pop_back_val());
295519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
295619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return AnyPairsCompletelyEliminated;
295719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
295819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
295919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// OptimizeWeakCalls - Weak pointer optimizations.
296019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ObjCARCOpt::OptimizeWeakCalls(Function &F) {
296119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // First, do memdep-style RLE and S2L optimizations. We can't use memdep
296219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // itself because it uses AliasAnalysis and we need to do provenance
296319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // queries instead.
296419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) {
296519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *Inst = &*I++;
296619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InstructionClass Class = GetBasicInstructionClass(Inst);
296719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Class != IC_LoadWeak && Class != IC_LoadWeakRetained)
296819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
296919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
297019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Delete objc_loadWeak calls with no users.
297119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Class == IC_LoadWeak && Inst->use_empty()) {
297219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Inst->eraseFromParent();
297319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
297419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
297519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
297619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // TODO: For now, just look for an earlier available version of this value
297719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // within the same block. Theoretically, we could do memdep-style non-local
297819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // analysis too, but that would want caching. A better approach would be to
297919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // use the technique that EarlyCSE uses.
298019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    inst_iterator Current = llvm::prior(I);
298119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BasicBlock *CurrentBB = Current.getBasicBlockIterator();
298219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (BasicBlock::iterator B = CurrentBB->begin(),
298319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                              J = Current.getInstructionIterator();
298419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         J != B; --J) {
298519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Instruction *EarlierInst = &*llvm::prior(J);
298619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InstructionClass EarlierClass = GetInstructionClass(EarlierInst);
298719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      switch (EarlierClass) {
298819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case IC_LoadWeak:
298919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case IC_LoadWeakRetained: {
299019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // If this is loading from the same pointer, replace this load's value
299119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // with that one.
299219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CallInst *Call = cast<CallInst>(Inst);
299319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CallInst *EarlierCall = cast<CallInst>(EarlierInst);
299419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Value *Arg = Call->getArgOperand(0);
299519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Value *EarlierArg = EarlierCall->getArgOperand(0);
299619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        switch (PA.getAA()->alias(Arg, EarlierArg)) {
299719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case AliasAnalysis::MustAlias:
299819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Changed = true;
299919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // If the load has a builtin retain, insert a plain retain for it.
300019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (Class == IC_LoadWeakRetained) {
300119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            CallInst *CI =
300219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              CallInst::Create(getRetainCallee(F.getParent()), EarlierCall,
300319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               "", Call);
300419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            CI->setTailCall();
300519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          }
300619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // Zap the fully redundant load.
300719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Call->replaceAllUsesWith(EarlierCall);
300819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Call->eraseFromParent();
300919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          goto clobbered;
301019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case AliasAnalysis::MayAlias:
301119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case AliasAnalysis::PartialAlias:
301219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          goto clobbered;
301319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case AliasAnalysis::NoAlias:
301419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
301519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
301619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
301719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
301819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case IC_StoreWeak:
301919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case IC_InitWeak: {
302019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // If this is storing to the same pointer and has the same size etc.
302119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // replace this load's value with the stored value.
302219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CallInst *Call = cast<CallInst>(Inst);
302319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CallInst *EarlierCall = cast<CallInst>(EarlierInst);
302419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Value *Arg = Call->getArgOperand(0);
302519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Value *EarlierArg = EarlierCall->getArgOperand(0);
302619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        switch (PA.getAA()->alias(Arg, EarlierArg)) {
302719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case AliasAnalysis::MustAlias:
302819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Changed = true;
302919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // If the load has a builtin retain, insert a plain retain for it.
303019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (Class == IC_LoadWeakRetained) {
303119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            CallInst *CI =
303219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              CallInst::Create(getRetainCallee(F.getParent()), EarlierCall,
303319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               "", Call);
303419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            CI->setTailCall();
303519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          }
303619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // Zap the fully redundant load.
303719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Call->replaceAllUsesWith(EarlierCall->getArgOperand(1));
303819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Call->eraseFromParent();
303919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          goto clobbered;
304019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case AliasAnalysis::MayAlias:
304119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case AliasAnalysis::PartialAlias:
304219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          goto clobbered;
304319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case AliasAnalysis::NoAlias:
304419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          break;
304519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
304619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
304719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
304819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case IC_MoveWeak:
304919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case IC_CopyWeak:
305019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // TOOD: Grab the copied value.
305119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        goto clobbered;
305219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case IC_AutoreleasepoolPush:
305319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case IC_None:
305419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      case IC_User:
305519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Weak pointers are only modified through the weak entry points
305619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // (and arbitrary calls, which could call the weak entry points).
305719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
305819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      default:
305919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Anything else could modify the weak pointer.
306019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        goto clobbered;
306119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
306219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
306319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  clobbered:;
306419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
306519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
306619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Then, for each destroyWeak with an alloca operand, check to see if
306719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // the alloca and all its users can be zapped.
306819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) {
306919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *Inst = &*I++;
307019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InstructionClass Class = GetBasicInstructionClass(Inst);
307119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (Class != IC_DestroyWeak)
307219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
307319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
307419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CallInst *Call = cast<CallInst>(Inst);
307519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Value *Arg = Call->getArgOperand(0);
307619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (AllocaInst *Alloca = dyn_cast<AllocaInst>(Arg)) {
307719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (Value::use_iterator UI = Alloca->use_begin(),
307819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           UE = Alloca->use_end(); UI != UE; ++UI) {
307919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Instruction *UserInst = cast<Instruction>(*UI);
308019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        switch (GetBasicInstructionClass(UserInst)) {
308119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case IC_InitWeak:
308219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case IC_StoreWeak:
308319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        case IC_DestroyWeak:
308419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          continue;
308519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        default:
308619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          goto done;
308719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
308819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
308919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Changed = true;
309019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (Value::use_iterator UI = Alloca->use_begin(),
309119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           UE = Alloca->use_end(); UI != UE; ) {
309219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CallInst *UserInst = cast<CallInst>(*UI++);
309319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (!UserInst->use_empty())
309419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          UserInst->replaceAllUsesWith(UserInst->getOperand(1));
309519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        UserInst->eraseFromParent();
309619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
309719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Alloca->eraseFromParent();
309819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    done:;
309919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
310019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
310119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
310219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
310319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// OptimizeSequences - Identify program paths which execute sequences of
310419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// retains and releases which can be eliminated.
310519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ObjCARCOpt::OptimizeSequences(Function &F) {
310619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// Releases, Retains - These are used to store the results of the main flow
310719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// analysis. These use Value* as the key instead of Instruction* so that the
310819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// map stays valid when we get around to rewriting code and calls get
310919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// replaced by arguments.
311019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DenseMap<Value *, RRInfo> Releases;
311119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  MapVector<Value *, RRInfo> Retains;
311219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
311319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// BBStates, This is used during the traversal of the function to track the
311419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// states for each identified object at each block.
311519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DenseMap<const BasicBlock *, BBState> BBStates;
311619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
311719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Analyze the CFG of the function, and all instructions.
311819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  bool NestingDetected = Visit(F, BBStates, Retains, Releases);
311919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
312019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Transform.
312119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return PerformCodePlacement(BBStates, Retains, Releases, F.getParent()) &&
312219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         NestingDetected;
312319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
312419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
312519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// OptimizeReturns - Look for this pattern:
312619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///
312719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///    %call = call i8* @something(...)
312819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///    %2 = call i8* @objc_retain(i8* %call)
312919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///    %3 = call i8* @objc_autorelease(i8* %2)
313019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///    ret i8* %3
313119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///
313219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// And delete the retain and autorelease.
313319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///
313419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// Otherwise if it's just this:
313519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///
313619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///    %3 = call i8* @objc_autorelease(i8* %2)
313719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///    ret i8* %3
313819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman///
313919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// convert the autorelease to autoreleaseRV.
314019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ObjCARCOpt::OptimizeReturns(Function &F) {
314119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!F.getReturnType()->isPointerTy())
314219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return;
314319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
314419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallPtrSet<Instruction *, 4> DependingInstructions;
314519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallPtrSet<const BasicBlock *, 4> Visited;
314619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) {
314719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    BasicBlock *BB = FI;
314819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ReturnInst *Ret = dyn_cast<ReturnInst>(&BB->back());
314919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (!Ret) continue;
315019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
315119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const Value *Arg = StripPointerCastsAndObjCCalls(Ret->getOperand(0));
315219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FindDependencies(NeedsPositiveRetainCount, Arg,
315319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     BB, Ret, DependingInstructions, Visited, PA);
315419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (DependingInstructions.size() != 1)
315519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      goto next_block;
315619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
315719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    {
315819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      CallInst *Autorelease =
315919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        dyn_cast_or_null<CallInst>(*DependingInstructions.begin());
316019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!Autorelease)
316119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        goto next_block;
316219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      InstructionClass AutoreleaseClass =
316319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        GetBasicInstructionClass(Autorelease);
316419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!IsAutorelease(AutoreleaseClass))
316519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        goto next_block;
316619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (GetObjCArg(Autorelease) != Arg)
316719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        goto next_block;
316819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
316919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      DependingInstructions.clear();
317019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      Visited.clear();
317119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
317219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Check that there is nothing that can affect the reference
317319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // count between the autorelease and the retain.
317419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FindDependencies(CanChangeRetainCount, Arg,
317519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                       BB, Autorelease, DependingInstructions, Visited, PA);
317619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (DependingInstructions.size() != 1)
317719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        goto next_block;
317819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
317919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      {
318019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CallInst *Retain =
318119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          dyn_cast_or_null<CallInst>(*DependingInstructions.begin());
318219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
318319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Check that we found a retain with the same argument.
318419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (!Retain ||
318519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            !IsRetain(GetBasicInstructionClass(Retain)) ||
318619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            GetObjCArg(Retain) != Arg)
318719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          goto next_block;
318819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
318919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        DependingInstructions.clear();
319019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Visited.clear();
319119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
319219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Convert the autorelease to an autoreleaseRV, since it's
319319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // returning the value.
319419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (AutoreleaseClass == IC_Autorelease) {
319519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Autorelease->setCalledFunction(getAutoreleaseRVCallee(F.getParent()));
319619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          AutoreleaseClass = IC_AutoreleaseRV;
319719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
319819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
319919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Check that there is nothing that can affect the reference
320019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // count between the retain and the call.
320119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        // Note that Retain need not be in BB.
320219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        FindDependencies(CanChangeRetainCount, Arg, Retain->getParent(), Retain,
320319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         DependingInstructions, Visited, PA);
320419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (DependingInstructions.size() != 1)
320519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          goto next_block;
320619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
320719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        {
320819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          CallInst *Call =
320919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            dyn_cast_or_null<CallInst>(*DependingInstructions.begin());
321019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
321119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // Check that the pointer is the return value of the call.
321219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (!Call || Arg != Call)
321319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            goto next_block;
321419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
321519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // Check that the call is a regular call.
321619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          InstructionClass Class = GetBasicInstructionClass(Call);
321719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (Class != IC_CallOrUser && Class != IC_Call)
321819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            goto next_block;
321919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
322019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          // If so, we can zap the retain and autorelease.
322119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          Changed = true;
322219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          ++NumRets;
322319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          EraseInstruction(Retain);
322419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          EraseInstruction(Autorelease);
322519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        }
322619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
322719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
322819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
322919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  next_block:
323019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DependingInstructions.clear();
323119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Visited.clear();
323219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
323319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
323419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
323519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ObjCARCOpt::doInitialization(Module &M) {
323619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!EnableARCOpts)
323719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
323819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
323919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Run = ModuleHasARC(M);
324019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Run)
324119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
324219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
324319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Identify the imprecise release metadata kind.
324419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ImpreciseReleaseMDKind =
324519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    M.getContext().getMDKindID("clang.imprecise_release");
324619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
324719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Intuitively, objc_retain and others are nocapture, however in practice
324819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // they are not, because they return their argument value. And objc_release
324919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // calls finalizers.
325019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
325119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // These are initialized lazily.
325219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RetainRVCallee = 0;
325319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AutoreleaseRVCallee = 0;
325419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ReleaseCallee = 0;
325519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RetainCallee = 0;
325619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RetainBlockCallee = 0;
325719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AutoreleaseCallee = 0;
325819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
325919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
326019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
326119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
326219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ObjCARCOpt::runOnFunction(Function &F) {
326319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!EnableARCOpts)
326419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
326519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
326619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If nothing in the Module uses ARC, don't do anything.
326719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Run)
326819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
326919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
327019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Changed = false;
327119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
327219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  PA.setAA(&getAnalysis<AliasAnalysis>());
327319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
327419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // This pass performs several distinct transformations. As a compile-time aid
327519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // when compiling code that isn't ObjC, skip these if the relevant ObjC
327619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // library functions aren't declared.
327719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
327819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Preliminary optimizations. This also computs UsedInThisFunction.
327919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  OptimizeIndividualCalls(F);
328019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
328119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Optimizations for weak pointers.
328219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (UsedInThisFunction & ((1 << IC_LoadWeak) |
328319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            (1 << IC_LoadWeakRetained) |
328419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            (1 << IC_StoreWeak) |
328519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            (1 << IC_InitWeak) |
328619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            (1 << IC_CopyWeak) |
328719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            (1 << IC_MoveWeak) |
328819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            (1 << IC_DestroyWeak)))
328919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OptimizeWeakCalls(F);
329019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
329119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Optimizations for retain+release pairs.
329219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (UsedInThisFunction & ((1 << IC_Retain) |
329319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            (1 << IC_RetainRV) |
329419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                            (1 << IC_RetainBlock)))
329519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (UsedInThisFunction & (1 << IC_Release))
329619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Run OptimizeSequences until it either stops making changes or
329719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // no retain+release pair nesting is detected.
329819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      while (OptimizeSequences(F)) {}
329919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
330019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Optimizations if objc_autorelease is used.
330119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (UsedInThisFunction &
330219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ((1 << IC_Autorelease) | (1 << IC_AutoreleaseRV)))
330319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    OptimizeReturns(F);
330419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
330519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Changed;
330619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
330719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
330819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ObjCARCOpt::releaseMemory() {
330919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  PA.clear();
331019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
331119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
331219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
331319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// ARC contraction.
331419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman//===----------------------------------------------------------------------===//
331519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
331619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// TODO: ObjCARCContract could insert PHI nodes when uses aren't
331719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// dominated by single calls.
331819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
331919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Operator.h"
332019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/InlineAsm.h"
332119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Analysis/Dominators.h"
332219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
332319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSTATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed");
332419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
332519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumannamespace {
332619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// ObjCARCContract - Late ARC optimizations.  These change the IR in a way
332719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  /// that makes it difficult to be analyzed by ObjCARCOpt, so it's run late.
332819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  class ObjCARCContract : public FunctionPass {
332919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool Changed;
333019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AliasAnalysis *AA;
333119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DominatorTree *DT;
333219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ProvenanceAnalysis PA;
333319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
333419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// Run - A flag indicating whether this optimization pass should run.
333519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool Run;
333619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
333719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// StoreStrongCallee, etc. - Declarations for ObjC runtime
333819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// functions, for use in creating calls to them. These are initialized
333919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// lazily to avoid cluttering up the Module with unused declarations.
334019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *StoreStrongCallee,
334119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman             *RetainAutoreleaseCallee, *RetainAutoreleaseRVCallee;
334219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
334319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// RetainRVMarker - The inline asm string to insert between calls and
334419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    /// RetainRV calls to make the optimization work on targets which need it.
334519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const MDString *RetainRVMarker;
334619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
334719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getStoreStrongCallee(Module *M);
334819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getRetainAutoreleaseCallee(Module *M);
334919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Constant *getRetainAutoreleaseRVCallee(Module *M);
335019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
335119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    bool ContractAutorelease(Function &F, Instruction *Autorelease,
335219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             InstructionClass Class,
335319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             SmallPtrSet<Instruction *, 4>
335419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               &DependingInstructions,
335519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             SmallPtrSet<const BasicBlock *, 4>
335619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                               &Visited);
335719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
335819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    void ContractRelease(Instruction *Release,
335919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         inst_iterator &Iter);
336019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
336119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual void getAnalysisUsage(AnalysisUsage &AU) const;
336219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual bool doInitialization(Module &M);
336319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    virtual bool runOnFunction(Function &F);
336419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
336519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  public:
336619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    static char ID;
336719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ObjCARCContract() : FunctionPass(ID) {
336819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      initializeObjCARCContractPass(*PassRegistry::getPassRegistry());
336919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
337019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  };
337119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
337219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
337319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanchar ObjCARCContract::ID = 0;
337419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_BEGIN(ObjCARCContract,
337519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                      "objc-arc-contract", "ObjC ARC contraction", false, false)
337619bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_AG_DEPENDENCY(AliasAnalysis)
337719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_DEPENDENCY(DominatorTree)
337819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanINITIALIZE_PASS_END(ObjCARCContract,
337919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                    "objc-arc-contract", "ObjC ARC contraction", false, false)
338019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
338119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanPass *llvm::createObjCARCContractPass() {
338219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return new ObjCARCContract();
338319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
338419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
338519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ObjCARCContract::getAnalysisUsage(AnalysisUsage &AU) const {
338619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AU.addRequired<AliasAnalysis>();
338719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AU.addRequired<DominatorTree>();
338819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AU.setPreservesCFG();
338919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
339019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
339119bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *ObjCARCContract::getStoreStrongCallee(Module *M) {
339219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!StoreStrongCallee) {
339319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LLVMContext &C = M->getContext();
339419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
339519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type *I8XX = PointerType::getUnqual(I8X);
339619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::vector<Type *> Params;
339719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Params.push_back(I8XX);
339819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Params.push_back(I8X);
339919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
340019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AttrListPtr Attributes;
340119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Attributes.addAttr(~0u, Attribute::NoUnwind);
340219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Attributes.addAttr(1, Attribute::NoCapture);
340319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
340419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    StoreStrongCallee =
340519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      M->getOrInsertFunction(
340619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        "objc_storeStrong",
340719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        FunctionType::get(Type::getVoidTy(C), Params, /*isVarArg=*/false),
340819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Attributes);
340919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
341019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return StoreStrongCallee;
341119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
341219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
341319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *ObjCARCContract::getRetainAutoreleaseCallee(Module *M) {
341419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!RetainAutoreleaseCallee) {
341519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LLVMContext &C = M->getContext();
341619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
341719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::vector<Type *> Params;
341819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Params.push_back(I8X);
341919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FunctionType *FTy =
342019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FunctionType::get(I8X, Params, /*isVarArg=*/false);
342119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AttrListPtr Attributes;
342219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Attributes.addAttr(~0u, Attribute::NoUnwind);
342319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RetainAutoreleaseCallee =
342419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      M->getOrInsertFunction("objc_retainAutorelease", FTy, Attributes);
342519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
342619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return RetainAutoreleaseCallee;
342719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
342819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
342919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanConstant *ObjCARCContract::getRetainAutoreleaseRVCallee(Module *M) {
343019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!RetainAutoreleaseRVCallee) {
343119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    LLVMContext &C = M->getContext();
343219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
343319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    std::vector<Type *> Params;
343419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Params.push_back(I8X);
343519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FunctionType *FTy =
343619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      FunctionType::get(I8X, Params, /*isVarArg=*/false);
343719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    AttrListPtr Attributes;
343819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Attributes.addAttr(~0u, Attribute::NoUnwind);
343919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    RetainAutoreleaseRVCallee =
344019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      M->getOrInsertFunction("objc_retainAutoreleaseReturnValue", FTy,
344119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                             Attributes);
344219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
344319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return RetainAutoreleaseRVCallee;
344419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
344519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
344619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ContractAutorelease - Merge an autorelease with a retain into a fused
344719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// call.
344819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool
344919bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanObjCARCContract::ContractAutorelease(Function &F, Instruction *Autorelease,
345019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                     InstructionClass Class,
345119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                     SmallPtrSet<Instruction *, 4>
345219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       &DependingInstructions,
345319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                     SmallPtrSet<const BasicBlock *, 4>
345419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                       &Visited) {
345519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  const Value *Arg = GetObjCArg(Autorelease);
345619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
345719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Check that there are no instructions between the retain and the autorelease
345819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // (such as an autorelease_pop) which may change the count.
345919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CallInst *Retain = 0;
346019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Class == IC_AutoreleaseRV)
346119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FindDependencies(RetainAutoreleaseRVDep, Arg,
346219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     Autorelease->getParent(), Autorelease,
346319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     DependingInstructions, Visited, PA);
346419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else
346519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    FindDependencies(RetainAutoreleaseDep, Arg,
346619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     Autorelease->getParent(), Autorelease,
346719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     DependingInstructions, Visited, PA);
346819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
346919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Visited.clear();
347019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (DependingInstructions.size() != 1) {
347119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    DependingInstructions.clear();
347219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
347319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
347419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
347519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Retain = dyn_cast_or_null<CallInst>(*DependingInstructions.begin());
347619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DependingInstructions.clear();
347719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
347819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Retain ||
347919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      GetBasicInstructionClass(Retain) != IC_Retain ||
348019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      GetObjCArg(Retain) != Arg)
348119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
348219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
348319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Changed = true;
348419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++NumPeeps;
348519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
348619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Class == IC_AutoreleaseRV)
348719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Retain->setCalledFunction(getRetainAutoreleaseRVCallee(F.getParent()));
348819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  else
348919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Retain->setCalledFunction(getRetainAutoreleaseCallee(F.getParent()));
349019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
349119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  EraseInstruction(Autorelease);
349219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return true;
349319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
349419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
349519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ContractRelease - Attempt to merge an objc_release with a store, load, and
349619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// objc_retain to form an objc_storeStrong. This can be a little tricky because
349719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// the instructions don't always appear in order, and there may be unrelated
349819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// intervening instructions.
349919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid ObjCARCContract::ContractRelease(Instruction *Release,
350019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                      inst_iterator &Iter) {
350119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  LoadInst *Load = dyn_cast<LoadInst>(GetObjCArg(Release));
350219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Load || !Load->isSimple()) return;
350319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
350419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // For now, require everything to be in one basic block.
350519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock *BB = Release->getParent();
350619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Load->getParent() != BB) return;
350719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
350819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Walk down to find the store.
350919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock::iterator I = Load, End = BB->end();
351019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++I;
351119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AliasAnalysis::Location Loc = AA->getLocation(Load);
351219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (I != End &&
351319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman         (&*I == Release ||
351419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          IsRetain(GetBasicInstructionClass(I)) ||
351519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          !(AA->getModRefInfo(I, Loc) & AliasAnalysis::Mod)))
351619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    ++I;
351719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StoreInst *Store = dyn_cast<StoreInst>(I);
351819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Store || !Store->isSimple()) return;
351919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Store->getPointerOperand() != Loc.Ptr) return;
352019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
352119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Value *New = StripPointerCastsAndObjCCalls(Store->getValueOperand());
352219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
352319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Walk up to find the retain.
352419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  I = Store;
352519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  BasicBlock::iterator Begin = BB->begin();
352619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  while (I != Begin && GetBasicInstructionClass(I) != IC_Retain)
352719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    --I;
352819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Instruction *Retain = I;
352919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (GetBasicInstructionClass(Retain) != IC_Retain) return;
353019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (GetObjCArg(Retain) != New) return;
353119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
353219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Changed = true;
353319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  ++NumStoreStrongs;
353419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
353519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  LLVMContext &C = Release->getContext();
353619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
353719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Type *I8XX = PointerType::getUnqual(I8X);
353819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
353919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Value *Args[] = { Load->getPointerOperand(), New };
354019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Args[0]->getType() != I8XX)
354119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Args[0] = new BitCastInst(Args[0], I8XX, "", Store);
354219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Args[1]->getType() != I8X)
354319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Args[1] = new BitCastInst(Args[1], I8X, "", Store);
354419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  CallInst *StoreStrong =
354519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    CallInst::Create(getStoreStrongCallee(BB->getParent()->getParent()),
354619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                     Args, "", Store);
354719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StoreStrong->setDoesNotThrow();
354819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StoreStrong->setDebugLoc(Store->getDebugLoc());
354919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
355019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (&*Iter == Store) ++Iter;
355119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Store->eraseFromParent();
355219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Release->eraseFromParent();
355319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  EraseInstruction(Retain);
355419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (Load->use_empty())
355519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Load->eraseFromParent();
355619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
355719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
355819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ObjCARCContract::doInitialization(Module &M) {
355919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Run = ModuleHasARC(M);
356019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Run)
356119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
356219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
356319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // These are initialized lazily.
356419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  StoreStrongCallee = 0;
356519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RetainAutoreleaseCallee = 0;
356619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RetainAutoreleaseRVCallee = 0;
356719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
356819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // Initialize RetainRVMarker.
356919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  RetainRVMarker = 0;
357019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (NamedMDNode *NMD =
357119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        M.getNamedMetadata("clang.arc.retainAutoreleasedReturnValueMarker"))
357219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    if (NMD->getNumOperands() == 1) {
357319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      const MDNode *N = NMD->getOperand(0);
357419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (N->getNumOperands() == 1)
357519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (const MDString *S = dyn_cast<MDString>(N->getOperand(0)))
357619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          RetainRVMarker = S;
357719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
357819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
357919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return false;
358019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
358119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
358219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanbool ObjCARCContract::runOnFunction(Function &F) {
358319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!EnableARCOpts)
358419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
358519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
358619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // If nothing in the Module uses ARC, don't do anything.
358719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  if (!Run)
358819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    return false;
358919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
359019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  Changed = false;
359119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  AA = &getAnalysis<AliasAnalysis>();
359219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  DT = &getAnalysis<DominatorTree>();
359319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
359419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  PA.setAA(&getAnalysis<AliasAnalysis>());
359519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
359619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // For ObjC library calls which return their argument, replace uses of the
359719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // argument with uses of the call return value, if it dominates the use. This
359819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  // reduces register pressure.
359919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallPtrSet<Instruction *, 4> DependingInstructions;
360019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  SmallPtrSet<const BasicBlock *, 4> Visited;
360119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) {
360219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    Instruction *Inst = &*I++;
360319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
360419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Only these library routines return their argument. In particular,
360519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // objc_retainBlock does not necessarily return its argument.
360619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    InstructionClass Class = GetBasicInstructionClass(Inst);
360719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    switch (Class) {
360819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_Retain:
360919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_FusedRetainAutorelease:
361019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_FusedRetainAutoreleaseRV:
361119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
361219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_Autorelease:
361319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_AutoreleaseRV:
361419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (ContractAutorelease(F, Inst, Class, DependingInstructions, Visited))
361519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        continue;
361619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
361719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_RetainRV: {
361819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If we're compiling for a target which needs a special inline-asm
361919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // marker to do the retainAutoreleasedReturnValue optimization,
362019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // insert it now.
362119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!RetainRVMarker)
362219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
362319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      BasicBlock::iterator BBI = Inst;
362419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      --BBI;
362519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      while (isNoopInstruction(BBI)) --BBI;
362619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (&*BBI == GetObjCArg(Inst)) {
362719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        InlineAsm *IA =
362819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          InlineAsm::get(FunctionType::get(Type::getVoidTy(Inst->getContext()),
362919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                           /*isVarArg=*/false),
363019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         RetainRVMarker->getString(),
363119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                         /*Constraints=*/"", /*hasSideEffects=*/true);
363219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CallInst::Create(IA, "", Inst);
363319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
363419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      break;
363519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
363619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_InitWeak: {
363719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // objc_initWeak(p, null) => *p = null
363819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      CallInst *CI = cast<CallInst>(Inst);
363919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (isNullOrUndef(CI->getArgOperand(1))) {
364019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Value *Null =
364119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          ConstantPointerNull::get(cast<PointerType>(CI->getType()));
364219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Changed = true;
364319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        new StoreInst(Null, CI->getArgOperand(0), CI);
364419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CI->replaceAllUsesWith(Null);
364519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        CI->eraseFromParent();
364619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
364719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
364819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
364919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    case IC_Release:
365019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      ContractRelease(Inst, I);
365119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
365219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    default:
365319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      continue;
365419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
365519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
365619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // Don't use GetObjCArg because we don't want to look through bitcasts
365719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    // and such; to do the replacement, the argument must have type i8*.
365819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    const Value *Arg = cast<CallInst>(Inst)->getArgOperand(0);
365919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    for (;;) {
366019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If we're compiling bugpointed code, don't get in trouble.
366119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
366219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
366319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // Look through the uses of the pointer.
366419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      for (Value::const_use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
366519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman           UI != UE; ) {
366619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Use &U = UI.getUse();
366719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        unsigned OperandNo = UI.getOperandNo();
366819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        ++UI; // Increment UI now, because we may unlink its element.
366919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        if (Instruction *UserInst = dyn_cast<Instruction>(U.getUser()))
367019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          if (Inst != UserInst && DT->dominates(Inst, UserInst)) {
367119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Changed = true;
367219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Instruction *Replacement = Inst;
367319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            Type *UseTy = U.get()->getType();
367419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            if (PHINode *PHI = dyn_cast<PHINode>(UserInst)) {
367519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              // For PHI nodes, insert the bitcast in the predecessor block.
367619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              unsigned ValNo =
367719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                PHINode::getIncomingValueNumForOperand(OperandNo);
367819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              BasicBlock *BB =
367919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                PHI->getIncomingBlock(ValNo);
368019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              if (Replacement->getType() != UseTy)
368119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                Replacement = new BitCastInst(Replacement, UseTy, "",
368219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                                              &BB->back());
368319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              for (unsigned i = 0, e = PHI->getNumIncomingValues();
368419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                   i != e; ++i)
368519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                if (PHI->getIncomingBlock(i) == BB) {
368619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                  // Keep the UI iterator valid.
368719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                  if (&PHI->getOperandUse(
368819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        PHINode::getOperandNumForIncomingValue(i)) ==
368919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                        &UI.getUse())
369019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                    ++UI;
369119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                  PHI->setIncomingValue(i, Replacement);
369219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                }
369319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            } else {
369419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              if (Replacement->getType() != UseTy)
369519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman                Replacement = new BitCastInst(Replacement, UseTy, "", UserInst);
369619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman              U.set(Replacement);
369719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman            }
369819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman          }
369919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      }
370019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
370119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // If Arg is a no-op casted pointer, strip one level of casts and
370219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      // iterate.
370319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg))
370419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Arg = BI->getOperand(0);
370519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else if (isa<GEPOperator>(Arg) &&
370619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               cast<GEPOperator>(Arg)->hasAllZeroIndices())
370719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Arg = cast<GEPOperator>(Arg)->getPointerOperand();
370819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else if (isa<GlobalAlias>(Arg) &&
370919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman               !cast<GlobalAlias>(Arg)->mayBeOverridden())
371019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        Arg = cast<GlobalAlias>(Arg)->getAliasee();
371119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman      else
371219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman        break;
371319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman    }
371419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  }
371519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman
371619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman  return Changed;
371719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman}
3718