124c4898973a074713201fb9351d302b9f7733e92Michael Gottesman//===- ObjCARCOpts.cpp - ObjC ARC Optimization ----------------------------===//
29fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall//
39fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall//                     The LLVM Compiler Infrastructure
49fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall//
59fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// This file is distributed under the University of Illinois Open Source
69fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// License. See LICENSE.TXT for details.
79fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall//
89fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall//===----------------------------------------------------------------------===//
981c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// \file
1081c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// This file defines ObjC ARC optimizations. ARC stands for Automatic
1181c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// Reference Counting and is a system for managing reference counts for objects
1281c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// in Objective C.
1381c6121699a66b3e84f7b794b375095a39584701Michael Gottesman///
1481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// The optimizations performed include elimination of redundant, partially
1581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// redundant, and inconsequential reference count operations, elimination of
1665c46b0cff2a7bcefff9b58895cdf8d710e3b6f7Michael Gottesman/// redundant weak pointer operations, and numerous minor simplifications.
1781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman///
1881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// WARNING: This file knows about certain library functions. It recognizes them
1981c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// by name, and hardwires knowledge of their semantics.
2081c6121699a66b3e84f7b794b375095a39584701Michael Gottesman///
2181c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// WARNING: This file knows about how certain Objective-C library functions are
2281c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// used. Naive LLVM IR transformations which would otherwise be
2381c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// behavior-preserving may break these assumptions.
2481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman///
259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall//===----------------------------------------------------------------------===//
269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
276504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#define DEBUG_TYPE "objc-arc-opts"
286504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesman#include "ObjCARC.h"
297a7102d17f979918042bc040e27288d64a6bea5fMichael Gottesman#include "DependencyAnalysis.h"
306086847bfbc538b99305b4d7e0a53ab610f6a9bbMichael Gottesman#include "ObjCARCAliasAnalysis.h"
313a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "ProvenanceAnalysis.h"
329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall#include "llvm/ADT/DenseMap.h"
333c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman#include "llvm/ADT/STLExtras.h"
343a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "llvm/ADT/SmallPtrSet.h"
357a7102d17f979918042bc040e27288d64a6bea5fMichael Gottesman#include "llvm/ADT/Statistic.h"
367a7102d17f979918042bc040e27288d64a6bea5fMichael Gottesman#include "llvm/IR/LLVMContext.h"
373a57c37964adfbbf83b4b309a2ceda43ba6d8231Michael Gottesman#include "llvm/Support/CFG.h"
389ab758b9bc2fe51af6dabbdeb30f4a2e600bdcd0Michael Gottesman#include "llvm/Support/Debug.h"
3909840daeefc1aa8760c535ded6a37eb4f8cd4eaaTimur Iskhodzhanov#include "llvm/Support/raw_ostream.h"
403c67f1cd94760f879e0ec5407f0d1078bc51f9b4Michael Gottesman
419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallusing namespace llvm;
426504255a2257c53df8ab191c1db4517139f5dc8cMichael Gottesmanusing namespace llvm::objcarc;
439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
4481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// \defgroup MiscUtils Miscellaneous utilities that are not ARC specific.
4581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// @{
469fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
479fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallnamespace {
4881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  /// \brief An associative container with fast insertion-order (deterministic)
4981c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  /// iteration over its elements. Plus the special blot operation.
509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  template<class KeyT, class ValueT>
519fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  class MapVector {
5281c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Map keys to indices in Vector.
539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    typedef DenseMap<KeyT, size_t> MapTy;
549fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    MapTy Map;
559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    typedef std::vector<std::pair<KeyT, ValueT> > VectorTy;
5781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Keys and values.
589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    VectorTy Vector;
599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  public:
619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    typedef typename VectorTy::iterator iterator;
629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    typedef typename VectorTy::const_iterator const_iterator;
639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    iterator begin() { return Vector.begin(); }
649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    iterator end() { return Vector.end(); }
659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    const_iterator begin() const { return Vector.begin(); }
669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    const_iterator end() const { return Vector.end(); }
679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall#ifdef XDEBUG
699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ~MapVector() {
709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      assert(Vector.size() >= Map.size()); // May differ due to blotting.
719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      for (typename MapTy::const_iterator I = Map.begin(), E = Map.end();
729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall           I != E; ++I) {
739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        assert(I->second < Vector.size());
749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        assert(Vector[I->second].first == I->first);
759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
769fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      for (typename VectorTy::const_iterator I = Vector.begin(),
779fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall           E = Vector.end(); I != E; ++I)
789fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        assert(!I->first ||
799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall               (Map.count(I->first) &&
809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                Map[I->first] == size_t(I - Vector.begin())));
819fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall#endif
839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
8422cc4ccc9ea4a45d1f529c1bf48d61a88d3615deDan Gohman    ValueT &operator[](const KeyT &Arg) {
859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      std::pair<typename MapTy::iterator, bool> Pair =
869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Map.insert(std::make_pair(Arg, size_t(0)));
879fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (Pair.second) {
8822cc4ccc9ea4a45d1f529c1bf48d61a88d3615deDan Gohman        size_t Num = Vector.size();
8922cc4ccc9ea4a45d1f529c1bf48d61a88d3615deDan Gohman        Pair.first->second = Num;
909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Vector.push_back(std::make_pair(Arg, ValueT()));
9122cc4ccc9ea4a45d1f529c1bf48d61a88d3615deDan Gohman        return Vector[Num].second;
929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return Vector[Pair.first->second].second;
949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    std::pair<iterator, bool>
979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    insert(const std::pair<KeyT, ValueT> &InsertPair) {
989fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      std::pair<typename MapTy::iterator, bool> Pair =
999fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Map.insert(std::make_pair(InsertPair.first, size_t(0)));
1009fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (Pair.second) {
10122cc4ccc9ea4a45d1f529c1bf48d61a88d3615deDan Gohman        size_t Num = Vector.size();
10222cc4ccc9ea4a45d1f529c1bf48d61a88d3615deDan Gohman        Pair.first->second = Num;
1039fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Vector.push_back(InsertPair);
10422cc4ccc9ea4a45d1f529c1bf48d61a88d3615deDan Gohman        return std::make_pair(Vector.begin() + Num, true);
1059fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
1069fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return std::make_pair(Vector.begin() + Pair.first->second, false);
1079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
1089fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
10922cc4ccc9ea4a45d1f529c1bf48d61a88d3615deDan Gohman    const_iterator find(const KeyT &Key) const {
1109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      typename MapTy::const_iterator It = Map.find(Key);
1119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (It == Map.end()) return Vector.end();
1129fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return Vector.begin() + It->second;
1139fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
1149fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
11581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// This is similar to erase, but instead of removing the element from the
11681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// vector, it just zeros out the key in the vector. This leaves iterators
11781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// intact, but clients must be prepared for zeroed-out keys when iterating.
11822cc4ccc9ea4a45d1f529c1bf48d61a88d3615deDan Gohman    void blot(const KeyT &Key) {
1199fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      typename MapTy::iterator It = Map.find(Key);
1209fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (It == Map.end()) return;
1219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Vector[It->second].first = KeyT();
1229fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Map.erase(It);
1239fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
1249fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
1259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void clear() {
1269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Map.clear();
1279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Vector.clear();
1289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
1299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  };
1309fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
1319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
13281c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// @}
13381c6121699a66b3e84f7b794b375095a39584701Michael Gottesman///
13481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// \defgroup ARCUtilities Utility declarations/definitions specific to ARC.
13581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// @{
1369fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
13781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// \brief This is similar to StripPointerCastsAndObjCCalls but it stops as soon
13881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// as it finds a value with multiple uses.
1399fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallstatic const Value *FindSingleUseIdentifiedObject(const Value *Arg) {
1409fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (Arg->hasOneUse()) {
1419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (const BitCastInst *BC = dyn_cast<BitCastInst>(Arg))
1429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return FindSingleUseIdentifiedObject(BC->getOperand(0));
1439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(Arg))
1449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (GEP->hasAllZeroIndices())
1459fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        return FindSingleUseIdentifiedObject(GEP->getPointerOperand());
1469fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (IsForwarding(GetBasicInstructionClass(Arg)))
1479fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return FindSingleUseIdentifiedObject(
1489fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall               cast<CallInst>(Arg)->getArgOperand(0));
1499fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (!IsObjCIdentifiedObject(Arg))
1509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return 0;
1519fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    return Arg;
1529fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
1539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
1540daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman  // If we found an identifiable object but it has multiple uses, but they are
1550daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman  // trivial uses, we can still consider this to be a single-use value.
1569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (IsObjCIdentifiedObject(Arg)) {
1579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    for (Value::const_use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
1589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall         UI != UE; ++UI) {
1599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      const User *U = *UI;
1609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (!U->use_empty() || StripPointerCastsAndObjCCalls(U) != Arg)
1619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall         return 0;
1629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
1639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
1649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    return Arg;
1659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
1669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
1679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return 0;
1689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
1699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
17082b83011a1e330e41147dbad97e44939840ba755Michael Gottesman/// \brief Test whether the given retainable object pointer escapes.
17181c6121699a66b3e84f7b794b375095a39584701Michael Gottesman///
17281c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// This differs from regular escape analysis in that a use as an
17381c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// argument to a call is not considered an escape.
17481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman///
17582b83011a1e330e41147dbad97e44939840ba755Michael Gottesmanstatic bool DoesRetainableObjPtrEscape(const User *Ptr) {
17682b83011a1e330e41147dbad97e44939840ba755Michael Gottesman  DEBUG(dbgs() << "DoesRetainableObjPtrEscape: Target: " << *Ptr << "\n");
177981308cffbfd1f77750452015f6e6f0f053e11d4Michael Gottesman
17879522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  // Walk the def-use chains.
17979522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  SmallVector<const Value *, 4> Worklist;
18082b83011a1e330e41147dbad97e44939840ba755Michael Gottesman  Worklist.push_back(Ptr);
18182b83011a1e330e41147dbad97e44939840ba755Michael Gottesman  // If Ptr has any operands add them as well.
18202c953ea8b8130bd60fdacb97649d6344f1e8143Michael Gottesman  for (User::const_op_iterator I = Ptr->op_begin(), E = Ptr->op_end(); I != E;
18302c953ea8b8130bd60fdacb97649d6344f1e8143Michael Gottesman       ++I) {
18482b83011a1e330e41147dbad97e44939840ba755Michael Gottesman    Worklist.push_back(*I);
18582b83011a1e330e41147dbad97e44939840ba755Michael Gottesman  }
1866056b85bb5e863f3b174ed21bd70e22a03ed61f7Michael Gottesman
1876056b85bb5e863f3b174ed21bd70e22a03ed61f7Michael Gottesman  // Ensure we do not visit any value twice.
18882b83011a1e330e41147dbad97e44939840ba755Michael Gottesman  SmallPtrSet<const Value *, 8> VisitedSet;
1896056b85bb5e863f3b174ed21bd70e22a03ed61f7Michael Gottesman
19079522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  do {
19179522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman    const Value *V = Worklist.pop_back_val();
192981308cffbfd1f77750452015f6e6f0f053e11d4Michael Gottesman
19382b83011a1e330e41147dbad97e44939840ba755Michael Gottesman    DEBUG(dbgs() << "DoesRetainableObjPtrEscape: Visiting: " << *V << "\n");
194981308cffbfd1f77750452015f6e6f0f053e11d4Michael Gottesman
19579522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman    for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end();
19679522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman         UI != UE; ++UI) {
19779522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman      const User *UUser = *UI;
198981308cffbfd1f77750452015f6e6f0f053e11d4Michael Gottesman
19982b83011a1e330e41147dbad97e44939840ba755Michael Gottesman      DEBUG(dbgs() << "DoesRetainableObjPtrEscape: User: " << *UUser << "\n");
200981308cffbfd1f77750452015f6e6f0f053e11d4Michael Gottesman
20179522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman      // Special - Use by a call (callee or argument) is not considered
20279522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman      // to be an escape.
20344234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman      switch (GetBasicInstructionClass(UUser)) {
20444234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman      case IC_StoreWeak:
20544234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman      case IC_InitWeak:
20644234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman      case IC_StoreStrong:
20744234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman      case IC_Autorelease:
208981308cffbfd1f77750452015f6e6f0f053e11d4Michael Gottesman      case IC_AutoreleaseRV: {
20902c953ea8b8130bd60fdacb97649d6344f1e8143Michael Gottesman        DEBUG(dbgs() << "DoesRetainableObjPtrEscape: User copies pointer "
21002c953ea8b8130bd60fdacb97649d6344f1e8143Michael Gottesman              "arguments. Pointer Escapes!\n");
21144234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman        // These special functions make copies of their pointer arguments.
21244234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman        return true;
213981308cffbfd1f77750452015f6e6f0f053e11d4Michael Gottesman      }
21444234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman      case IC_User:
21544234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman      case IC_None:
21644234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman        // Use by an instruction which copies the value is an escape if the
21744234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman        // result is an escape.
21844234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman        if (isa<BitCastInst>(UUser) || isa<GetElementPtrInst>(UUser) ||
21944234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman            isa<PHINode>(UUser) || isa<SelectInst>(UUser)) {
2206056b85bb5e863f3b174ed21bd70e22a03ed61f7Michael Gottesman
2213603e9aa5e46923c44db1e6254f0393a2b0644e4Michael Gottesman          if (VisitedSet.insert(UUser)) {
22202c953ea8b8130bd60fdacb97649d6344f1e8143Michael Gottesman            DEBUG(dbgs() << "DoesRetainableObjPtrEscape: User copies value. "
22302c953ea8b8130bd60fdacb97649d6344f1e8143Michael Gottesman                  "Ptr escapes if result escapes. Adding to list.\n");
2246056b85bb5e863f3b174ed21bd70e22a03ed61f7Michael Gottesman            Worklist.push_back(UUser);
2256056b85bb5e863f3b174ed21bd70e22a03ed61f7Michael Gottesman          } else {
22602c953ea8b8130bd60fdacb97649d6344f1e8143Michael Gottesman            DEBUG(dbgs() << "DoesRetainableObjPtrEscape: Already visited node."
22702c953ea8b8130bd60fdacb97649d6344f1e8143Michael Gottesman                  "\n");
2286056b85bb5e863f3b174ed21bd70e22a03ed61f7Michael Gottesman          }
22944234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman          continue;
23044234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman        }
23144234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman        // Use by a load is not an escape.
23244234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman        if (isa<LoadInst>(UUser))
23344234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman          continue;
23444234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman        // Use by a store is not an escape if the use is the address.
23544234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman        if (const StoreInst *SI = dyn_cast<StoreInst>(UUser))
23644234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman          if (V != SI->getValueOperand())
23744234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman            continue;
23844234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman        break;
23944234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman      default:
24044234775486a0bd8fb6dae4048666ea5567caa11Dan Gohman        // Regular calls and other stuff are not considered escapes.
24179522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman        continue;
24279522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman      }
243a3b08d68bd281773b0300222edb4149abce4b4b8Dan Gohman      // Otherwise, conservatively assume an escape.
24402c953ea8b8130bd60fdacb97649d6344f1e8143Michael Gottesman      DEBUG(dbgs() << "DoesRetainableObjPtrEscape: Assuming ptr escapes.\n");
24579522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman      return true;
24679522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman    }
24779522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  } while (!Worklist.empty());
24879522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman
24979522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  // No escapes found.
25002c953ea8b8130bd60fdacb97649d6344f1e8143Michael Gottesman  DEBUG(dbgs() << "DoesRetainableObjPtrEscape: Ptr does not escape.\n");
25179522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  return false;
25279522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman}
25379522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman
25481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// @}
25581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman///
25681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// \defgroup ARCOpt ARC Optimization.
25781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// @{
2589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
2599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// TODO: On code like this:
2609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall//
2619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// objc_retain(%x)
2629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// stuff_that_cannot_release()
2639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// objc_autorelease(%x)
2649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// stuff_that_cannot_release()
2659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// objc_retain(%x)
2669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// stuff_that_cannot_release()
2679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// objc_autorelease(%x)
2689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall//
2699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// The second retain and autorelease can be deleted.
2709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
2719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// TODO: It should be possible to delete
2729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// objc_autoreleasePoolPush and objc_autoreleasePoolPop
2739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// pairs if nothing is actually autoreleased between them. Also, autorelease
2749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// calls followed by objc_autoreleasePoolPop calls (perhaps in ObjC++ code
2759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// after inlining) can be turned into plain release calls.
2769fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
2779fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// TODO: Critical-edge splitting. If the optimial insertion point is
2789fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// a critical edge, the current algorithm has to fail, because it doesn't
2799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// know how to split edges. It should be possible to make the optimizer
2809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// think in terms of edges, rather than blocks, and then split critical
2819fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// edges on demand.
2829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
2839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// TODO: OptimizeSequences could generalized to be Interprocedural.
2849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
2859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// TODO: Recognize that a bunch of other objc runtime calls have
2869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// non-escaping arguments and non-releasing arguments, and may be
2879fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// non-autoreleasing.
2889fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
2899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// TODO: Sink autorelease calls as far as possible. Unfortunately we
2909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// usually can't sink them past other calls, which would be the main
2919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall// case where it would be useful.
2929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
293e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman// TODO: The pointer returned from objc_loadWeakRetained is retained.
294e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman
295e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman// TODO: Delete release+retain pairs (rare).
296c4bcd4d964327e52ceadcc9be270718d758f8535Dan Gohman
2979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallSTATISTIC(NumNoops,       "Number of no-op objc calls eliminated");
2989fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallSTATISTIC(NumPartialNoops, "Number of partially no-op objc calls eliminated");
2999fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallSTATISTIC(NumAutoreleases,"Number of autoreleases converted to releases");
3009fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallSTATISTIC(NumRets,        "Number of return value forwarding "
3019fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                          "retain+autoreleaes eliminated");
3029fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallSTATISTIC(NumRRs,         "Number of retain+release paths eliminated");
3039fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallSTATISTIC(NumPeeps,       "Number of calls peephole-optimized");
3049fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
3059fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallnamespace {
30681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  /// \enum Sequence
30781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  ///
30881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  /// \brief A sequence of states that a pointer may go through in which an
30981c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  /// objc_retain and objc_release are actually needed.
3109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  enum Sequence {
3119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    S_None,
312a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    S_Retain,         ///< objc_retain(x).
313a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    S_CanRelease,     ///< foo(x) -- x could possibly see a ref count decrement.
314a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    S_Use,            ///< any use of x.
315b82d200dcb748619e22491ecfb9662ae86d7dfd5Michael Gottesman    S_Stop,           ///< like S_Release, but code motion is stopped.
316a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    S_Release,        ///< objc_release(x).
317485da648484e443f38c8ddbe5cb8ace07e2166e7Michael Gottesman    S_MovableRelease  ///< objc_release(x), !clang.imprecise_release.
3189fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  };
319a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman
320a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman  raw_ostream &operator<<(raw_ostream &OS, const Sequence S)
321a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    LLVM_ATTRIBUTE_UNUSED;
322a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman  raw_ostream &operator<<(raw_ostream &OS, const Sequence S) {
323a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    switch (S) {
324a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    case S_None:
325a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman      return OS << "S_None";
326a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    case S_Retain:
327a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman      return OS << "S_Retain";
328a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    case S_CanRelease:
329a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman      return OS << "S_CanRelease";
330a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    case S_Use:
331a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman      return OS << "S_Use";
332a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    case S_Release:
333a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman      return OS << "S_Release";
334a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    case S_MovableRelease:
335a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman      return OS << "S_MovableRelease";
336a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    case S_Stop:
337a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman      return OS << "S_Stop";
338a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    }
339a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman    llvm_unreachable("Unknown sequence type.");
340a519c97b4278970b7104005205c6f42910cb9acbMichael Gottesman  }
3419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
3429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
3439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallstatic Sequence MergeSeqs(Sequence A, Sequence B, bool TopDown) {
3449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // The easy cases.
3459fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (A == B)
3469fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    return A;
3479fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (A == S_None || B == S_None)
3489fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    return S_None;
3499fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
3509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (A > B) std::swap(A, B);
3519fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (TopDown) {
3529fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // Choose the side which is further along in the sequence.
353a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman    if ((A == S_Retain || A == S_CanRelease) &&
354a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman        (B == S_CanRelease || B == S_Use))
3559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return B;
3569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  } else {
3579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // Choose the side which is further along in the sequence.
3589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if ((A == S_Use || A == S_CanRelease) &&
359a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman        (B == S_Use || B == S_Release || B == S_Stop || B == S_MovableRelease))
3609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return A;
3619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // If both sides are releases, choose the more conservative one.
3629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (A == S_Stop && (B == S_Release || B == S_MovableRelease))
3639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return A;
3649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (A == S_Release && B == S_MovableRelease)
3659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return A;
3669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
3679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
3689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return S_None;
3699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
3709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
3719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallnamespace {
37281c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  /// \brief Unidirectional information about either a
3739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  /// retain-decrement-use-release sequence or release-use-decrement-retain
3749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  /// reverese sequence.
3759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  struct RRInfo {
37681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// After an objc_retain, the reference count of the referenced
377e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    /// object is known to be positive. Similarly, before an objc_release, the
378e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    /// reference count of the referenced object is known to be positive. If
379e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    /// there are retain-release pairs in code regions where the retain count
380e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    /// is known to be positive, they can be eliminated, regardless of any side
381e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    /// effects between them.
382e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    ///
383e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    /// Also, a retain+release pair nested within another retain+release
384e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    /// pair all on the known same pointer value can be eliminated, regardless
385e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    /// of any intervening side effects.
386e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    ///
387e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    /// KnownSafe is true when either of these conditions is satisfied.
388e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    bool KnownSafe;
3899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
39081c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// True if the Calls are objc_retainBlock calls (as opposed to objc_retain
39181c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// calls).
3929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    bool IsRetainBlock;
3939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
39481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// True of the objc_release calls are all marked with the "tail" keyword.
3959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    bool IsTailCallRelease;
3969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
39781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// If the Calls are objc_release calls and they all have a
39881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// clang.imprecise_release tag, this is the metadata tag.
3999fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    MDNode *ReleaseMetadata;
4009fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
40181c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// For a top-down sequence, the set of objc_retains or
4029fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    /// objc_retainBlocks. For bottom-up, the set of objc_releases.
4039fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    SmallPtrSet<Instruction *, 2> Calls;
4049fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
40581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// The set of optimal insert positions for moving calls in the opposite
40681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// sequence.
4079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    SmallPtrSet<Instruction *, 2> ReverseInsertPts;
4089fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
4099fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    RRInfo() :
41079522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman      KnownSafe(false), IsRetainBlock(false),
41150ade659829269f0338cd1bfa0a574dcec62562eDan Gohman      IsTailCallRelease(false),
4129fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      ReleaseMetadata(0) {}
4139fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
4149fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void clear();
4159fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  };
4169fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
4179fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
4189fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid RRInfo::clear() {
419e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman  KnownSafe = false;
4209fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  IsRetainBlock = false;
4219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  IsTailCallRelease = false;
4229fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  ReleaseMetadata = 0;
4239fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  Calls.clear();
4249fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  ReverseInsertPts.clear();
4259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
4269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
4279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallnamespace {
42881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  /// \brief This class summarizes several per-pointer runtime properties which
42981c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  /// are propogated through the flow graph.
4309fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  class PtrState {
43181c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// True if the reference count is known to be incremented.
43250ade659829269f0338cd1bfa0a574dcec62562eDan Gohman    bool KnownPositiveRefCount;
43350ade659829269f0338cd1bfa0a574dcec62562eDan Gohman
43481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// True of we've seen an opportunity for partial RR elimination, such as
43581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// pushing calls into a CFG triangle or into one side of a CFG diamond.
43650ade659829269f0338cd1bfa0a574dcec62562eDan Gohman    bool Partial;
4379fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
43881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// The current position in the sequence.
4390daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman    Sequence Seq : 8;
4409fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
4419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  public:
44281c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Unidirectional information about the current sequence.
44381c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    ///
4449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    /// TODO: Encapsulate this better.
4459fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    RRInfo RRI;
4469fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
447230768bd1316a012e88ac62689589fe5e2f10456Dan Gohman    PtrState() : KnownPositiveRefCount(false), Partial(false),
4480daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman                 Seq(S_None) {}
449a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman
450da6bf1d8bbf8e787f7c0edffbad40531dd520446Michael Gottesman    void SetKnownPositiveRefCount() {
45150ade659829269f0338cd1bfa0a574dcec62562eDan Gohman      KnownPositiveRefCount = true;
4529fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
4539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
454da6bf1d8bbf8e787f7c0edffbad40531dd520446Michael Gottesman    void ClearRefCount() {
45550ade659829269f0338cd1bfa0a574dcec62562eDan Gohman      KnownPositiveRefCount = false;
4569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
4579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
458da6bf1d8bbf8e787f7c0edffbad40531dd520446Michael Gottesman    bool IsKnownIncremented() const {
45950ade659829269f0338cd1bfa0a574dcec62562eDan Gohman      return KnownPositiveRefCount;
4609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
4619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
462da6bf1d8bbf8e787f7c0edffbad40531dd520446Michael Gottesman    void SetSeq(Sequence NewSeq) {
4639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Seq = NewSeq;
4649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
4659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
466da6bf1d8bbf8e787f7c0edffbad40531dd520446Michael Gottesman    Sequence GetSeq() const {
4679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return Seq;
4689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
4699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
470da6bf1d8bbf8e787f7c0edffbad40531dd520446Michael Gottesman    void ClearSequenceProgress() {
47150ade659829269f0338cd1bfa0a574dcec62562eDan Gohman      ResetSequenceProgress(S_None);
47250ade659829269f0338cd1bfa0a574dcec62562eDan Gohman    }
47350ade659829269f0338cd1bfa0a574dcec62562eDan Gohman
474da6bf1d8bbf8e787f7c0edffbad40531dd520446Michael Gottesman    void ResetSequenceProgress(Sequence NewSeq) {
47550ade659829269f0338cd1bfa0a574dcec62562eDan Gohman      Seq = NewSeq;
47650ade659829269f0338cd1bfa0a574dcec62562eDan Gohman      Partial = false;
4779fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      RRI.clear();
4789fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
4799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
4809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void Merge(const PtrState &Other, bool TopDown);
4819fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  };
4829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
4839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
4849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid
4859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallPtrState::Merge(const PtrState &Other, bool TopDown) {
4869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  Seq = MergeSeqs(Seq, Other.Seq, TopDown);
48750ade659829269f0338cd1bfa0a574dcec62562eDan Gohman  KnownPositiveRefCount = KnownPositiveRefCount && Other.KnownPositiveRefCount;
4889fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
4899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // We can't merge a plain objc_retain with an objc_retainBlock.
4909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (RRI.IsRetainBlock != Other.RRI.IsRetainBlock)
4919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Seq = S_None;
4929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
49390b8bcd33ab4fd7dd95bd1dc9a2d7d03dcd83ad6Dan Gohman  // If we're not in a sequence (anymore), drop all associated state.
4949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (Seq == S_None) {
49550ade659829269f0338cd1bfa0a574dcec62562eDan Gohman    Partial = false;
4969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    RRI.clear();
49750ade659829269f0338cd1bfa0a574dcec62562eDan Gohman  } else if (Partial || Other.Partial) {
49890b8bcd33ab4fd7dd95bd1dc9a2d7d03dcd83ad6Dan Gohman    // If we're doing a merge on a path that's previously seen a partial
49990b8bcd33ab4fd7dd95bd1dc9a2d7d03dcd83ad6Dan Gohman    // merge, conservatively drop the sequence, to avoid doing partial
50090b8bcd33ab4fd7dd95bd1dc9a2d7d03dcd83ad6Dan Gohman    // RR elimination. If the branch predicates for the two merge differ,
50190b8bcd33ab4fd7dd95bd1dc9a2d7d03dcd83ad6Dan Gohman    // mixing them is unsafe.
50250ade659829269f0338cd1bfa0a574dcec62562eDan Gohman    ClearSequenceProgress();
5039fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  } else {
5049fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // Conservatively merge the ReleaseMetadata information.
5059fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (RRI.ReleaseMetadata != Other.RRI.ReleaseMetadata)
5069fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      RRI.ReleaseMetadata = 0;
5079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
508e6d5e88c1230eae7056a5cd6238e86c00cdff72fDan Gohman    RRI.KnownSafe = RRI.KnownSafe && Other.RRI.KnownSafe;
5090daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman    RRI.IsTailCallRelease = RRI.IsTailCallRelease &&
5100daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman                            Other.RRI.IsTailCallRelease;
5119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    RRI.Calls.insert(Other.RRI.Calls.begin(), Other.RRI.Calls.end());
51290b8bcd33ab4fd7dd95bd1dc9a2d7d03dcd83ad6Dan Gohman
51390b8bcd33ab4fd7dd95bd1dc9a2d7d03dcd83ad6Dan Gohman    // Merge the insert point sets. If there are any differences,
51490b8bcd33ab4fd7dd95bd1dc9a2d7d03dcd83ad6Dan Gohman    // that makes this a partial merge.
5150daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman    Partial = RRI.ReverseInsertPts.size() != Other.RRI.ReverseInsertPts.size();
51690b8bcd33ab4fd7dd95bd1dc9a2d7d03dcd83ad6Dan Gohman    for (SmallPtrSet<Instruction *, 2>::const_iterator
51790b8bcd33ab4fd7dd95bd1dc9a2d7d03dcd83ad6Dan Gohman         I = Other.RRI.ReverseInsertPts.begin(),
51890b8bcd33ab4fd7dd95bd1dc9a2d7d03dcd83ad6Dan Gohman         E = Other.RRI.ReverseInsertPts.end(); I != E; ++I)
51950ade659829269f0338cd1bfa0a574dcec62562eDan Gohman      Partial |= RRI.ReverseInsertPts.insert(*I);
5209fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
5219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
5229fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
5239fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallnamespace {
52481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  /// \brief Per-BasicBlock state.
5259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  class BBState {
52681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// The number of unique control paths from the entry which can reach this
52781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// block.
5289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    unsigned TopDownPathCount;
5299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
53081c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// The number of unique control paths to exits from this block.
5319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    unsigned BottomUpPathCount;
5329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
53381c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// A type for PerPtrTopDown and PerPtrBottomUp.
5349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    typedef MapVector<const Value *, PtrState> MapTy;
5359fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
53681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// The top-down traversal uses this to record information known about a
53781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// pointer at the bottom of each block.
5389fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    MapTy PerPtrTopDown;
5399fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
54081c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// The bottom-up traversal uses this to record information known about a
54181c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// pointer at the top of each block.
5429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    MapTy PerPtrBottomUp;
5439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
54481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Effective predecessors of the current block ignoring ignorable edges and
54581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// ignored backedges.
546eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    SmallVector<BasicBlock *, 2> Preds;
54781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Effective successors of the current block ignoring ignorable edges and
54881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// ignored backedges.
549eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    SmallVector<BasicBlock *, 2> Succs;
550eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman
5519fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  public:
5529fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    BBState() : TopDownPathCount(0), BottomUpPathCount(0) {}
5539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
5549fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    typedef MapTy::iterator ptr_iterator;
5559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    typedef MapTy::const_iterator ptr_const_iterator;
5569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
5579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ptr_iterator top_down_ptr_begin() { return PerPtrTopDown.begin(); }
5589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ptr_iterator top_down_ptr_end() { return PerPtrTopDown.end(); }
5599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ptr_const_iterator top_down_ptr_begin() const {
5609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return PerPtrTopDown.begin();
5619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
5629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ptr_const_iterator top_down_ptr_end() const {
5639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return PerPtrTopDown.end();
5649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
5659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
5669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ptr_iterator bottom_up_ptr_begin() { return PerPtrBottomUp.begin(); }
5679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ptr_iterator bottom_up_ptr_end() { return PerPtrBottomUp.end(); }
5689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ptr_const_iterator bottom_up_ptr_begin() const {
5699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return PerPtrBottomUp.begin();
5709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
5719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ptr_const_iterator bottom_up_ptr_end() const {
5729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return PerPtrBottomUp.end();
5739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
5749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
57581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Mark this block as being an entry block, which has one path from the
57681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// entry by definition.
5779fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void SetAsEntry() { TopDownPathCount = 1; }
5789fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
57981c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Mark this block as being an exit block, which has one path to an exit by
58081c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// definition.
5819fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void SetAsExit()  { BottomUpPathCount = 1; }
5829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
5839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    PtrState &getPtrTopDownState(const Value *Arg) {
5849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return PerPtrTopDown[Arg];
5859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
5869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
5879fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    PtrState &getPtrBottomUpState(const Value *Arg) {
5889fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return PerPtrBottomUp[Arg];
5899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
5909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
5919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void clearBottomUpPointers() {
592a81388fb4ab78cf85019840a27057b185f828ad1Evan Cheng      PerPtrBottomUp.clear();
5939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
5949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
5959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void clearTopDownPointers() {
5969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      PerPtrTopDown.clear();
5979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
5989fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
5999fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void InitFromPred(const BBState &Other);
6009fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void InitFromSucc(const BBState &Other);
6019fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void MergePred(const BBState &Other);
6029fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void MergeSucc(const BBState &Other);
6039fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
60481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Return the number of possible unique paths from an entry to an exit
60581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// which pass through this block. This is only valid after both the
60681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// top-down and bottom-up traversals are complete.
6079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    unsigned GetAllPathCount() const {
608eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      assert(TopDownPathCount != 0);
609eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      assert(BottomUpPathCount != 0);
6109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return TopDownPathCount * BottomUpPathCount;
6119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
612a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman
613eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    // Specialized CFG utilities.
614447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman    typedef SmallVectorImpl<BasicBlock *>::const_iterator edge_iterator;
615eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    edge_iterator pred_begin() { return Preds.begin(); }
616eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    edge_iterator pred_end() { return Preds.end(); }
617eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    edge_iterator succ_begin() { return Succs.begin(); }
618eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    edge_iterator succ_end() { return Succs.end(); }
619eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman
620eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    void addSucc(BasicBlock *Succ) { Succs.push_back(Succ); }
621eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    void addPred(BasicBlock *Pred) { Preds.push_back(Pred); }
622eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman
623eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    bool isExit() const { return Succs.empty(); }
6249fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  };
6259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
6269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
6279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid BBState::InitFromPred(const BBState &Other) {
6289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  PerPtrTopDown = Other.PerPtrTopDown;
6299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  TopDownPathCount = Other.TopDownPathCount;
6309fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
6319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
6329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid BBState::InitFromSucc(const BBState &Other) {
6339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  PerPtrBottomUp = Other.PerPtrBottomUp;
6349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  BottomUpPathCount = Other.BottomUpPathCount;
6359fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
6369fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
63781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// The top-down traversal uses this to merge information about predecessors to
63881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// form the initial state for a new block.
6399fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid BBState::MergePred(const BBState &Other) {
6409fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Other.TopDownPathCount can be 0, in which case it is either dead or a
6419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // loop backedge. Loop backedges are special.
6429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  TopDownPathCount += Other.TopDownPathCount;
6439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
6447899e47f205f32127ec2b6229ca587e996e0a08eMichael Gottesman  // Check for overflow. If we have overflow, fall back to conservative
6457899e47f205f32127ec2b6229ca587e996e0a08eMichael Gottesman  // behavior.
6460d1bc5f916d6b0f4eb5bf69cf87e244b52be009eDan Gohman  if (TopDownPathCount < Other.TopDownPathCount) {
6470d1bc5f916d6b0f4eb5bf69cf87e244b52be009eDan Gohman    clearTopDownPointers();
6480d1bc5f916d6b0f4eb5bf69cf87e244b52be009eDan Gohman    return;
6490d1bc5f916d6b0f4eb5bf69cf87e244b52be009eDan Gohman  }
6500d1bc5f916d6b0f4eb5bf69cf87e244b52be009eDan Gohman
6519fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // For each entry in the other set, if our set has an entry with the same key,
6529fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // merge the entries. Otherwise, copy the entry and merge it with an empty
6539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // entry.
6549fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (ptr_const_iterator MI = Other.top_down_ptr_begin(),
6559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       ME = Other.top_down_ptr_end(); MI != ME; ++MI) {
6569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    std::pair<ptr_iterator, bool> Pair = PerPtrTopDown.insert(*MI);
6579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Pair.first->second.Merge(Pair.second ? PtrState() : MI->second,
6589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                             /*TopDown=*/true);
6599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
6609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
661fa7eed1f8eee4fd3839e589c3e0e84f79d248c8aDan Gohman  // For each entry in our set, if the other set doesn't have an entry with the
6629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // same key, force it to merge with an empty entry.
6639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (ptr_iterator MI = top_down_ptr_begin(),
6649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       ME = top_down_ptr_end(); MI != ME; ++MI)
6659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (Other.PerPtrTopDown.find(MI->first) == Other.PerPtrTopDown.end())
6669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      MI->second.Merge(PtrState(), /*TopDown=*/true);
6679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
6689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
66981c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// The bottom-up traversal uses this to merge information about successors to
67081c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// form the initial state for a new block.
6719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid BBState::MergeSucc(const BBState &Other) {
6729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Other.BottomUpPathCount can be 0, in which case it is either dead or a
6739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // loop backedge. Loop backedges are special.
6749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  BottomUpPathCount += Other.BottomUpPathCount;
6759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
6767899e47f205f32127ec2b6229ca587e996e0a08eMichael Gottesman  // Check for overflow. If we have overflow, fall back to conservative
6777899e47f205f32127ec2b6229ca587e996e0a08eMichael Gottesman  // behavior.
6780d1bc5f916d6b0f4eb5bf69cf87e244b52be009eDan Gohman  if (BottomUpPathCount < Other.BottomUpPathCount) {
6790d1bc5f916d6b0f4eb5bf69cf87e244b52be009eDan Gohman    clearBottomUpPointers();
6800d1bc5f916d6b0f4eb5bf69cf87e244b52be009eDan Gohman    return;
6810d1bc5f916d6b0f4eb5bf69cf87e244b52be009eDan Gohman  }
6820d1bc5f916d6b0f4eb5bf69cf87e244b52be009eDan Gohman
6839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // For each entry in the other set, if our set has an entry with the
6849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // same key, merge the entries. Otherwise, copy the entry and merge
6859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // it with an empty entry.
6869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (ptr_const_iterator MI = Other.bottom_up_ptr_begin(),
6879fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       ME = Other.bottom_up_ptr_end(); MI != ME; ++MI) {
6889fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    std::pair<ptr_iterator, bool> Pair = PerPtrBottomUp.insert(*MI);
6899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Pair.first->second.Merge(Pair.second ? PtrState() : MI->second,
6909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                             /*TopDown=*/false);
6919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
6929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
693fa7eed1f8eee4fd3839e589c3e0e84f79d248c8aDan Gohman  // For each entry in our set, if the other set doesn't have an entry
6949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // with the same key, force it to merge with an empty entry.
6959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (ptr_iterator MI = bottom_up_ptr_begin(),
6969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       ME = bottom_up_ptr_end(); MI != ME; ++MI)
6979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (Other.PerPtrBottomUp.find(MI->first) == Other.PerPtrBottomUp.end())
6989fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      MI->second.Merge(PtrState(), /*TopDown=*/false);
6999fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
7009fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
7019fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallnamespace {
70281c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  /// \brief The main ARC optimization pass.
7039fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  class ObjCARCOpt : public FunctionPass {
7049fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    bool Changed;
7059fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ProvenanceAnalysis PA;
7069fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
70781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// A flag indicating whether this optimization pass should run.
708c4bcd4d964327e52ceadcc9be270718d758f8535Dan Gohman    bool Run;
709c4bcd4d964327e52ceadcc9be270718d758f8535Dan Gohman
71081c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Declarations for ObjC runtime functions, for use in creating calls to
71181c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// them. These are initialized lazily to avoid cluttering up the Module
71281c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// with unused declarations.
71381c6121699a66b3e84f7b794b375095a39584701Michael Gottesman
71481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Declaration for ObjC runtime function
71581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// objc_retainAutoreleasedReturnValue.
71681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    Constant *RetainRVCallee;
71781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Declaration for ObjC runtime function objc_autoreleaseReturnValue.
71881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    Constant *AutoreleaseRVCallee;
71981c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Declaration for ObjC runtime function objc_release.
72081c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    Constant *ReleaseCallee;
72181c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Declaration for ObjC runtime function objc_retain.
72281c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    Constant *RetainCallee;
72381c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Declaration for ObjC runtime function objc_retainBlock.
72481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    Constant *RetainBlockCallee;
72581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Declaration for ObjC runtime function objc_autorelease.
72681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    Constant *AutoreleaseCallee;
72781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman
72881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// Flags which determine whether each of the interesting runtine functions
72981c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// is in fact used in the current function.
7309fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    unsigned UsedInThisFunction;
7319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
73281c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// The Metadata Kind for clang.imprecise_release metadata.
7339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    unsigned ImpreciseReleaseMDKind;
7349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
73581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// The Metadata Kind for clang.arc.copy_on_escape metadata.
736a974beaa1f63394a67c38c66ff0f39a759c7998fDan Gohman    unsigned CopyOnEscapeMDKind;
737a974beaa1f63394a67c38c66ff0f39a759c7998fDan Gohman
73881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman    /// The Metadata Kind for clang.arc.no_objc_arc_exceptions metadata.
739dbe266be35cfee0fbda5523ac578fef81e8fdfccDan Gohman    unsigned NoObjCARCExceptionsMDKind;
740dbe266be35cfee0fbda5523ac578fef81e8fdfccDan Gohman
7419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Constant *getRetainRVCallee(Module *M);
7429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Constant *getAutoreleaseRVCallee(Module *M);
7439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Constant *getReleaseCallee(Module *M);
7449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Constant *getRetainCallee(Module *M);
7454428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman    Constant *getRetainBlockCallee(Module *M);
7469fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Constant *getAutoreleaseCallee(Module *M);
7479fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
74879522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman    bool IsRetainBlockOptimizable(const Instruction *Inst);
74979522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman
7509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void OptimizeRetainCall(Function &F, Instruction *Retain);
7519fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    bool OptimizeRetainRVCall(Function &F, Instruction *RetainRV);
7520e385450fc62a69cf7c557173f2f5df132702379Michael Gottesman    void OptimizeAutoreleaseRVCall(Function &F, Instruction *AutoreleaseRV,
7530e385450fc62a69cf7c557173f2f5df132702379Michael Gottesman                                   InstructionClass &Class);
7549fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void OptimizeIndividualCalls(Function &F);
7559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
7569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void CheckForCFGHazards(const BasicBlock *BB,
7579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                            DenseMap<const BasicBlock *, BBState> &BBStates,
7589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                            BBState &MyStates) const;
759c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    bool VisitInstructionBottomUp(Instruction *Inst,
760fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman                                  BasicBlock *BB,
761c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman                                  MapVector<Value *, RRInfo> &Retains,
762c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman                                  BBState &MyStates);
7639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    bool VisitBottomUp(BasicBlock *BB,
7649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                       DenseMap<const BasicBlock *, BBState> &BBStates,
7659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                       MapVector<Value *, RRInfo> &Retains);
766c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    bool VisitInstructionTopDown(Instruction *Inst,
767c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman                                 DenseMap<Value *, RRInfo> &Releases,
768c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman                                 BBState &MyStates);
7699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    bool VisitTopDown(BasicBlock *BB,
7709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                      DenseMap<const BasicBlock *, BBState> &BBStates,
7719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                      DenseMap<Value *, RRInfo> &Releases);
7729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    bool Visit(Function &F,
7739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall               DenseMap<const BasicBlock *, BBState> &BBStates,
7749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall               MapVector<Value *, RRInfo> &Retains,
7759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall               DenseMap<Value *, RRInfo> &Releases);
7769fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
7779fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void MoveCalls(Value *Arg, RRInfo &RetainsToMove, RRInfo &ReleasesToMove,
7789fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                   MapVector<Value *, RRInfo> &Retains,
7799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                   DenseMap<Value *, RRInfo> &Releases,
7804428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman                   SmallVectorImpl<Instruction *> &DeadInsts,
7814428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman                   Module *M);
7829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
783862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    bool ConnectTDBUTraversals(DenseMap<const BasicBlock *, BBState> &BBStates,
784862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                               MapVector<Value *, RRInfo> &Retains,
785862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                               DenseMap<Value *, RRInfo> &Releases,
786862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                               Module *M,
787862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                               SmallVector<Instruction *, 4> &NewRetains,
788862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                               SmallVector<Instruction *, 4> &NewReleases,
789862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                               SmallVector<Instruction *, 8> &DeadInsts,
790862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                               RRInfo &RetainsToMove,
791862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                               RRInfo &ReleasesToMove,
792862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                               Value *Arg,
793862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                               bool KnownSafe,
794862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                               bool &AnyPairsCompletelyEliminated);
795862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman
7969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    bool PerformCodePlacement(DenseMap<const BasicBlock *, BBState> &BBStates,
7979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                              MapVector<Value *, RRInfo> &Retains,
7984428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman                              DenseMap<Value *, RRInfo> &Releases,
7994428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman                              Module *M);
8009fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
8019fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void OptimizeWeakCalls(Function &F);
8029fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
8039fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    bool OptimizeSequences(Function &F);
8049fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
8059fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    void OptimizeReturns(Function &F);
8069fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
8079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    virtual void getAnalysisUsage(AnalysisUsage &AU) const;
8089fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    virtual bool doInitialization(Module &M);
8099fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    virtual bool runOnFunction(Function &F);
8109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    virtual void releaseMemory();
8119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
8129fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  public:
8139fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    static char ID;
8149fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ObjCARCOpt() : FunctionPass(ID) {
8159fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      initializeObjCARCOptPass(*PassRegistry::getPassRegistry());
8169fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
8179fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  };
8189fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
8199fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
8209fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallchar ObjCARCOpt::ID = 0;
8219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallINITIALIZE_PASS_BEGIN(ObjCARCOpt,
8229fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                      "objc-arc", "ObjC ARC optimization", false, false)
8239fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallINITIALIZE_PASS_DEPENDENCY(ObjCARCAliasAnalysis)
8249fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallINITIALIZE_PASS_END(ObjCARCOpt,
8259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                    "objc-arc", "ObjC ARC optimization", false, false)
8269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
8279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallPass *llvm::createObjCARCOptPass() {
8289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return new ObjCARCOpt();
8299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
8309fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
8319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid ObjCARCOpt::getAnalysisUsage(AnalysisUsage &AU) const {
8329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  AU.addRequired<ObjCARCAliasAnalysis>();
8339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  AU.addRequired<AliasAnalysis>();
8349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // ARC optimization doesn't currently split critical edges.
8359fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  AU.setPreservesCFG();
8369fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
8379fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
83879522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohmanbool ObjCARCOpt::IsRetainBlockOptimizable(const Instruction *Inst) {
83979522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  // Without the magic metadata tag, we have to assume this might be an
84079522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  // objc_retainBlock call inserted to convert a block pointer to an id,
84179522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  // in which case it really is needed.
84279522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  if (!Inst->getMetadata(CopyOnEscapeMDKind))
84379522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman    return false;
84479522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman
84579522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  // If the pointer "escapes" (not including being used in a call),
84679522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  // the copy may be needed.
84782b83011a1e330e41147dbad97e44939840ba755Michael Gottesman  if (DoesRetainableObjPtrEscape(Inst))
84879522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman    return false;
84979522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman
85079522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  // Otherwise, it's not needed.
85179522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman  return true;
85279522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman}
85379522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman
8549fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallConstant *ObjCARCOpt::getRetainRVCallee(Module *M) {
8559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (!RetainRVCallee) {
8569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    LLVMContext &C = M->getContext();
8575fdd6c8793462549e3593890ec61573da06e3346Jay Foad    Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
8580daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman    Type *Params[] = { I8X };
8590daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman    FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
860034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    AttributeSet Attribute =
861defaca00b8087d452df2b783250a48a32658a910Bill Wendling      AttributeSet().addAttribute(M->getContext(), AttributeSet::FunctionIndex,
862defaca00b8087d452df2b783250a48a32658a910Bill Wendling                                  Attribute::NoUnwind);
8639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    RetainRVCallee =
8649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      M->getOrInsertFunction("objc_retainAutoreleasedReturnValue", FTy,
865034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling                             Attribute);
8669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
8679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return RetainRVCallee;
8689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
8699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
8709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallConstant *ObjCARCOpt::getAutoreleaseRVCallee(Module *M) {
8719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (!AutoreleaseRVCallee) {
8729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    LLVMContext &C = M->getContext();
8735fdd6c8793462549e3593890ec61573da06e3346Jay Foad    Type *I8X = PointerType::getUnqual(Type::getInt8Ty(C));
8740daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman    Type *Params[] = { I8X };
8750daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman    FunctionType *FTy = FunctionType::get(I8X, Params, /*isVarArg=*/false);
876034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    AttributeSet Attribute =
877defaca00b8087d452df2b783250a48a32658a910Bill Wendling      AttributeSet().addAttribute(M->getContext(), AttributeSet::FunctionIndex,
878defaca00b8087d452df2b783250a48a32658a910Bill Wendling                                  Attribute::NoUnwind);
8799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    AutoreleaseRVCallee =
8809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      M->getOrInsertFunction("objc_autoreleaseReturnValue", FTy,
881034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling                             Attribute);
8829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
8839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return AutoreleaseRVCallee;
8849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
8859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
8869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallConstant *ObjCARCOpt::getReleaseCallee(Module *M) {
8879fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (!ReleaseCallee) {
8889fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    LLVMContext &C = M->getContext();
8890daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman    Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
890034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    AttributeSet Attribute =
891defaca00b8087d452df2b783250a48a32658a910Bill Wendling      AttributeSet().addAttribute(M->getContext(), AttributeSet::FunctionIndex,
892defaca00b8087d452df2b783250a48a32658a910Bill Wendling                                  Attribute::NoUnwind);
8939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ReleaseCallee =
8949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      M->getOrInsertFunction(
8959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        "objc_release",
8969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        FunctionType::get(Type::getVoidTy(C), Params, /*isVarArg=*/false),
897034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling        Attribute);
8989fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
8999fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return ReleaseCallee;
9009fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
9019fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
9029fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallConstant *ObjCARCOpt::getRetainCallee(Module *M) {
9039fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (!RetainCallee) {
9049fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    LLVMContext &C = M->getContext();
9050daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman    Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
906034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    AttributeSet Attribute =
907defaca00b8087d452df2b783250a48a32658a910Bill Wendling      AttributeSet().addAttribute(M->getContext(), AttributeSet::FunctionIndex,
908defaca00b8087d452df2b783250a48a32658a910Bill Wendling                                  Attribute::NoUnwind);
9099fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    RetainCallee =
9109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      M->getOrInsertFunction(
9119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        "objc_retain",
9129fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        FunctionType::get(Params[0], Params, /*isVarArg=*/false),
913034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling        Attribute);
9149fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
9159fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return RetainCallee;
9169fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
9179fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
9184428069f10ac6e7efb55826437c82428d4bbe03eDan GohmanConstant *ObjCARCOpt::getRetainBlockCallee(Module *M) {
9194428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman  if (!RetainBlockCallee) {
9204428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman    LLVMContext &C = M->getContext();
9210daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman    Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
9221d2fd75e3b60314210934078915aa573a2727854Dan Gohman    // objc_retainBlock is not nounwind because it calls user copy constructors
9231d2fd75e3b60314210934078915aa573a2727854Dan Gohman    // which could theoretically throw.
9244428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman    RetainBlockCallee =
9254428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman      M->getOrInsertFunction(
9264428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman        "objc_retainBlock",
9274428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman        FunctionType::get(Params[0], Params, /*isVarArg=*/false),
92899faa3b4ec6d03ac7808fe4ff3fbf3d04e375502Bill Wendling        AttributeSet());
9294428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman  }
9304428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman  return RetainBlockCallee;
9314428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman}
9324428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman
9339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallConstant *ObjCARCOpt::getAutoreleaseCallee(Module *M) {
9349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (!AutoreleaseCallee) {
9359fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    LLVMContext &C = M->getContext();
9360daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman    Type *Params[] = { PointerType::getUnqual(Type::getInt8Ty(C)) };
937034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling    AttributeSet Attribute =
938defaca00b8087d452df2b783250a48a32658a910Bill Wendling      AttributeSet().addAttribute(M->getContext(), AttributeSet::FunctionIndex,
939defaca00b8087d452df2b783250a48a32658a910Bill Wendling                                  Attribute::NoUnwind);
9409fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    AutoreleaseCallee =
9419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      M->getOrInsertFunction(
9429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        "objc_autorelease",
9439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        FunctionType::get(Params[0], Params, /*isVarArg=*/false),
944034b94b17006f51722886b0f2283fb6fb19aca1fBill Wendling        Attribute);
9459fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
9469fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return AutoreleaseCallee;
9479fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
9489fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
94981c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// Turn objc_retain into objc_retainAutoreleasedReturnValue if the operand is a
95081c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// return value.
9519fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid
9529fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallObjCARCOpt::OptimizeRetainCall(Function &F, Instruction *Retain) {
953447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman  ImmutableCallSite CS(GetObjCArg(Retain));
954447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman  const Instruction *Call = CS.getInstruction();
9559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (!Call) return;
9569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (Call->getParent() != Retain->getParent()) return;
9579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
9589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Check that the call is next to the retain.
959447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman  BasicBlock::const_iterator I = Call;
9609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  ++I;
9619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  while (isNoopInstruction(I)) ++I;
9629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (&*I != Retain)
9639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    return;
9649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
9659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Turn it to an objc_retainAutoreleasedReturnValue..
9669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  Changed = true;
9679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  ++NumPeeps;
9682f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
969715f6a62a17f1e26a7c3f673b70bf44c99ae7caeMichael Gottesman  DEBUG(dbgs() << "ObjCARCOpt::OptimizeRetainCall: Transforming "
970e7a715f61e7855a280734063989a1001320e85deMichael Gottesman                  "objc_retain => objc_retainAutoreleasedReturnValue"
971e7a715f61e7855a280734063989a1001320e85deMichael Gottesman                  " since the operand is a return value.\n"
972715f6a62a17f1e26a7c3f673b70bf44c99ae7caeMichael Gottesman                  "                                Old: "
973715f6a62a17f1e26a7c3f673b70bf44c99ae7caeMichael Gottesman               << *Retain << "\n");
9742f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
9759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  cast<CallInst>(Retain)->setCalledFunction(getRetainRVCallee(F.getParent()));
976715f6a62a17f1e26a7c3f673b70bf44c99ae7caeMichael Gottesman
977715f6a62a17f1e26a7c3f673b70bf44c99ae7caeMichael Gottesman  DEBUG(dbgs() << "                                New: "
978715f6a62a17f1e26a7c3f673b70bf44c99ae7caeMichael Gottesman               << *Retain << "\n");
9799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
9809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
98181c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// Turn objc_retainAutoreleasedReturnValue into objc_retain if the operand is
98281c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// not a return value.  Or, if it can be paired with an
98381c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// objc_autoreleaseReturnValue, delete the pair and return true.
9849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallbool
9859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) {
9866fedb3c4016b8f706c472280a3a9b22430c73ef4Dan Gohman  // Check for the argument being from an immediately preceding call or invoke.
987447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman  const Value *Arg = GetObjCArg(RetainRV);
988447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman  ImmutableCallSite CS(Arg);
989447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman  if (const Instruction *Call = CS.getInstruction()) {
9909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (Call->getParent() == RetainRV->getParent()) {
991447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman      BasicBlock::const_iterator I = Call;
9929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      ++I;
9939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      while (isNoopInstruction(I)) ++I;
9949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (&*I == RetainRV)
9959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        return false;
996447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman    } else if (const InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
9976fedb3c4016b8f706c472280a3a9b22430c73ef4Dan Gohman      BasicBlock *RetainRVParent = RetainRV->getParent();
9986fedb3c4016b8f706c472280a3a9b22430c73ef4Dan Gohman      if (II->getNormalDest() == RetainRVParent) {
999447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman        BasicBlock::const_iterator I = RetainRVParent->begin();
10006fedb3c4016b8f706c472280a3a9b22430c73ef4Dan Gohman        while (isNoopInstruction(I)) ++I;
10016fedb3c4016b8f706c472280a3a9b22430c73ef4Dan Gohman        if (&*I == RetainRV)
10026fedb3c4016b8f706c472280a3a9b22430c73ef4Dan Gohman          return false;
10036fedb3c4016b8f706c472280a3a9b22430c73ef4Dan Gohman      }
10049fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
10056fedb3c4016b8f706c472280a3a9b22430c73ef4Dan Gohman  }
10069fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
10079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Check for being preceded by an objc_autoreleaseReturnValue on the same
10089fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // pointer. In this case, we can delete the pair.
10099fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  BasicBlock::iterator I = RetainRV, Begin = RetainRV->getParent()->begin();
10109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (I != Begin) {
10119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    do --I; while (I != Begin && isNoopInstruction(I));
10129fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (GetBasicInstructionClass(I) == IC_AutoreleaseRV &&
10139fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        GetObjCArg(I) == Arg) {
10149fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Changed = true;
10159fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      ++NumPeeps;
10162f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
101787a0f02953147bf1bf840ccb92ee046aa9b190f5Michael Gottesman      DEBUG(dbgs() << "ObjCARCOpt::OptimizeRetainRVCall: Erasing " << *I << "\n"
101887a0f02953147bf1bf840ccb92ee046aa9b190f5Michael Gottesman                   << "                                  Erasing " << *RetainRV
101987a0f02953147bf1bf840ccb92ee046aa9b190f5Michael Gottesman                   << "\n");
10202f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
10219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      EraseInstruction(I);
10229fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      EraseInstruction(RetainRV);
10239fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      return true;
10249fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
10259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
10269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
10279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Turn it to a plain objc_retain.
10289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  Changed = true;
10299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  ++NumPeeps;
10302f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
103136e4bc406ca93f5ebd8e8b67cbf5d236c8423cbeMichael Gottesman  DEBUG(dbgs() << "ObjCARCOpt::OptimizeRetainRVCall: Transforming "
103236e4bc406ca93f5ebd8e8b67cbf5d236c8423cbeMichael Gottesman                  "objc_retainAutoreleasedReturnValue => "
103336e4bc406ca93f5ebd8e8b67cbf5d236c8423cbeMichael Gottesman                  "objc_retain since the operand is not a return value.\n"
103436e4bc406ca93f5ebd8e8b67cbf5d236c8423cbeMichael Gottesman                  "                                  Old: "
103536e4bc406ca93f5ebd8e8b67cbf5d236c8423cbeMichael Gottesman               << *RetainRV << "\n");
10362f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
10379fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  cast<CallInst>(RetainRV)->setCalledFunction(getRetainCallee(F.getParent()));
103836e4bc406ca93f5ebd8e8b67cbf5d236c8423cbeMichael Gottesman
103936e4bc406ca93f5ebd8e8b67cbf5d236c8423cbeMichael Gottesman  DEBUG(dbgs() << "                                  New: "
104036e4bc406ca93f5ebd8e8b67cbf5d236c8423cbeMichael Gottesman               << *RetainRV << "\n");
104136e4bc406ca93f5ebd8e8b67cbf5d236c8423cbeMichael Gottesman
10429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return false;
10439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
10449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
104581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// Turn objc_autoreleaseReturnValue into objc_autorelease if the result is not
104681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// used as a return value.
10479fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid
10480e385450fc62a69cf7c557173f2f5df132702379Michael GottesmanObjCARCOpt::OptimizeAutoreleaseRVCall(Function &F, Instruction *AutoreleaseRV,
10490e385450fc62a69cf7c557173f2f5df132702379Michael Gottesman                                      InstructionClass &Class) {
10509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Check for a return of the pointer value.
10519fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  const Value *Ptr = GetObjCArg(AutoreleaseRV);
1052126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman  SmallVector<const Value *, 2> Users;
1053126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman  Users.push_back(Ptr);
1054126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman  do {
1055126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman    Ptr = Users.pop_back_val();
1056126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman    for (Value::const_use_iterator UI = Ptr->use_begin(), UE = Ptr->use_end();
1057126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman         UI != UE; ++UI) {
1058126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman      const User *I = *UI;
1059126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman      if (isa<ReturnInst>(I) || GetBasicInstructionClass(I) == IC_RetainRV)
1060126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman        return;
1061126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman      if (isa<BitCastInst>(I))
1062126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman        Users.push_back(I);
1063126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman    }
1064126a54f1fa233d9da377a3e9f2ae85ff5fe34d9fDan Gohman  } while (!Users.empty());
10659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
10669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  Changed = true;
10679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  ++NumPeeps;
106848239c753abd4bdc9424f6df2b8ddd43840f93c3Michael Gottesman
106948239c753abd4bdc9424f6df2b8ddd43840f93c3Michael Gottesman  DEBUG(dbgs() << "ObjCARCOpt::OptimizeAutoreleaseRVCall: Transforming "
107048239c753abd4bdc9424f6df2b8ddd43840f93c3Michael Gottesman                  "objc_autoreleaseReturnValue => "
107148239c753abd4bdc9424f6df2b8ddd43840f93c3Michael Gottesman                  "objc_autorelease since its operand is not used as a return "
107248239c753abd4bdc9424f6df2b8ddd43840f93c3Michael Gottesman                  "value.\n"
107348239c753abd4bdc9424f6df2b8ddd43840f93c3Michael Gottesman                  "                                       Old: "
107448239c753abd4bdc9424f6df2b8ddd43840f93c3Michael Gottesman               << *AutoreleaseRV << "\n");
107548239c753abd4bdc9424f6df2b8ddd43840f93c3Michael Gottesman
1076e8c161a92451ad38919525ea73ae3c6936c24bdfMichael Gottesman  CallInst *AutoreleaseRVCI = cast<CallInst>(AutoreleaseRV);
1077e8c161a92451ad38919525ea73ae3c6936c24bdfMichael Gottesman  AutoreleaseRVCI->
10789fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    setCalledFunction(getAutoreleaseCallee(F.getParent()));
1079e8c161a92451ad38919525ea73ae3c6936c24bdfMichael Gottesman  AutoreleaseRVCI->setTailCall(false); // Never tail call objc_autorelease.
10800e385450fc62a69cf7c557173f2f5df132702379Michael Gottesman  Class = IC_Autorelease;
10812f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
108248239c753abd4bdc9424f6df2b8ddd43840f93c3Michael Gottesman  DEBUG(dbgs() << "                                       New: "
108348239c753abd4bdc9424f6df2b8ddd43840f93c3Michael Gottesman               << *AutoreleaseRV << "\n");
10842f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
10859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
10869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
108781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// Visit each call, one at a time, and make simplifications without doing any
108881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// additional analysis.
10899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid ObjCARCOpt::OptimizeIndividualCalls(Function &F) {
10909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Reset all the flags in preparation for recomputing them.
10919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  UsedInThisFunction = 0;
10929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
10939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Visit all objc_* calls in F.
10949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) {
10959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Instruction *Inst = &*I++;
10968f22c8b5e1f32bf253f968a81542a76dbfc3efc7Michael Gottesman
10979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    InstructionClass Class = GetBasicInstructionClass(Inst);
10989fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
1099268e0ffa78483512ad65002cb2081ab88b0f52a8Michael Gottesman    DEBUG(dbgs() << "ObjCARCOpt::OptimizeIndividualCalls: Visiting: Class: "
1100268e0ffa78483512ad65002cb2081ab88b0f52a8Michael Gottesman          << Class << "; " << *Inst << "\n");
110188ceb186f156136592c71021585e847c073612ccMichael Gottesman
11029fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    switch (Class) {
11039fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    default: break;
11049fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
11059fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // Delete no-op casts. These function calls have special semantics, but
11069fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // the semantics are entirely implemented via lowering in the front-end,
11079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // so by the time they reach the optimizer, they are just no-op calls
11089fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // which return their argument.
11099fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    //
11109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // There are gray areas here, as the ability to cast reference-counted
11119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // pointers to raw void* and back allows code to break ARC assumptions,
11129fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // however these are currently considered to be unimportant.
11139fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case IC_NoopCast:
11149fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Changed = true;
11159fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      ++NumNoops;
11164680abec929e5415da8a918debcee786389aa592Michael Gottesman      DEBUG(dbgs() << "ObjCARCOpt::OptimizeIndividualCalls: Erasing no-op cast:"
11174680abec929e5415da8a918debcee786389aa592Michael Gottesman                   " " << *Inst << "\n");
11189fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      EraseInstruction(Inst);
11199fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      continue;
11209fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
11219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // If the pointer-to-weak-pointer is null, it's undefined behavior.
11229fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case IC_StoreWeak:
11239fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case IC_LoadWeak:
11249fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case IC_LoadWeakRetained:
11259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case IC_InitWeak:
11269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case IC_DestroyWeak: {
11279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      CallInst *CI = cast<CallInst>(Inst);
11289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (isNullOrUndef(CI->getArgOperand(0))) {
1129d6bf201fa20a5cd3aa9f61767081d1d03d8aee3cDan Gohman        Changed = true;
1130db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner        Type *Ty = CI->getArgOperand(0)->getType();
11319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        new StoreInst(UndefValue::get(cast<PointerType>(Ty)->getElementType()),
11329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                      Constant::getNullValue(Ty),
11339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                      CI);
11342f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman        llvm::Value *NewValue = UndefValue::get(CI->getType());
1135e549492c3680814b31058b183d315d69fd9293deMichael Gottesman        DEBUG(dbgs() << "ObjCARCOpt::OptimizeIndividualCalls: A null "
1136e549492c3680814b31058b183d315d69fd9293deMichael Gottesman                        "pointer-to-weak-pointer is undefined behavior.\n"
1137e549492c3680814b31058b183d315d69fd9293deMichael Gottesman                        "                                     Old = " << *CI <<
1138e549492c3680814b31058b183d315d69fd9293deMichael Gottesman                        "\n                                     New = " <<
11392f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman                        *NewValue << "\n");
1140e549492c3680814b31058b183d315d69fd9293deMichael Gottesman        CI->replaceAllUsesWith(NewValue);
11419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        CI->eraseFromParent();
11429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        continue;
11439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
11449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      break;
11459fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
11469fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case IC_CopyWeak:
11479fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case IC_MoveWeak: {
11489fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      CallInst *CI = cast<CallInst>(Inst);
11499fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (isNullOrUndef(CI->getArgOperand(0)) ||
11509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          isNullOrUndef(CI->getArgOperand(1))) {
1151d6bf201fa20a5cd3aa9f61767081d1d03d8aee3cDan Gohman        Changed = true;
1152db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner        Type *Ty = CI->getArgOperand(0)->getType();
11539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        new StoreInst(UndefValue::get(cast<PointerType>(Ty)->getElementType()),
11549fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                      Constant::getNullValue(Ty),
11559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                      CI);
1156e549492c3680814b31058b183d315d69fd9293deMichael Gottesman
1157e549492c3680814b31058b183d315d69fd9293deMichael Gottesman        llvm::Value *NewValue = UndefValue::get(CI->getType());
1158e549492c3680814b31058b183d315d69fd9293deMichael Gottesman        DEBUG(dbgs() << "ObjCARCOpt::OptimizeIndividualCalls: A null "
1159e549492c3680814b31058b183d315d69fd9293deMichael Gottesman                        "pointer-to-weak-pointer is undefined behavior.\n"
1160e549492c3680814b31058b183d315d69fd9293deMichael Gottesman                        "                                     Old = " << *CI <<
1161e549492c3680814b31058b183d315d69fd9293deMichael Gottesman                        "\n                                     New = " <<
1162e549492c3680814b31058b183d315d69fd9293deMichael Gottesman                        *NewValue << "\n");
11632f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
1164e549492c3680814b31058b183d315d69fd9293deMichael Gottesman        CI->replaceAllUsesWith(NewValue);
11659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        CI->eraseFromParent();
11669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        continue;
11679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
11689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      break;
11699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
11709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case IC_Retain:
11719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      OptimizeRetainCall(F, Inst);
11729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      break;
11739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case IC_RetainRV:
11749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (OptimizeRetainRVCall(F, Inst))
11759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        continue;
11769fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      break;
11779fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case IC_AutoreleaseRV:
11780e385450fc62a69cf7c557173f2f5df132702379Michael Gottesman      OptimizeAutoreleaseRVCall(F, Inst, Class);
11799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      break;
11809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
11819fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
11829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // objc_autorelease(x) -> objc_release(x) if x is otherwise unused.
11839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (IsAutorelease(Class) && Inst->use_empty()) {
11849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      CallInst *Call = cast<CallInst>(Inst);
11859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      const Value *Arg = Call->getArgOperand(0);
11869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Arg = FindSingleUseIdentifiedObject(Arg);
11879fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (Arg) {
11889fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Changed = true;
11899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        ++NumAutoreleases;
11909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
11919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // Create the declaration lazily.
11929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        LLVMContext &C = Inst->getContext();
11939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        CallInst *NewCall =
11949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          CallInst::Create(getReleaseCallee(F.getParent()),
11959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                           Call->getArgOperand(0), "", Call);
11969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        NewCall->setMetadata(ImpreciseReleaseMDKind,
11979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                             MDNode::get(C, ArrayRef<Value *>()));
11982f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
119920d9fff206ebb21d08f61783462ca56d5efe0af9Michael Gottesman        DEBUG(dbgs() << "ObjCARCOpt::OptimizeIndividualCalls: Replacing "
120020d9fff206ebb21d08f61783462ca56d5efe0af9Michael Gottesman                        "objc_autorelease(x) with objc_release(x) since x is "
120120d9fff206ebb21d08f61783462ca56d5efe0af9Michael Gottesman                        "otherwise unused.\n"
1202795612702ec46412414b923a33e71fd3a080e826Michael Gottesman                        "                                     Old: " << *Call <<
120320d9fff206ebb21d08f61783462ca56d5efe0af9Michael Gottesman                        "\n                                     New: " <<
120420d9fff206ebb21d08f61783462ca56d5efe0af9Michael Gottesman                        *NewCall << "\n");
12052f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
12069fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        EraseInstruction(Call);
12079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Inst = NewCall;
12089fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Class = IC_Release;
12099fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
12109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
12119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
12129fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // For functions which can never be passed stack arguments, add
12139fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // a tail keyword.
12149fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (IsAlwaysTail(Class)) {
12159fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Changed = true;
1216817d4e942bf7e7ef51002eb905e5751b44c51223Michael Gottesman      DEBUG(dbgs() << "ObjCARCOpt::OptimizeIndividualCalls: Adding tail keyword"
1217817d4e942bf7e7ef51002eb905e5751b44c51223Michael Gottesman            " to function since it can never be passed stack args: " << *Inst <<
1218817d4e942bf7e7ef51002eb905e5751b44c51223Michael Gottesman            "\n");
12199fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      cast<CallInst>(Inst)->setTailCall();
12209fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
12219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
1222e8c161a92451ad38919525ea73ae3c6936c24bdfMichael Gottesman    // Ensure that functions that can never have a "tail" keyword due to the
1223e8c161a92451ad38919525ea73ae3c6936c24bdfMichael Gottesman    // semantics of ARC truly do not do so.
1224e8c161a92451ad38919525ea73ae3c6936c24bdfMichael Gottesman    if (IsNeverTail(Class)) {
1225e8c161a92451ad38919525ea73ae3c6936c24bdfMichael Gottesman      Changed = true;
12267899e47f205f32127ec2b6229ca587e996e0a08eMichael Gottesman      DEBUG(dbgs() << "ObjCARCOpt::OptimizeIndividualCalls: Removing tail "
12277899e47f205f32127ec2b6229ca587e996e0a08eMichael Gottesman            "keyword from function: " << *Inst <<
1228e8c161a92451ad38919525ea73ae3c6936c24bdfMichael Gottesman            "\n");
1229e8c161a92451ad38919525ea73ae3c6936c24bdfMichael Gottesman      cast<CallInst>(Inst)->setTailCall(false);
1230e8c161a92451ad38919525ea73ae3c6936c24bdfMichael Gottesman    }
1231e8c161a92451ad38919525ea73ae3c6936c24bdfMichael Gottesman
12329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // Set nounwind as needed.
12339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (IsNoThrow(Class)) {
12349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Changed = true;
123538bc25a52e7f0019c7339371f2eca080269dd6afMichael Gottesman      DEBUG(dbgs() << "ObjCARCOpt::OptimizeIndividualCalls: Found no throw"
123638bc25a52e7f0019c7339371f2eca080269dd6afMichael Gottesman            " class. Setting nounwind on: " << *Inst << "\n");
12379fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      cast<CallInst>(Inst)->setDoesNotThrow();
12389fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
12399fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
12409fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (!IsNoopOnNull(Class)) {
12419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      UsedInThisFunction |= 1 << Class;
12429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      continue;
12439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
12449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
12459fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    const Value *Arg = GetObjCArg(Inst);
12469fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
12479fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // ARC calls with null are no-ops. Delete them.
12489fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (isNullOrUndef(Arg)) {
12499fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Changed = true;
12509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      ++NumNoops;
1251fbe4d6b1fa256825ded9d9ebf1b6aeca3d1ff270Michael Gottesman      DEBUG(dbgs() << "ObjCARCOpt::OptimizeIndividualCalls: ARC calls with "
1252fbe4d6b1fa256825ded9d9ebf1b6aeca3d1ff270Michael Gottesman            " null are no-ops. Erasing: " << *Inst << "\n");
12539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      EraseInstruction(Inst);
12549fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      continue;
12559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
12569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
12579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // Keep track of which of retain, release, autorelease, and retain_block
12589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // are actually present in this function.
12599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    UsedInThisFunction |= 1 << Class;
12609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
12619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // If Arg is a PHI, and one or more incoming values to the
12629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // PHI are null, and the call is control-equivalent to the PHI, and there
12639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // are no relevant side effects between the PHI and the call, the call
12649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // could be pushed up to just those paths with non-null incoming values.
12659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // For now, don't bother splitting critical edges for this.
12669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    SmallVector<std::pair<Instruction *, const Value *>, 4> Worklist;
12679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Worklist.push_back(std::make_pair(Inst, Arg));
12689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    do {
12699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      std::pair<Instruction *, const Value *> Pair = Worklist.pop_back_val();
12709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Inst = Pair.first;
12719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Arg = Pair.second;
12729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
12739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      const PHINode *PN = dyn_cast<PHINode>(Arg);
12749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (!PN) continue;
12759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
12769fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // Determine if the PHI has any null operands, or any incoming
12779fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // critical edges.
12789fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      bool HasNull = false;
12799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      bool HasCriticalEdges = false;
12809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
12819fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Value *Incoming =
12829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          StripPointerCastsAndObjCCalls(PN->getIncomingValue(i));
12839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        if (isNullOrUndef(Incoming))
12849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          HasNull = true;
12859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        else if (cast<TerminatorInst>(PN->getIncomingBlock(i)->back())
12869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                   .getNumSuccessors() != 1) {
12879fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          HasCriticalEdges = true;
12889fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          break;
12899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        }
12909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
12919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // If we have null operands and no critical edges, optimize.
12929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (!HasCriticalEdges && HasNull) {
12939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        SmallPtrSet<Instruction *, 4> DependingInstructions;
12949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        SmallPtrSet<const BasicBlock *, 4> Visited;
12959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
12969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // Check that there is nothing that cares about the reference
12979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // count between the call and the phi.
1298511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman        switch (Class) {
1299511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman        case IC_Retain:
1300511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman        case IC_RetainBlock:
1301511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          // These can always be moved up.
1302511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          break;
1303511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman        case IC_Release:
13040daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman          // These can't be moved across things that care about the retain
13050daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman          // count.
1306511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          FindDependencies(NeedsPositiveRetainCount, Arg,
1307511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman                           Inst->getParent(), Inst,
1308511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman                           DependingInstructions, Visited, PA);
1309511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          break;
1310511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman        case IC_Autorelease:
1311511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          // These can't be moved across autorelease pool scope boundaries.
1312511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          FindDependencies(AutoreleasePoolBoundary, Arg,
1313511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman                           Inst->getParent(), Inst,
1314511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman                           DependingInstructions, Visited, PA);
1315511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          break;
1316511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman        case IC_RetainRV:
1317511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman        case IC_AutoreleaseRV:
1318511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          // Don't move these; the RV optimization depends on the autoreleaseRV
1319511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          // being tail called, and the retainRV being immediately after a call
1320511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          // (which might still happen if we get lucky with codegen layout, but
1321511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          // it's not worth taking the chance).
1322511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          continue;
1323511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman        default:
1324511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman          llvm_unreachable("Invalid dependence flavor");
1325511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman        }
1326511568dd1f9863de1633b0db8bb105f783e8ac50Dan Gohman
13279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        if (DependingInstructions.size() == 1 &&
13289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            *DependingInstructions.begin() == PN) {
13299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          Changed = true;
13309fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          ++NumPartialNoops;
13319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          // Clone the call into each predecessor that has a non-null value.
13329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          CallInst *CInst = cast<CallInst>(Inst);
1333db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner          Type *ParamTy = CInst->getArgOperand(0)->getType();
13349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
13359fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            Value *Incoming =
13369fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall              StripPointerCastsAndObjCCalls(PN->getIncomingValue(i));
13379fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            if (!isNullOrUndef(Incoming)) {
13389fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall              CallInst *Clone = cast<CallInst>(CInst->clone());
13399fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall              Value *Op = PN->getIncomingValue(i);
13409fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall              Instruction *InsertPos = &PN->getIncomingBlock(i)->back();
13419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall              if (Op->getType() != ParamTy)
13429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                Op = new BitCastInst(Op, ParamTy, "", InsertPos);
13439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall              Clone->setArgOperand(0, Op);
13449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall              Clone->insertBefore(InsertPos);
13455581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman
13465581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman              DEBUG(dbgs() << "ObjCARCOpt::OptimizeIndividualCalls: Cloning "
13475581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman                           << *CInst << "\n"
13485581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman                           "                                     And inserting "
13495581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman                           "clone at " << *InsertPos << "\n");
13509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall              Worklist.push_back(std::make_pair(Clone, Incoming));
13519fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            }
13529fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          }
13539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          // Erase the original call.
13545581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman          DEBUG(dbgs() << "Erasing: " << *CInst << "\n");
13559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          EraseInstruction(CInst);
13569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          continue;
13579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        }
13589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
13599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    } while (!Worklist.empty());
13609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
13610d3582b1d1bedde39f964420edd237583bc5a010Michael Gottesman  DEBUG(dbgs() << "ObjCARCOpt::OptimizeIndividualCalls: Finished List.\n");
13629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
13639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
136481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// Check for critical edges, loop boundaries, irreducible control flow, or
136581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// other CFG structures where moving code across the edge would result in it
136681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// being executed more.
13679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid
13689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallObjCARCOpt::CheckForCFGHazards(const BasicBlock *BB,
13699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                               DenseMap<const BasicBlock *, BBState> &BBStates,
13709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                               BBState &MyStates) const {
13719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // If any top-down local-use or possible-dec has a succ which is earlier in
13729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // the sequence, forget it.
137322cc4ccc9ea4a45d1f529c1bf48d61a88d3615deDan Gohman  for (BBState::ptr_iterator I = MyStates.top_down_ptr_begin(),
13749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       E = MyStates.top_down_ptr_end(); I != E; ++I)
13759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    switch (I->second.GetSeq()) {
13769fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    default: break;
13779fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case S_Use: {
13789fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      const Value *Arg = I->first;
13799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      const TerminatorInst *TI = cast<TerminatorInst>(&BB->back());
13809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      bool SomeSuccHasSame = false;
13819fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      bool AllSuccsHaveSame = true;
138222cc4ccc9ea4a45d1f529c1bf48d61a88d3615deDan Gohman      PtrState &S = I->second;
1383dbe266be35cfee0fbda5523ac578fef81e8fdfccDan Gohman      succ_const_iterator SI(TI), SE(TI, false);
1384dbe266be35cfee0fbda5523ac578fef81e8fdfccDan Gohman
1385dbe266be35cfee0fbda5523ac578fef81e8fdfccDan Gohman      for (; SI != SE; ++SI) {
138670e2968866aa09b4c164db77d310f5d43a588227Dan Gohman        Sequence SuccSSeq = S_None;
138770e2968866aa09b4c164db77d310f5d43a588227Dan Gohman        bool SuccSRRIKnownSafe = false;
13880daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman        // If VisitBottomUp has pointer information for this successor, take
13890daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman        // what we know about it.
1390447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman        DenseMap<const BasicBlock *, BBState>::iterator BBI =
1391447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman          BBStates.find(*SI);
1392447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman        assert(BBI != BBStates.end());
1393447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman        const PtrState &SuccS = BBI->second.getPtrBottomUpState(Arg);
1394447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman        SuccSSeq = SuccS.GetSeq();
1395447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman        SuccSRRIKnownSafe = SuccS.RRI.KnownSafe;
139670e2968866aa09b4c164db77d310f5d43a588227Dan Gohman        switch (SuccSSeq) {
13979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case S_None:
1398a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman        case S_CanRelease: {
139970e2968866aa09b4c164db77d310f5d43a588227Dan Gohman          if (!S.RRI.KnownSafe && !SuccSRRIKnownSafe) {
1400a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman            S.ClearSequenceProgress();
140170e2968866aa09b4c164db77d310f5d43a588227Dan Gohman            break;
140270e2968866aa09b4c164db77d310f5d43a588227Dan Gohman          }
1403a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman          continue;
1404a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman        }
14059fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case S_Use:
14069fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          SomeSuccHasSame = true;
14079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          break;
14089fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case S_Stop:
14099fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case S_Release:
14109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case S_MovableRelease:
141170e2968866aa09b4c164db77d310f5d43a588227Dan Gohman          if (!S.RRI.KnownSafe && !SuccSRRIKnownSafe)
1412a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman            AllSuccsHaveSame = false;
14139fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          break;
14149fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case S_Retain:
14159fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          llvm_unreachable("bottom-up pointer in retain state!");
14169fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        }
1417a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman      }
14189fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // If the state at the other end of any of the successor edges
14199fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // matches the current state, require all edges to match. This
14209fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // guards against loops in the middle of a sequence.
14219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (SomeSuccHasSame && !AllSuccsHaveSame)
1422a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman        S.ClearSequenceProgress();
14232e68beb36afad1fbf578b10a012e655690c47120Dan Gohman      break;
14249fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
14259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    case S_CanRelease: {
14269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      const Value *Arg = I->first;
14279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      const TerminatorInst *TI = cast<TerminatorInst>(&BB->back());
14289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      bool SomeSuccHasSame = false;
14299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      bool AllSuccsHaveSame = true;
143022cc4ccc9ea4a45d1f529c1bf48d61a88d3615deDan Gohman      PtrState &S = I->second;
1431dbe266be35cfee0fbda5523ac578fef81e8fdfccDan Gohman      succ_const_iterator SI(TI), SE(TI, false);
1432dbe266be35cfee0fbda5523ac578fef81e8fdfccDan Gohman
1433dbe266be35cfee0fbda5523ac578fef81e8fdfccDan Gohman      for (; SI != SE; ++SI) {
143470e2968866aa09b4c164db77d310f5d43a588227Dan Gohman        Sequence SuccSSeq = S_None;
143570e2968866aa09b4c164db77d310f5d43a588227Dan Gohman        bool SuccSRRIKnownSafe = false;
14360daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman        // If VisitBottomUp has pointer information for this successor, take
14370daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman        // what we know about it.
1438447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman        DenseMap<const BasicBlock *, BBState>::iterator BBI =
1439447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman          BBStates.find(*SI);
1440447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman        assert(BBI != BBStates.end());
1441447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman        const PtrState &SuccS = BBI->second.getPtrBottomUpState(Arg);
1442447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman        SuccSSeq = SuccS.GetSeq();
1443447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman        SuccSRRIKnownSafe = SuccS.RRI.KnownSafe;
144470e2968866aa09b4c164db77d310f5d43a588227Dan Gohman        switch (SuccSSeq) {
1445a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman        case S_None: {
144670e2968866aa09b4c164db77d310f5d43a588227Dan Gohman          if (!S.RRI.KnownSafe && !SuccSRRIKnownSafe) {
1447a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman            S.ClearSequenceProgress();
144870e2968866aa09b4c164db77d310f5d43a588227Dan Gohman            break;
144970e2968866aa09b4c164db77d310f5d43a588227Dan Gohman          }
1450a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman          continue;
1451a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman        }
14529fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case S_CanRelease:
14539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          SomeSuccHasSame = true;
14549fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          break;
14559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case S_Stop:
14569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case S_Release:
14579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case S_MovableRelease:
14589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case S_Use:
145970e2968866aa09b4c164db77d310f5d43a588227Dan Gohman          if (!S.RRI.KnownSafe && !SuccSRRIKnownSafe)
1460a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman            AllSuccsHaveSame = false;
14619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          break;
14629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case S_Retain:
14639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          llvm_unreachable("bottom-up pointer in retain state!");
14649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        }
1465a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman      }
14669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // If the state at the other end of any of the successor edges
14679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // matches the current state, require all edges to match. This
14689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // guards against loops in the middle of a sequence.
14699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (SomeSuccHasSame && !AllSuccsHaveSame)
1470a7f7db2ebd4d3ca5c4e50cb2f9047dd85a34c6c8Dan Gohman        S.ClearSequenceProgress();
14712e68beb36afad1fbf578b10a012e655690c47120Dan Gohman      break;
14729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
14739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
14749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
14759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
14769fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallbool
1477c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan GohmanObjCARCOpt::VisitInstructionBottomUp(Instruction *Inst,
1478fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman                                     BasicBlock *BB,
1479c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman                                     MapVector<Value *, RRInfo> &Retains,
1480c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman                                     BBState &MyStates) {
1481c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  bool NestingDetected = false;
1482c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  InstructionClass Class = GetInstructionClass(Inst);
1483c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  const Value *Arg = 0;
1484c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1485c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  switch (Class) {
1486c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_Release: {
1487c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    Arg = GetObjCArg(Inst);
1488c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1489c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    PtrState &S = MyStates.getPtrBottomUpState(Arg);
1490c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1491c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // If we see two releases in a row on the same pointer. If so, make
1492c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // a note, and we'll cicle back to revisit it after we've
1493c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // hopefully eliminated the second release, which may allow us to
1494c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // eliminate the first release too.
1495c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // Theoretically we could implement removal of nested retain+release
1496c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // pairs by making PtrState hold a stack of states, but this is
1497c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // simple and avoids adding overhead for the non-nested case.
1498cf14005185778d823631a2367401e65b5e4802d8Michael Gottesman    if (S.GetSeq() == S_Release || S.GetSeq() == S_MovableRelease) {
1499cf14005185778d823631a2367401e65b5e4802d8Michael Gottesman      DEBUG(dbgs() << "ObjCARCOpt::VisitInstructionBottomUp: Found nested "
1500cf14005185778d823631a2367401e65b5e4802d8Michael Gottesman                      "releases (i.e. a release pair)\n");
1501c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      NestingDetected = true;
1502cf14005185778d823631a2367401e65b5e4802d8Michael Gottesman    }
1503c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1504c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    MDNode *ReleaseMetadata = Inst->getMetadata(ImpreciseReleaseMDKind);
150550ade659829269f0338cd1bfa0a574dcec62562eDan Gohman    S.ResetSequenceProgress(ReleaseMetadata ? S_MovableRelease : S_Release);
1506c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    S.RRI.ReleaseMetadata = ReleaseMetadata;
1507230768bd1316a012e88ac62689589fe5e2f10456Dan Gohman    S.RRI.KnownSafe = S.IsKnownIncremented();
1508c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    S.RRI.IsTailCallRelease = cast<CallInst>(Inst)->isTailCall();
1509c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    S.RRI.Calls.insert(Inst);
1510c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1511230768bd1316a012e88ac62689589fe5e2f10456Dan Gohman    S.SetKnownPositiveRefCount();
1512c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    break;
1513c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  }
1514c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_RetainBlock:
1515c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // An objc_retainBlock call with just a use may need to be kept,
1516c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // because it may be copying a block from the stack to the heap.
1517c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    if (!IsRetainBlockOptimizable(Inst))
1518c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      break;
1519c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // FALLTHROUGH
1520c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_Retain:
1521c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_RetainRV: {
1522c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    Arg = GetObjCArg(Inst);
1523c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1524c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    PtrState &S = MyStates.getPtrBottomUpState(Arg);
152550ade659829269f0338cd1bfa0a574dcec62562eDan Gohman    S.SetKnownPositiveRefCount();
1526c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1527c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    switch (S.GetSeq()) {
1528c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Stop:
1529c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Release:
1530c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_MovableRelease:
1531c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Use:
1532c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      S.RRI.ReverseInsertPts.clear();
1533c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      // FALL THROUGH
1534c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_CanRelease:
1535c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      // Don't do retain+release tracking for IC_RetainRV, because it's
1536c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      // better to let it remain as the first instruction after a call.
1537c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      if (Class != IC_RetainRV) {
1538c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        S.RRI.IsRetainBlock = Class == IC_RetainBlock;
1539c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        Retains[Inst] = S.RRI;
1540c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      }
1541c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      S.ClearSequenceProgress();
1542c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      break;
1543c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_None:
1544c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      break;
1545c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Retain:
1546c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      llvm_unreachable("bottom-up pointer in retain state!");
1547c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    }
1548c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    return NestingDetected;
1549c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  }
1550c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_AutoreleasepoolPop:
1551c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // Conservatively, clear MyStates for all known pointers.
1552c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    MyStates.clearBottomUpPointers();
1553c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    return NestingDetected;
1554c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_AutoreleasepoolPush:
1555c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_None:
1556c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // These are irrelevant.
1557c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    return NestingDetected;
1558c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  default:
1559c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    break;
1560c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  }
1561c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1562c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  // Consider any other possible effects of this instruction on each
1563c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  // pointer being tracked.
1564c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  for (BBState::ptr_iterator MI = MyStates.bottom_up_ptr_begin(),
1565c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman       ME = MyStates.bottom_up_ptr_end(); MI != ME; ++MI) {
1566c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    const Value *Ptr = MI->first;
1567c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    if (Ptr == Arg)
1568c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      continue; // Handled above.
1569c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    PtrState &S = MI->second;
1570c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    Sequence Seq = S.GetSeq();
1571c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1572c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // Check for possible releases.
1573c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    if (CanAlterRefCount(Inst, Ptr, PA, Class)) {
157450ade659829269f0338cd1bfa0a574dcec62562eDan Gohman      S.ClearRefCount();
1575c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      switch (Seq) {
1576c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      case S_Use:
1577c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        S.SetSeq(S_CanRelease);
1578c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        continue;
1579c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      case S_CanRelease:
1580c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      case S_Release:
1581c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      case S_MovableRelease:
1582c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      case S_Stop:
1583c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      case S_None:
1584c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        break;
1585c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      case S_Retain:
1586c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        llvm_unreachable("bottom-up pointer in retain state!");
1587c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      }
1588c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    }
1589c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1590c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // Check for possible direct uses.
1591c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    switch (Seq) {
1592c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Release:
1593c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_MovableRelease:
1594c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      if (CanUse(Inst, Ptr, PA, Class)) {
1595c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        assert(S.RRI.ReverseInsertPts.empty());
1596fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman        // If this is an invoke instruction, we're scanning it as part of
1597fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman        // one of its successor blocks, since we can't insert code after it
1598fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman        // in its own block, and we don't want to split critical edges.
1599fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman        if (isa<InvokeInst>(Inst))
1600fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman          S.RRI.ReverseInsertPts.insert(BB->getFirstInsertionPt());
1601fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman        else
1602b54a5eda6d9a1f50c1861b53e19be84994e586efFrancois Pichet          S.RRI.ReverseInsertPts.insert(llvm::next(BasicBlock::iterator(Inst)));
1603c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        S.SetSeq(S_Use);
1604c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      } else if (Seq == S_Release &&
1605c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman                 (Class == IC_User || Class == IC_CallOrUser)) {
1606c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        // Non-movable releases depend on any possible objc pointer use.
1607c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        S.SetSeq(S_Stop);
1608c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        assert(S.RRI.ReverseInsertPts.empty());
1609fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman        // As above; handle invoke specially.
1610fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman        if (isa<InvokeInst>(Inst))
1611fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman          S.RRI.ReverseInsertPts.insert(BB->getFirstInsertionPt());
1612fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman        else
1613b54a5eda6d9a1f50c1861b53e19be84994e586efFrancois Pichet          S.RRI.ReverseInsertPts.insert(llvm::next(BasicBlock::iterator(Inst)));
1614c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      }
1615c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      break;
1616c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Stop:
1617c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      if (CanUse(Inst, Ptr, PA, Class))
1618c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        S.SetSeq(S_Use);
1619c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      break;
1620c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_CanRelease:
1621c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Use:
1622c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_None:
1623c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      break;
1624c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Retain:
1625c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      llvm_unreachable("bottom-up pointer in retain state!");
1626c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    }
1627c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  }
1628c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1629c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  return NestingDetected;
1630c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman}
1631c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1632c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohmanbool
16339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallObjCARCOpt::VisitBottomUp(BasicBlock *BB,
16349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                          DenseMap<const BasicBlock *, BBState> &BBStates,
16359fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                          MapVector<Value *, RRInfo> &Retains) {
16369fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  bool NestingDetected = false;
16379fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  BBState &MyStates = BBStates[BB];
16389fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
16399fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Merge the states from each successor to compute the initial state
16409fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // for the current block.
164140e466091e76f4608ad09789546d3012c8c11c3eDan Gohman  BBState::edge_iterator SI(MyStates.succ_begin()),
164240e466091e76f4608ad09789546d3012c8c11c3eDan Gohman                         SE(MyStates.succ_end());
164340e466091e76f4608ad09789546d3012c8c11c3eDan Gohman  if (SI != SE) {
1644eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    const BasicBlock *Succ = *SI;
1645eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    DenseMap<const BasicBlock *, BBState>::iterator I = BBStates.find(Succ);
1646eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    assert(I != BBStates.end());
1647eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    MyStates.InitFromSucc(I->second);
1648eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    ++SI;
1649eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    for (; SI != SE; ++SI) {
1650eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      Succ = *SI;
1651eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      I = BBStates.find(Succ);
1652eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      assert(I != BBStates.end());
1653eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      MyStates.MergeSucc(I->second);
1654eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    }
1655dbe266be35cfee0fbda5523ac578fef81e8fdfccDan Gohman  }
16569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
16579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Visit all the instructions, bottom-up.
16589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (BasicBlock::iterator I = BB->end(), E = BB->begin(); I != E; --I) {
16599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Instruction *Inst = llvm::prior(I);
1660fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman
1661fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman    // Invoke instructions are visited as part of their successors (below).
1662fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman    if (isa<InvokeInst>(Inst))
1663fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman      continue;
1664fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman
1665cf14005185778d823631a2367401e65b5e4802d8Michael Gottesman    DEBUG(dbgs() << "ObjCARCOpt::VisitButtonUp: Visiting " << *Inst << "\n");
1666cf14005185778d823631a2367401e65b5e4802d8Michael Gottesman
1667fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman    NestingDetected |= VisitInstructionBottomUp(Inst, BB, Retains, MyStates);
1668fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman  }
1669fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman
1670447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman  // If there's a predecessor with an invoke, visit the invoke as if it were
1671447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman  // part of this block, since we can't insert code after an invoke in its own
1672447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman  // block, and we don't want to split critical edges.
1673eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman  for (BBState::edge_iterator PI(MyStates.pred_begin()),
1674eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman       PE(MyStates.pred_end()); PI != PE; ++PI) {
1675fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman    BasicBlock *Pred = *PI;
1676447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman    if (InvokeInst *II = dyn_cast<InvokeInst>(&Pred->back()))
1677447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman      NestingDetected |= VisitInstructionBottomUp(II, BB, Retains, MyStates);
1678c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  }
16799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
1680c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  return NestingDetected;
1681c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman}
16829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
1683c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohmanbool
1684c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan GohmanObjCARCOpt::VisitInstructionTopDown(Instruction *Inst,
1685c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman                                    DenseMap<Value *, RRInfo> &Releases,
1686c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman                                    BBState &MyStates) {
1687c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  bool NestingDetected = false;
1688c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  InstructionClass Class = GetInstructionClass(Inst);
1689c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  const Value *Arg = 0;
16909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
1691c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  switch (Class) {
1692c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_RetainBlock:
1693c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // An objc_retainBlock call with just a use may need to be kept,
1694c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // because it may be copying a block from the stack to the heap.
1695c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    if (!IsRetainBlockOptimizable(Inst))
1696c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      break;
1697c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // FALLTHROUGH
1698c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_Retain:
1699c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_RetainRV: {
1700c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    Arg = GetObjCArg(Inst);
1701c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1702c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    PtrState &S = MyStates.getPtrTopDownState(Arg);
1703c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1704c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // Don't do retain+release tracking for IC_RetainRV, because it's
1705c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // better to let it remain as the first instruction after a call.
1706c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    if (Class != IC_RetainRV) {
1707c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      // If we see two retains in a row on the same pointer. If so, make
17089fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // a note, and we'll cicle back to revisit it after we've
1709c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      // hopefully eliminated the second retain, which may allow us to
1710c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      // eliminate the first retain too.
17119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // Theoretically we could implement removal of nested retain+release
17129fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // pairs by making PtrState hold a stack of states, but this is
17139fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // simple and avoids adding overhead for the non-nested case.
1714c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      if (S.GetSeq() == S_Retain)
17159fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        NestingDetected = true;
17169fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
171750ade659829269f0338cd1bfa0a574dcec62562eDan Gohman      S.ResetSequenceProgress(S_Retain);
1718c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      S.RRI.IsRetainBlock = Class == IC_RetainBlock;
1719230768bd1316a012e88ac62689589fe5e2f10456Dan Gohman      S.RRI.KnownSafe = S.IsKnownIncremented();
17209fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      S.RRI.Calls.insert(Inst);
1721c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    }
17229fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
1723230768bd1316a012e88ac62689589fe5e2f10456Dan Gohman    S.SetKnownPositiveRefCount();
1724c72d3be38915728142d13f982eeef218e42f21aaDan Gohman
1725c72d3be38915728142d13f982eeef218e42f21aaDan Gohman    // A retain can be a potential use; procede to the generic checking
1726c72d3be38915728142d13f982eeef218e42f21aaDan Gohman    // code below.
1727c72d3be38915728142d13f982eeef218e42f21aaDan Gohman    break;
1728c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  }
1729c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_Release: {
1730c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    Arg = GetObjCArg(Inst);
1731c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1732c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    PtrState &S = MyStates.getPtrTopDownState(Arg);
1733230768bd1316a012e88ac62689589fe5e2f10456Dan Gohman    S.ClearRefCount();
1734c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1735c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    switch (S.GetSeq()) {
1736c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Retain:
1737c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_CanRelease:
1738c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      S.RRI.ReverseInsertPts.clear();
1739c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      // FALL THROUGH
1740c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Use:
1741c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      S.RRI.ReleaseMetadata = Inst->getMetadata(ImpreciseReleaseMDKind);
1742c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      S.RRI.IsTailCallRelease = cast<CallInst>(Inst)->isTailCall();
1743c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      Releases[Inst] = S.RRI;
1744c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      S.ClearSequenceProgress();
17459fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      break;
1746c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_None:
1747c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      break;
1748c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Stop:
1749c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Release:
1750c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_MovableRelease:
1751c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      llvm_unreachable("top-down pointer in release state!");
17529fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
1753c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    break;
1754c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  }
1755c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_AutoreleasepoolPop:
1756c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // Conservatively, clear MyStates for all known pointers.
1757c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    MyStates.clearTopDownPointers();
1758c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    return NestingDetected;
1759c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_AutoreleasepoolPush:
1760c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  case IC_None:
1761c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // These are irrelevant.
1762c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    return NestingDetected;
1763c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  default:
1764c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    break;
1765c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  }
17669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
1767c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  // Consider any other possible effects of this instruction on each
1768c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  // pointer being tracked.
1769c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman  for (BBState::ptr_iterator MI = MyStates.top_down_ptr_begin(),
1770c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman       ME = MyStates.top_down_ptr_end(); MI != ME; ++MI) {
1771c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    const Value *Ptr = MI->first;
1772c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    if (Ptr == Arg)
1773c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      continue; // Handled above.
1774c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    PtrState &S = MI->second;
1775c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    Sequence Seq = S.GetSeq();
1776c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1777c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // Check for possible releases.
1778c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    if (CanAlterRefCount(Inst, Ptr, PA, Class)) {
177950ade659829269f0338cd1bfa0a574dcec62562eDan Gohman      S.ClearRefCount();
1780c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      switch (Seq) {
1781c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      case S_Retain:
1782c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        S.SetSeq(S_CanRelease);
1783c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        assert(S.RRI.ReverseInsertPts.empty());
1784c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        S.RRI.ReverseInsertPts.insert(Inst);
17859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
1786c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        // One call can't cause a transition from S_Retain to S_CanRelease
1787c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        // and S_CanRelease to S_Use. If we've made the first transition,
1788c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        // we're done.
1789c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        continue;
17909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case S_Use:
17919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case S_CanRelease:
17929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case S_None:
17939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        break;
1794c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      case S_Stop:
17959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case S_Release:
17969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case S_MovableRelease:
1797c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        llvm_unreachable("top-down pointer in release state!");
17989fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
17999fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
1800c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman
1801c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    // Check for possible direct uses.
1802c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    switch (Seq) {
1803c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_CanRelease:
1804c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      if (CanUse(Inst, Ptr, PA, Class))
1805c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman        S.SetSeq(S_Use);
1806c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      break;
1807c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Retain:
1808c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Use:
1809c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_None:
1810c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      break;
1811c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Stop:
1812c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_Release:
1813c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    case S_MovableRelease:
1814c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman      llvm_unreachable("top-down pointer in release state!");
1815c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    }
18169fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
18179fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
18189fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return NestingDetected;
18199fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
18209fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
18219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallbool
18229fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallObjCARCOpt::VisitTopDown(BasicBlock *BB,
18239fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                         DenseMap<const BasicBlock *, BBState> &BBStates,
18249fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                         DenseMap<Value *, RRInfo> &Releases) {
18259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  bool NestingDetected = false;
18269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  BBState &MyStates = BBStates[BB];
18279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
18289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Merge the states from each predecessor to compute the initial state
18299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // for the current block.
183040e466091e76f4608ad09789546d3012c8c11c3eDan Gohman  BBState::edge_iterator PI(MyStates.pred_begin()),
183140e466091e76f4608ad09789546d3012c8c11c3eDan Gohman                         PE(MyStates.pred_end());
183240e466091e76f4608ad09789546d3012c8c11c3eDan Gohman  if (PI != PE) {
1833eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    const BasicBlock *Pred = *PI;
1834eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    DenseMap<const BasicBlock *, BBState>::iterator I = BBStates.find(Pred);
1835eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    assert(I != BBStates.end());
1836eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    MyStates.InitFromPred(I->second);
1837eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    ++PI;
1838eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    for (; PI != PE; ++PI) {
1839eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      Pred = *PI;
1840eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      I = BBStates.find(Pred);
1841eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      assert(I != BBStates.end());
1842eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      MyStates.MergePred(I->second);
1843eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    }
1844eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman  }
18459fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
18469fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Visit all the instructions, top-down.
18479fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
18489fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Instruction *Inst = I;
1849cf14005185778d823631a2367401e65b5e4802d8Michael Gottesman
1850cf14005185778d823631a2367401e65b5e4802d8Michael Gottesman    DEBUG(dbgs() << "ObjCARCOpt::VisitTopDown: Visiting " << *Inst << "\n");
1851cf14005185778d823631a2367401e65b5e4802d8Michael Gottesman
1852c7f5c6e0e3a25aa5f6320766dd1bb29371e6948dDan Gohman    NestingDetected |= VisitInstructionTopDown(Inst, Releases, MyStates);
18539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
18549fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
18559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  CheckForCFGHazards(BB, BBStates, MyStates);
18569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return NestingDetected;
18579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
18589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
185959a1c93e955c366084742ceca65e7b1afd8772acDan Gohmanstatic void
186059a1c93e955c366084742ceca65e7b1afd8772acDan GohmanComputePostOrders(Function &F,
186159a1c93e955c366084742ceca65e7b1afd8772acDan Gohman                  SmallVectorImpl<BasicBlock *> &PostOrder,
1862eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman                  SmallVectorImpl<BasicBlock *> &ReverseCFGPostOrder,
1863eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman                  unsigned NoObjCARCExceptionsMDKind,
1864eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman                  DenseMap<const BasicBlock *, BBState> &BBStates) {
186581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  /// The visited set, for doing DFS walks.
1866d8e48c48215c8aaa87b19245efac8a490c693d17Dan Gohman  SmallPtrSet<BasicBlock *, 16> Visited;
186759a1c93e955c366084742ceca65e7b1afd8772acDan Gohman
186859a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  // Do DFS, computing the PostOrder.
186959a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  SmallPtrSet<BasicBlock *, 16> OnStack;
187059a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  SmallVector<std::pair<BasicBlock *, succ_iterator>, 16> SuccStack;
1871eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman
1872eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman  // Functions always have exactly one entry block, and we don't have
1873eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman  // any other block that we treat like an entry block.
187459a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  BasicBlock *EntryBB = &F.getEntryBlock();
18750daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman  BBState &MyStates = BBStates[EntryBB];
18760daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman  MyStates.SetAsEntry();
18770daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman  TerminatorInst *EntryTI = cast<TerminatorInst>(&EntryBB->back());
18780daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman  SuccStack.push_back(std::make_pair(EntryBB, succ_iterator(EntryTI)));
187959a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  Visited.insert(EntryBB);
188059a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  OnStack.insert(EntryBB);
188159a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  do {
188259a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  dfs_next_succ:
1883eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    BasicBlock *CurrBB = SuccStack.back().first;
1884eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    TerminatorInst *TI = cast<TerminatorInst>(&CurrBB->back());
1885eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    succ_iterator SE(TI, false);
18860daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman
1887eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    while (SuccStack.back().second != SE) {
1888eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      BasicBlock *SuccBB = *SuccStack.back().second++;
1889eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      if (Visited.insert(SuccBB)) {
18900daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman        TerminatorInst *TI = cast<TerminatorInst>(&SuccBB->back());
18910daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman        SuccStack.push_back(std::make_pair(SuccBB, succ_iterator(TI)));
1892eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman        BBStates[CurrBB].addSucc(SuccBB);
18930daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman        BBState &SuccStates = BBStates[SuccBB];
18940daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman        SuccStates.addPred(CurrBB);
1895eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman        OnStack.insert(SuccBB);
189659a1c93e955c366084742ceca65e7b1afd8772acDan Gohman        goto dfs_next_succ;
189759a1c93e955c366084742ceca65e7b1afd8772acDan Gohman      }
1898eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman
1899eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      if (!OnStack.count(SuccBB)) {
1900eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman        BBStates[CurrBB].addSucc(SuccBB);
1901eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman        BBStates[SuccBB].addPred(CurrBB);
1902eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      }
190359a1c93e955c366084742ceca65e7b1afd8772acDan Gohman    }
1904eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    OnStack.erase(CurrBB);
1905eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    PostOrder.push_back(CurrBB);
1906eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    SuccStack.pop_back();
190759a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  } while (!SuccStack.empty());
190859a1c93e955c366084742ceca65e7b1afd8772acDan Gohman
190959a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  Visited.clear();
191059a1c93e955c366084742ceca65e7b1afd8772acDan Gohman
1911eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman  // Do reverse-CFG DFS, computing the reverse-CFG PostOrder.
1912eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman  // Functions may have many exits, and there also blocks which we treat
1913eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman  // as exits due to ignored edges.
1914eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman  SmallVector<std::pair<BasicBlock *, BBState::edge_iterator>, 16> PredStack;
1915d8e48c48215c8aaa87b19245efac8a490c693d17Dan Gohman  for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
1916eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    BasicBlock *ExitBB = I;
1917eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    BBState &MyStates = BBStates[ExitBB];
1918eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    if (!MyStates.isExit())
1919eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      continue;
192059a1c93e955c366084742ceca65e7b1afd8772acDan Gohman
1921447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman    MyStates.SetAsExit();
1922eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman
1923eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman    PredStack.push_back(std::make_pair(ExitBB, MyStates.pred_begin()));
192459a1c93e955c366084742ceca65e7b1afd8772acDan Gohman    Visited.insert(ExitBB);
192559a1c93e955c366084742ceca65e7b1afd8772acDan Gohman    while (!PredStack.empty()) {
192659a1c93e955c366084742ceca65e7b1afd8772acDan Gohman    reverse_dfs_next_succ:
1927eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      BBState::edge_iterator PE = BBStates[PredStack.back().first].pred_end();
1928eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman      while (PredStack.back().second != PE) {
192959a1c93e955c366084742ceca65e7b1afd8772acDan Gohman        BasicBlock *BB = *PredStack.back().second++;
193059a1c93e955c366084742ceca65e7b1afd8772acDan Gohman        if (Visited.insert(BB)) {
1931eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman          PredStack.push_back(std::make_pair(BB, BBStates[BB].pred_begin()));
193259a1c93e955c366084742ceca65e7b1afd8772acDan Gohman          goto reverse_dfs_next_succ;
193359a1c93e955c366084742ceca65e7b1afd8772acDan Gohman        }
193459a1c93e955c366084742ceca65e7b1afd8772acDan Gohman      }
193559a1c93e955c366084742ceca65e7b1afd8772acDan Gohman      ReverseCFGPostOrder.push_back(PredStack.pop_back_val().first);
193659a1c93e955c366084742ceca65e7b1afd8772acDan Gohman    }
1937d8e48c48215c8aaa87b19245efac8a490c693d17Dan Gohman  }
193859a1c93e955c366084742ceca65e7b1afd8772acDan Gohman}
193959a1c93e955c366084742ceca65e7b1afd8772acDan Gohman
194081c6121699a66b3e84f7b794b375095a39584701Michael Gottesman// Visit the function both top-down and bottom-up.
194159a1c93e955c366084742ceca65e7b1afd8772acDan Gohmanbool
194259a1c93e955c366084742ceca65e7b1afd8772acDan GohmanObjCARCOpt::Visit(Function &F,
194359a1c93e955c366084742ceca65e7b1afd8772acDan Gohman                  DenseMap<const BasicBlock *, BBState> &BBStates,
194459a1c93e955c366084742ceca65e7b1afd8772acDan Gohman                  MapVector<Value *, RRInfo> &Retains,
194559a1c93e955c366084742ceca65e7b1afd8772acDan Gohman                  DenseMap<Value *, RRInfo> &Releases) {
194659a1c93e955c366084742ceca65e7b1afd8772acDan Gohman
194759a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  // Use reverse-postorder traversals, because we magically know that loops
194859a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  // will be well behaved, i.e. they won't repeatedly call retain on a single
194959a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  // pointer without doing a release. We can't use the ReversePostOrderTraversal
195059a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  // class here because we want the reverse-CFG postorder to consider each
195159a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  // function exit point, and we want to ignore selected cycle edges.
195259a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  SmallVector<BasicBlock *, 16> PostOrder;
195359a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  SmallVector<BasicBlock *, 16> ReverseCFGPostOrder;
1954eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman  ComputePostOrders(F, PostOrder, ReverseCFGPostOrder,
1955eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman                    NoObjCARCExceptionsMDKind,
1956eeeb7752a8eb13f799d33046246b6826990119f1Dan Gohman                    BBStates);
195759a1c93e955c366084742ceca65e7b1afd8772acDan Gohman
195859a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  // Use reverse-postorder on the reverse CFG for bottom-up.
19599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  bool BottomUpNestingDetected = false;
1960b48ef3a3ec7f527b0c76e7fbb37bbaac63b7c6aaDan Gohman  for (SmallVectorImpl<BasicBlock *>::const_reverse_iterator I =
196159a1c93e955c366084742ceca65e7b1afd8772acDan Gohman       ReverseCFGPostOrder.rbegin(), E = ReverseCFGPostOrder.rend();
196259a1c93e955c366084742ceca65e7b1afd8772acDan Gohman       I != E; ++I)
196359a1c93e955c366084742ceca65e7b1afd8772acDan Gohman    BottomUpNestingDetected |= VisitBottomUp(*I, BBStates, Retains);
19649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
196559a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  // Use reverse-postorder for top-down.
19669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  bool TopDownNestingDetected = false;
196759a1c93e955c366084742ceca65e7b1afd8772acDan Gohman  for (SmallVectorImpl<BasicBlock *>::const_reverse_iterator I =
196859a1c93e955c366084742ceca65e7b1afd8772acDan Gohman       PostOrder.rbegin(), E = PostOrder.rend();
196959a1c93e955c366084742ceca65e7b1afd8772acDan Gohman       I != E; ++I)
197059a1c93e955c366084742ceca65e7b1afd8772acDan Gohman    TopDownNestingDetected |= VisitTopDown(*I, BBStates, Releases);
19719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
19729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return TopDownNestingDetected && BottomUpNestingDetected;
19739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
19749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
197581c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// Move the calls in RetainsToMove and ReleasesToMove.
19769fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid ObjCARCOpt::MoveCalls(Value *Arg,
19779fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                           RRInfo &RetainsToMove,
19789fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                           RRInfo &ReleasesToMove,
19799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                           MapVector<Value *, RRInfo> &Retains,
19809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                           DenseMap<Value *, RRInfo> &Releases,
19814428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman                           SmallVectorImpl<Instruction *> &DeadInsts,
19824428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman                           Module *M) {
1983db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *ArgTy = Arg->getType();
19844428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman  Type *ParamTy = PointerType::getUnqual(Type::getInt8Ty(ArgTy->getContext()));
19859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
19869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Insert the new retain and release calls.
19879fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (SmallPtrSet<Instruction *, 2>::const_iterator
19889fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       PI = ReleasesToMove.ReverseInsertPts.begin(),
19899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       PE = ReleasesToMove.ReverseInsertPts.end(); PI != PE; ++PI) {
19909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Instruction *InsertPt = *PI;
19919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Value *MyArg = ArgTy == ParamTy ? Arg :
19929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                   new BitCastInst(Arg, ParamTy, "", InsertPt);
19939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    CallInst *Call =
19949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      CallInst::Create(RetainsToMove.IsRetainBlock ?
19954428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman                         getRetainBlockCallee(M) : getRetainCallee(M),
19969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                       MyArg, "", InsertPt);
19979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Call->setDoesNotThrow();
199879522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman    if (RetainsToMove.IsRetainBlock)
1999a974beaa1f63394a67c38c66ff0f39a759c7998fDan Gohman      Call->setMetadata(CopyOnEscapeMDKind,
2000a974beaa1f63394a67c38c66ff0f39a759c7998fDan Gohman                        MDNode::get(M->getContext(), ArrayRef<Value *>()));
200179522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman    else
20029fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Call->setTailCall();
20035581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman
20045581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman    DEBUG(dbgs() << "ObjCARCOpt::MoveCalls: Inserting new Release: " << *Call
20055581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman                 << "\n"
20065581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman                    "                       At insertion point: " << *InsertPt
20075581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman                 << "\n");
20089fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
20099fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (SmallPtrSet<Instruction *, 2>::const_iterator
20109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       PI = RetainsToMove.ReverseInsertPts.begin(),
20119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       PE = RetainsToMove.ReverseInsertPts.end(); PI != PE; ++PI) {
2012fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman    Instruction *InsertPt = *PI;
2013fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman    Value *MyArg = ArgTy == ParamTy ? Arg :
2014fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman                   new BitCastInst(Arg, ParamTy, "", InsertPt);
2015fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman    CallInst *Call = CallInst::Create(getReleaseCallee(M), MyArg,
2016fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman                                      "", InsertPt);
2017fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman    // Attach a clang.imprecise_release metadata tag, if appropriate.
2018fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman    if (MDNode *M = ReleasesToMove.ReleaseMetadata)
2019fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman      Call->setMetadata(ImpreciseReleaseMDKind, M);
2020fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman    Call->setDoesNotThrow();
2021fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman    if (ReleasesToMove.IsTailCallRelease)
2022fbab4a8c8a142502b7cdeb7112366f8560a94cecDan Gohman      Call->setTailCall();
20235581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman
20245581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman    DEBUG(dbgs() << "ObjCARCOpt::MoveCalls: Inserting new Retain: " << *Call
20255581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman                 << "\n"
20265581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman                    "                       At insertion point: " << *InsertPt
20275581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman                 << "\n");
20289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
20299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
20309fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Delete the original retain and release calls.
20319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (SmallPtrSet<Instruction *, 2>::const_iterator
20329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       AI = RetainsToMove.Calls.begin(),
20339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       AE = RetainsToMove.Calls.end(); AI != AE; ++AI) {
20349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Instruction *OrigRetain = *AI;
20359fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Retains.blot(OrigRetain);
20369fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    DeadInsts.push_back(OrigRetain);
20375581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman    DEBUG(dbgs() << "ObjCARCOpt::MoveCalls: Deleting retain: " << *OrigRetain <<
20385581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman                    "\n");
20399fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
20409fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (SmallPtrSet<Instruction *, 2>::const_iterator
20419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       AI = ReleasesToMove.Calls.begin(),
20429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall       AE = ReleasesToMove.Calls.end(); AI != AE; ++AI) {
20439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Instruction *OrigRelease = *AI;
20449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Releases.erase(OrigRelease);
20459fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    DeadInsts.push_back(OrigRelease);
20465581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman    DEBUG(dbgs() << "ObjCARCOpt::MoveCalls: Deleting release: " << *OrigRelease
20475581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman                 << "\n");
20489fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
20499fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
20509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
2051862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesmanbool
2052862d51fc671af273e52593246e7607fe9a6ba80cMichael GottesmanObjCARCOpt::ConnectTDBUTraversals(DenseMap<const BasicBlock *, BBState>
2053862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                                    &BBStates,
2054862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                                  MapVector<Value *, RRInfo> &Retains,
2055862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                                  DenseMap<Value *, RRInfo> &Releases,
2056862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                                  Module *M,
2057862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                                  SmallVector<Instruction *, 4> &NewRetains,
2058862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                                  SmallVector<Instruction *, 4> &NewReleases,
2059862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                                  SmallVector<Instruction *, 8> &DeadInsts,
2060862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                                  RRInfo &RetainsToMove,
2061862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                                  RRInfo &ReleasesToMove,
2062862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                                  Value *Arg,
2063862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                                  bool KnownSafe,
2064862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                                  bool &AnyPairsCompletelyEliminated) {
2065862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // If a pair happens in a region where it is known that the reference count
2066862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // is already incremented, we can similarly ignore possible decrements.
2067862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  bool KnownSafeTD = true, KnownSafeBU = true;
2068862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman
2069862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // Connect the dots between the top-down-collected RetainsToMove and
2070862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // bottom-up-collected ReleasesToMove to form sets of related calls.
2071862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // This is an iterative process so that we connect multiple releases
2072862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // to multiple retains if needed.
2073862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  unsigned OldDelta = 0;
2074862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  unsigned NewDelta = 0;
2075862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  unsigned OldCount = 0;
2076862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  unsigned NewCount = 0;
2077862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  bool FirstRelease = true;
2078862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  bool FirstRetain = true;
2079862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  for (;;) {
2080862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    for (SmallVectorImpl<Instruction *>::const_iterator
2081862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman           NI = NewRetains.begin(), NE = NewRetains.end(); NI != NE; ++NI) {
2082862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      Instruction *NewRetain = *NI;
2083862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      MapVector<Value *, RRInfo>::const_iterator It = Retains.find(NewRetain);
2084862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      assert(It != Retains.end());
2085862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      const RRInfo &NewRetainRRI = It->second;
2086862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      KnownSafeTD &= NewRetainRRI.KnownSafe;
2087862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      for (SmallPtrSet<Instruction *, 2>::const_iterator
2088862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman             LI = NewRetainRRI.Calls.begin(),
2089862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman             LE = NewRetainRRI.Calls.end(); LI != LE; ++LI) {
2090862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        Instruction *NewRetainRelease = *LI;
2091862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        DenseMap<Value *, RRInfo>::const_iterator Jt =
2092862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          Releases.find(NewRetainRelease);
2093862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        if (Jt == Releases.end())
2094862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          return false;
2095862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        const RRInfo &NewRetainReleaseRRI = Jt->second;
2096862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        assert(NewRetainReleaseRRI.Calls.count(NewRetain));
2097862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        if (ReleasesToMove.Calls.insert(NewRetainRelease)) {
2098862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          OldDelta -=
2099862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            BBStates[NewRetainRelease->getParent()].GetAllPathCount();
2100862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman
2101862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          // Merge the ReleaseMetadata and IsTailCallRelease values.
2102862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          if (FirstRelease) {
2103862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            ReleasesToMove.ReleaseMetadata =
2104862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman              NewRetainReleaseRRI.ReleaseMetadata;
2105862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            ReleasesToMove.IsTailCallRelease =
2106862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman              NewRetainReleaseRRI.IsTailCallRelease;
2107862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            FirstRelease = false;
2108862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          } else {
2109862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            if (ReleasesToMove.ReleaseMetadata !=
2110862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                NewRetainReleaseRRI.ReleaseMetadata)
2111862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman              ReleasesToMove.ReleaseMetadata = 0;
2112862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            if (ReleasesToMove.IsTailCallRelease !=
2113862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                NewRetainReleaseRRI.IsTailCallRelease)
2114862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman              ReleasesToMove.IsTailCallRelease = false;
2115862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          }
2116862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman
2117862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          // Collect the optimal insertion points.
2118862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          if (!KnownSafe)
2119862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            for (SmallPtrSet<Instruction *, 2>::const_iterator
2120862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                   RI = NewRetainReleaseRRI.ReverseInsertPts.begin(),
2121862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                   RE = NewRetainReleaseRRI.ReverseInsertPts.end();
2122862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                 RI != RE; ++RI) {
2123862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman              Instruction *RIP = *RI;
2124862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman              if (ReleasesToMove.ReverseInsertPts.insert(RIP))
2125862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                NewDelta -= BBStates[RIP->getParent()].GetAllPathCount();
2126862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            }
2127862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          NewReleases.push_back(NewRetainRelease);
2128862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        }
2129862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      }
2130862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    }
2131862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    NewRetains.clear();
2132862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    if (NewReleases.empty()) break;
2133862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman
2134862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    // Back the other way.
2135862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    for (SmallVectorImpl<Instruction *>::const_iterator
2136862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman           NI = NewReleases.begin(), NE = NewReleases.end(); NI != NE; ++NI) {
2137862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      Instruction *NewRelease = *NI;
2138862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      DenseMap<Value *, RRInfo>::const_iterator It =
2139862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        Releases.find(NewRelease);
2140862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      assert(It != Releases.end());
2141862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      const RRInfo &NewReleaseRRI = It->second;
2142862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      KnownSafeBU &= NewReleaseRRI.KnownSafe;
2143862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      for (SmallPtrSet<Instruction *, 2>::const_iterator
2144862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman             LI = NewReleaseRRI.Calls.begin(),
2145862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman             LE = NewReleaseRRI.Calls.end(); LI != LE; ++LI) {
2146862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        Instruction *NewReleaseRetain = *LI;
2147862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        MapVector<Value *, RRInfo>::const_iterator Jt =
2148862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          Retains.find(NewReleaseRetain);
2149862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        if (Jt == Retains.end())
2150862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          return false;
2151862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        const RRInfo &NewReleaseRetainRRI = Jt->second;
2152862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        assert(NewReleaseRetainRRI.Calls.count(NewRelease));
2153862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        if (RetainsToMove.Calls.insert(NewReleaseRetain)) {
2154862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          unsigned PathCount =
2155862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            BBStates[NewReleaseRetain->getParent()].GetAllPathCount();
2156862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          OldDelta += PathCount;
2157862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          OldCount += PathCount;
2158862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman
2159862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          // Merge the IsRetainBlock values.
2160862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          if (FirstRetain) {
2161862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            RetainsToMove.IsRetainBlock = NewReleaseRetainRRI.IsRetainBlock;
2162862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            FirstRetain = false;
2163862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          } else if (ReleasesToMove.IsRetainBlock !=
2164862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                     NewReleaseRetainRRI.IsRetainBlock)
2165862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            // It's not possible to merge the sequences if one uses
2166862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            // objc_retain and the other uses objc_retainBlock.
2167862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            return false;
2168862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman
2169862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          // Collect the optimal insertion points.
2170862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          if (!KnownSafe)
2171862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            for (SmallPtrSet<Instruction *, 2>::const_iterator
2172862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                   RI = NewReleaseRetainRRI.ReverseInsertPts.begin(),
2173862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                   RE = NewReleaseRetainRRI.ReverseInsertPts.end();
2174862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                 RI != RE; ++RI) {
2175862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman              Instruction *RIP = *RI;
2176862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman              if (RetainsToMove.ReverseInsertPts.insert(RIP)) {
2177862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                PathCount = BBStates[RIP->getParent()].GetAllPathCount();
2178862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                NewDelta += PathCount;
2179862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                NewCount += PathCount;
2180862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman              }
2181862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman            }
2182862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman          NewRetains.push_back(NewReleaseRetain);
2183862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman        }
2184862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      }
2185862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    }
2186862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    NewReleases.clear();
2187862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    if (NewRetains.empty()) break;
2188862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  }
2189862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman
2190862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // If the pointer is known incremented or nested, we can safely delete the
2191862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // pair regardless of what's between them.
2192862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  if (KnownSafeTD || KnownSafeBU) {
2193862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    RetainsToMove.ReverseInsertPts.clear();
2194862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    ReleasesToMove.ReverseInsertPts.clear();
2195862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    NewCount = 0;
2196862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  } else {
2197862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    // Determine whether the new insertion points we computed preserve the
2198862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    // balance of retain and release calls through the program.
2199862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    // TODO: If the fully aggressive solution isn't valid, try to find a
2200862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    // less aggressive solution which is.
2201862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    if (NewDelta != 0)
2202862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      return false;
2203862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  }
2204862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman
2205862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // Determine whether the original call points are balanced in the retain and
2206862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // release calls through the program. If not, conservatively don't touch
2207862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // them.
2208862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // TODO: It's theoretically possible to do code motion in this case, as
2209862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // long as the existing imbalances are maintained.
2210862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  if (OldDelta != 0)
2211862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    return false;
2212862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman
2213862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  Changed = true;
2214862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  assert(OldCount != 0 && "Unreachable code?");
2215862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  NumRRs += OldCount - NewCount;
2216862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // Set to true if we completely removed any RR pairs.
2217e65d46246c3e8fc279a9b6b7aaf985060ba88ab0Michael Gottesman  AnyPairsCompletelyEliminated = NewCount == 0;
2218862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman
2219862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  // We can move calls!
2220862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman  return true;
2221862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman}
2222862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman
222381c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// Identify pairings between the retains and releases, and delete and/or move
222481c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// them.
22259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallbool
22269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallObjCARCOpt::PerformCodePlacement(DenseMap<const BasicBlock *, BBState>
22279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                                   &BBStates,
22289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                                 MapVector<Value *, RRInfo> &Retains,
22294428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman                                 DenseMap<Value *, RRInfo> &Releases,
22304428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman                                 Module *M) {
22319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  bool AnyPairsCompletelyEliminated = false;
22329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  RRInfo RetainsToMove;
22339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  RRInfo ReleasesToMove;
22349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  SmallVector<Instruction *, 4> NewRetains;
22359fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  SmallVector<Instruction *, 4> NewReleases;
22369fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  SmallVector<Instruction *, 8> DeadInsts;
22379fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
2238d6bf201fa20a5cd3aa9f61767081d1d03d8aee3cDan Gohman  // Visit each retain.
22399fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (MapVector<Value *, RRInfo>::const_iterator I = Retains.begin(),
2240597fece886fb4551d1f26ec7749d86e89970d8c2Dan Gohman       E = Retains.end(); I != E; ++I) {
2241597fece886fb4551d1f26ec7749d86e89970d8c2Dan Gohman    Value *V = I->first;
22429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (!V) continue; // blotted
22439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
22449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Instruction *Retain = cast<Instruction>(V);
22455581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman
22465581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman    DEBUG(dbgs() << "ObjCARCOpt::PerformCodePlacement: Visiting: " << *Retain
22475581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman          << "\n");
22485581115075e688bdf44920f6b93dd42e94c3ccf6Michael Gottesman
22499fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Value *Arg = GetObjCArg(Retain);
22509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
225179522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman    // If the object being released is in static or stack storage, we know it's
22529fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // not being managed by ObjC reference counting, so we can delete pairs
22539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // regardless of what possible decrements or uses lie between them.
225479522dc569d3fb51b4a12cdacf24b82e5d5992d2Dan Gohman    bool KnownSafe = isa<Constant>(Arg) || isa<AllocaInst>(Arg);
22550daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman
22561b31ea8f935d4b643abf100c4943180c9ed8ba1aDan Gohman    // A constant pointer can't be pointing to an object on the heap. It may
22571b31ea8f935d4b643abf100c4943180c9ed8ba1aDan Gohman    // be reference-counted, but it won't be deleted.
22581b31ea8f935d4b643abf100c4943180c9ed8ba1aDan Gohman    if (const LoadInst *LI = dyn_cast<LoadInst>(Arg))
22591b31ea8f935d4b643abf100c4943180c9ed8ba1aDan Gohman      if (const GlobalVariable *GV =
22601b31ea8f935d4b643abf100c4943180c9ed8ba1aDan Gohman            dyn_cast<GlobalVariable>(
22611b31ea8f935d4b643abf100c4943180c9ed8ba1aDan Gohman              StripPointerCastsAndObjCCalls(LI->getPointerOperand())))
22621b31ea8f935d4b643abf100c4943180c9ed8ba1aDan Gohman        if (GV->isConstant())
22631b31ea8f935d4b643abf100c4943180c9ed8ba1aDan Gohman          KnownSafe = true;
22641b31ea8f935d4b643abf100c4943180c9ed8ba1aDan Gohman
22659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // Connect the dots between the top-down-collected RetainsToMove and
22669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // bottom-up-collected ReleasesToMove to form sets of related calls.
22679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    NewRetains.push_back(Retain);
2268862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    bool PerformMoveCalls =
2269862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      ConnectTDBUTraversals(BBStates, Retains, Releases, M, NewRetains,
2270862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                            NewReleases, DeadInsts, RetainsToMove,
2271862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                            ReleasesToMove, Arg, KnownSafe,
2272862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                            AnyPairsCompletelyEliminated);
22739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
2274862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    if (PerformMoveCalls) {
2275862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      // Ok, everything checks out and we're all set. Let's move/delete some
2276862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      // code!
2277862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman      MoveCalls(Arg, RetainsToMove, ReleasesToMove,
2278862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman                Retains, Releases, DeadInsts, M);
2279862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    }
22809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
2281862d51fc671af273e52593246e7607fe9a6ba80cMichael Gottesman    // Clean up state for next retain.
22829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    NewReleases.clear();
22839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    NewRetains.clear();
22849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    RetainsToMove.clear();
22859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ReleasesToMove.clear();
22869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
22879fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
22889fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Now that we're done moving everything, we can delete the newly dead
22899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // instructions, as we no longer need them as insert points.
22909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  while (!DeadInsts.empty())
22919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    EraseInstruction(DeadInsts.pop_back_val());
22929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
22939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return AnyPairsCompletelyEliminated;
22949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
22959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
229681c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// Weak pointer optimizations.
22979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid ObjCARCOpt::OptimizeWeakCalls(Function &F) {
22989fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // First, do memdep-style RLE and S2L optimizations. We can't use memdep
22999fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // itself because it uses AliasAnalysis and we need to do provenance
23009fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // queries instead.
23019fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) {
23029fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Instruction *Inst = &*I++;
23038f22c8b5e1f32bf253f968a81542a76dbfc3efc7Michael Gottesman
23045c0ae4727fe49a8173ee9084af4f5fb7d6d33f2cMichael Gottesman    DEBUG(dbgs() << "ObjCARCOpt::OptimizeWeakCalls: Visiting: " << *Inst <<
23058f22c8b5e1f32bf253f968a81542a76dbfc3efc7Michael Gottesman          "\n");
23068f22c8b5e1f32bf253f968a81542a76dbfc3efc7Michael Gottesman
23079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    InstructionClass Class = GetBasicInstructionClass(Inst);
23089fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (Class != IC_LoadWeak && Class != IC_LoadWeakRetained)
23099fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      continue;
23109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
23119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // Delete objc_loadWeak calls with no users.
23129fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (Class == IC_LoadWeak && Inst->use_empty()) {
23139fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Inst->eraseFromParent();
23149fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      continue;
23159fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
23169fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
23179fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // TODO: For now, just look for an earlier available version of this value
23189fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // within the same block. Theoretically, we could do memdep-style non-local
23199fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // analysis too, but that would want caching. A better approach would be to
23209fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    // use the technique that EarlyCSE uses.
23219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    inst_iterator Current = llvm::prior(I);
23229fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    BasicBlock *CurrentBB = Current.getBasicBlockIterator();
23239fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    for (BasicBlock::iterator B = CurrentBB->begin(),
23249fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                              J = Current.getInstructionIterator();
23259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall         J != B; --J) {
23269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Instruction *EarlierInst = &*llvm::prior(J);
23279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      InstructionClass EarlierClass = GetInstructionClass(EarlierInst);
23289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      switch (EarlierClass) {
23299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case IC_LoadWeak:
23309fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case IC_LoadWeakRetained: {
23319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // If this is loading from the same pointer, replace this load's value
23329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // with that one.
23339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        CallInst *Call = cast<CallInst>(Inst);
23349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        CallInst *EarlierCall = cast<CallInst>(EarlierInst);
23359fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Value *Arg = Call->getArgOperand(0);
23369fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Value *EarlierArg = EarlierCall->getArgOperand(0);
23379fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        switch (PA.getAA()->alias(Arg, EarlierArg)) {
23389fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case AliasAnalysis::MustAlias:
23399fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          Changed = true;
23409fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          // If the load has a builtin retain, insert a plain retain for it.
23419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          if (Class == IC_LoadWeakRetained) {
23429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            CallInst *CI =
23439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall              CallInst::Create(getRetainCallee(F.getParent()), EarlierCall,
23449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                               "", Call);
23459fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            CI->setTailCall();
23469fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          }
23479fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          // Zap the fully redundant load.
23489fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          Call->replaceAllUsesWith(EarlierCall);
23499fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          Call->eraseFromParent();
23509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          goto clobbered;
23519fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case AliasAnalysis::MayAlias:
23529fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case AliasAnalysis::PartialAlias:
23539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          goto clobbered;
23549fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case AliasAnalysis::NoAlias:
23559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          break;
23569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        }
23579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        break;
23589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
23599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case IC_StoreWeak:
23609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case IC_InitWeak: {
23619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // If this is storing to the same pointer and has the same size etc.
23629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // replace this load's value with the stored value.
23639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        CallInst *Call = cast<CallInst>(Inst);
23649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        CallInst *EarlierCall = cast<CallInst>(EarlierInst);
23659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Value *Arg = Call->getArgOperand(0);
23669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Value *EarlierArg = EarlierCall->getArgOperand(0);
23679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        switch (PA.getAA()->alias(Arg, EarlierArg)) {
23689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case AliasAnalysis::MustAlias:
23699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          Changed = true;
23709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          // If the load has a builtin retain, insert a plain retain for it.
23719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          if (Class == IC_LoadWeakRetained) {
23729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            CallInst *CI =
23739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall              CallInst::Create(getRetainCallee(F.getParent()), EarlierCall,
23749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                               "", Call);
23759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            CI->setTailCall();
23769fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          }
23779fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          // Zap the fully redundant load.
23789fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          Call->replaceAllUsesWith(EarlierCall->getArgOperand(1));
23799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          Call->eraseFromParent();
23809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          goto clobbered;
23819fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case AliasAnalysis::MayAlias:
23829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case AliasAnalysis::PartialAlias:
23839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          goto clobbered;
23849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case AliasAnalysis::NoAlias:
23859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          break;
23869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        }
23879fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        break;
23889fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
23899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case IC_MoveWeak:
23909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case IC_CopyWeak:
23919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // TOOD: Grab the copied value.
23929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        goto clobbered;
23939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case IC_AutoreleasepoolPush:
23949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case IC_None:
23959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      case IC_User:
23969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // Weak pointers are only modified through the weak entry points
23979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // (and arbitrary calls, which could call the weak entry points).
23989fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        break;
23999fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      default:
24009fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // Anything else could modify the weak pointer.
24019fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        goto clobbered;
24029fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
24039fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
24049fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  clobbered:;
24059fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
24069fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
24079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Then, for each destroyWeak with an alloca operand, check to see if
24089fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // the alloca and all its users can be zapped.
24099fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E; ) {
24109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Instruction *Inst = &*I++;
24119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    InstructionClass Class = GetBasicInstructionClass(Inst);
24129fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (Class != IC_DestroyWeak)
24139fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      continue;
24149fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
24159fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    CallInst *Call = cast<CallInst>(Inst);
24169fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Value *Arg = Call->getArgOperand(0);
24179fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (AllocaInst *Alloca = dyn_cast<AllocaInst>(Arg)) {
24189fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      for (Value::use_iterator UI = Alloca->use_begin(),
24199fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall           UE = Alloca->use_end(); UI != UE; ++UI) {
2420447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman        const Instruction *UserInst = cast<Instruction>(*UI);
24219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        switch (GetBasicInstructionClass(UserInst)) {
24229fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case IC_InitWeak:
24239fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case IC_StoreWeak:
24249fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        case IC_DestroyWeak:
24259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          continue;
24269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        default:
24279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          goto done;
24289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        }
24299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
24309fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Changed = true;
24319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      for (Value::use_iterator UI = Alloca->use_begin(),
24329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall           UE = Alloca->use_end(); UI != UE; ) {
24339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        CallInst *UserInst = cast<CallInst>(*UI++);
2434ce5d8b0d03b9c37727d08de4fa1bcc7be7ea8bb1Dan Gohman        switch (GetBasicInstructionClass(UserInst)) {
2435ce5d8b0d03b9c37727d08de4fa1bcc7be7ea8bb1Dan Gohman        case IC_InitWeak:
2436ce5d8b0d03b9c37727d08de4fa1bcc7be7ea8bb1Dan Gohman        case IC_StoreWeak:
2437ce5d8b0d03b9c37727d08de4fa1bcc7be7ea8bb1Dan Gohman          // These functions return their second argument.
2438ce5d8b0d03b9c37727d08de4fa1bcc7be7ea8bb1Dan Gohman          UserInst->replaceAllUsesWith(UserInst->getArgOperand(1));
2439ce5d8b0d03b9c37727d08de4fa1bcc7be7ea8bb1Dan Gohman          break;
2440ce5d8b0d03b9c37727d08de4fa1bcc7be7ea8bb1Dan Gohman        case IC_DestroyWeak:
2441ce5d8b0d03b9c37727d08de4fa1bcc7be7ea8bb1Dan Gohman          // No return value.
2442ce5d8b0d03b9c37727d08de4fa1bcc7be7ea8bb1Dan Gohman          break;
2443ce5d8b0d03b9c37727d08de4fa1bcc7be7ea8bb1Dan Gohman        default:
24444c8f909cdf221195f1d306033a4f843c5a7ee81aDan Gohman          llvm_unreachable("alloca really is used!");
2445ce5d8b0d03b9c37727d08de4fa1bcc7be7ea8bb1Dan Gohman        }
24469fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        UserInst->eraseFromParent();
24479fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
24489fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Alloca->eraseFromParent();
24499fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    done:;
24509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
24519fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
24522f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
24535c0ae4727fe49a8173ee9084af4f5fb7d6d33f2cMichael Gottesman  DEBUG(dbgs() << "ObjCARCOpt::OptimizeWeakCalls: Finished List.\n\n");
24542f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
24559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
24569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
245781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// Identify program paths which execute sequences of retains and releases which
245881c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// can be eliminated.
24599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallbool ObjCARCOpt::OptimizeSequences(Function &F) {
24609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  /// Releases, Retains - These are used to store the results of the main flow
24619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  /// analysis. These use Value* as the key instead of Instruction* so that the
24629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  /// map stays valid when we get around to rewriting code and calls get
24639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  /// replaced by arguments.
24649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  DenseMap<Value *, RRInfo> Releases;
24659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  MapVector<Value *, RRInfo> Retains;
24669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
246781c6121699a66b3e84f7b794b375095a39584701Michael Gottesman  /// This is used during the traversal of the function to track the
24689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  /// states for each identified object at each block.
24699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  DenseMap<const BasicBlock *, BBState> BBStates;
24709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
24719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Analyze the CFG of the function, and all instructions.
24729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  bool NestingDetected = Visit(F, BBStates, Retains, Releases);
24739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
24749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Transform.
24754428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman  return PerformCodePlacement(BBStates, Retains, Releases, F.getParent()) &&
24764428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman         NestingDetected;
24779fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
24789fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
247981c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// Look for this pattern:
2480c5252da873d547a19069eaf9030fec203f128f66Dmitri Gribenko/// \code
24819fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall///    %call = call i8* @something(...)
24829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall///    %2 = call i8* @objc_retain(i8* %call)
24839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall///    %3 = call i8* @objc_autorelease(i8* %2)
24849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall///    ret i8* %3
2485c5252da873d547a19069eaf9030fec203f128f66Dmitri Gribenko/// \endcode
24869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall/// And delete the retain and autorelease.
24879fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall///
24889fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall/// Otherwise if it's just this:
2489c5252da873d547a19069eaf9030fec203f128f66Dmitri Gribenko/// \code
24909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall///    %3 = call i8* @objc_autorelease(i8* %2)
24919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall///    ret i8* %3
2492c5252da873d547a19069eaf9030fec203f128f66Dmitri Gribenko/// \endcode
24939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall/// convert the autorelease to autoreleaseRV.
24949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid ObjCARCOpt::OptimizeReturns(Function &F) {
24959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (!F.getReturnType()->isPointerTy())
24969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    return;
24979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
24989fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  SmallPtrSet<Instruction *, 4> DependingInstructions;
24999fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  SmallPtrSet<const BasicBlock *, 4> Visited;
25009fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) {
25019fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    BasicBlock *BB = FI;
25029fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    ReturnInst *Ret = dyn_cast<ReturnInst>(&BB->back());
25038f22c8b5e1f32bf253f968a81542a76dbfc3efc7Michael Gottesman
25045c0ae4727fe49a8173ee9084af4f5fb7d6d33f2cMichael Gottesman    DEBUG(dbgs() << "ObjCARCOpt::OptimizeReturns: Visiting: " << *Ret << "\n");
25058f22c8b5e1f32bf253f968a81542a76dbfc3efc7Michael Gottesman
25069fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (!Ret) continue;
25079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25089fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    const Value *Arg = StripPointerCastsAndObjCCalls(Ret->getOperand(0));
25099fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    FindDependencies(NeedsPositiveRetainCount, Arg,
25109fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                     BB, Ret, DependingInstructions, Visited, PA);
25119fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (DependingInstructions.size() != 1)
25129fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      goto next_block;
25139fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25149fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    {
25159fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      CallInst *Autorelease =
25169fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        dyn_cast_or_null<CallInst>(*DependingInstructions.begin());
25179fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (!Autorelease)
25189fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        goto next_block;
25190daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman      InstructionClass AutoreleaseClass = GetBasicInstructionClass(Autorelease);
25209fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (!IsAutorelease(AutoreleaseClass))
25219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        goto next_block;
25229fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (GetObjCArg(Autorelease) != Arg)
25239fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        goto next_block;
25249fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      DependingInstructions.clear();
25269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      Visited.clear();
25279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // Check that there is nothing that can affect the reference
25299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // count between the autorelease and the retain.
25309fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      FindDependencies(CanChangeRetainCount, Arg,
25319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                       BB, Autorelease, DependingInstructions, Visited, PA);
25329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      if (DependingInstructions.size() != 1)
25339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        goto next_block;
25349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25359fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      {
25369fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        CallInst *Retain =
25379fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          dyn_cast_or_null<CallInst>(*DependingInstructions.begin());
25389fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25399fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // Check that we found a retain with the same argument.
25409fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        if (!Retain ||
25419fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            !IsRetain(GetBasicInstructionClass(Retain)) ||
25429fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            GetObjCArg(Retain) != Arg)
25439fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          goto next_block;
25449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25459fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        DependingInstructions.clear();
25469fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        Visited.clear();
25479fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25489fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // Convert the autorelease to an autoreleaseRV, since it's
25499fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // returning the value.
25509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        if (AutoreleaseClass == IC_Autorelease) {
25515dc300107b0f31ef876f2bf93e9893f6aa8204a2Michael Gottesman          DEBUG(dbgs() << "ObjCARCOpt::OptimizeReturns: Converting autorelease "
25525dc300107b0f31ef876f2bf93e9893f6aa8204a2Michael Gottesman                          "=> autoreleaseRV since it's returning a value.\n"
25535dc300107b0f31ef876f2bf93e9893f6aa8204a2Michael Gottesman                          "                             In: " << *Autorelease
25545dc300107b0f31ef876f2bf93e9893f6aa8204a2Michael Gottesman                       << "\n");
25559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          Autorelease->setCalledFunction(getAutoreleaseRVCallee(F.getParent()));
25565dc300107b0f31ef876f2bf93e9893f6aa8204a2Michael Gottesman          DEBUG(dbgs() << "                             Out: " << *Autorelease
25575dc300107b0f31ef876f2bf93e9893f6aa8204a2Michael Gottesman                       << "\n");
2558e8c161a92451ad38919525ea73ae3c6936c24bdfMichael Gottesman          Autorelease->setTailCall(); // Always tail call autoreleaseRV.
25599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          AutoreleaseClass = IC_AutoreleaseRV;
25609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        }
25619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // Check that there is nothing that can affect the reference
25639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        // count between the retain and the call.
256427e0666725c6558574cb7a55f8c91e7532e09548Dan Gohman        // Note that Retain need not be in BB.
256527e0666725c6558574cb7a55f8c91e7532e09548Dan Gohman        FindDependencies(CanChangeRetainCount, Arg, Retain->getParent(), Retain,
25669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                         DependingInstructions, Visited, PA);
25679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        if (DependingInstructions.size() != 1)
25689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          goto next_block;
25699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        {
25719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          CallInst *Call =
25729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            dyn_cast_or_null<CallInst>(*DependingInstructions.begin());
25739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          // Check that the pointer is the return value of the call.
25759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          if (!Call || Arg != Call)
25769fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            goto next_block;
25779fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25789fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          // Check that the call is a regular call.
25799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          InstructionClass Class = GetBasicInstructionClass(Call);
25809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          if (Class != IC_CallOrUser && Class != IC_Call)
25819fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall            goto next_block;
25829fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          // If so, we can zap the retain and autorelease.
25849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          Changed = true;
25859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          ++NumRets;
2586f93109a9b6843fcbe759e69f360b6e079d46c55eMichael Gottesman          DEBUG(dbgs() << "ObjCARCOpt::OptimizeReturns: Erasing: " << *Retain
2587f93109a9b6843fcbe759e69f360b6e079d46c55eMichael Gottesman                       << "\n                             Erasing: "
2588f93109a9b6843fcbe759e69f360b6e079d46c55eMichael Gottesman                       << *Autorelease << "\n");
25899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          EraseInstruction(Retain);
25909fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall          EraseInstruction(Autorelease);
25919fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall        }
25929fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      }
25939fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    }
25949fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
25959fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  next_block:
25969fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    DependingInstructions.clear();
25979fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    Visited.clear();
25989fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  }
25992f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
26005c0ae4727fe49a8173ee9084af4f5fb7d6d33f2cMichael Gottesman  DEBUG(dbgs() << "ObjCARCOpt::OptimizeReturns: Finished List.\n\n");
26012f1bfc4c7937fdf59e2d88e0e23d0657daba79b2Michael Gottesman
26029fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
26039fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26049fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallbool ObjCARCOpt::doInitialization(Module &M) {
26059fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (!EnableARCOpts)
26069fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    return false;
26079fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
2608d6bf201fa20a5cd3aa9f61767081d1d03d8aee3cDan Gohman  // If nothing in the Module uses ARC, don't do anything.
2609c4bcd4d964327e52ceadcc9be270718d758f8535Dan Gohman  Run = ModuleHasARC(M);
2610c4bcd4d964327e52ceadcc9be270718d758f8535Dan Gohman  if (!Run)
2611c4bcd4d964327e52ceadcc9be270718d758f8535Dan Gohman    return false;
2612c4bcd4d964327e52ceadcc9be270718d758f8535Dan Gohman
26139fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Identify the imprecise release metadata kind.
26149fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  ImpreciseReleaseMDKind =
26159fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    M.getContext().getMDKindID("clang.imprecise_release");
2616a974beaa1f63394a67c38c66ff0f39a759c7998fDan Gohman  CopyOnEscapeMDKind =
2617a974beaa1f63394a67c38c66ff0f39a759c7998fDan Gohman    M.getContext().getMDKindID("clang.arc.copy_on_escape");
2618dbe266be35cfee0fbda5523ac578fef81e8fdfccDan Gohman  NoObjCARCExceptionsMDKind =
2619dbe266be35cfee0fbda5523ac578fef81e8fdfccDan Gohman    M.getContext().getMDKindID("clang.arc.no_objc_arc_exceptions");
26209fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26219fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Intuitively, objc_retain and others are nocapture, however in practice
26229fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // they are not, because they return their argument value. And objc_release
2623447989cb680041ff484c8c00ee5b7135a9df6b3dDan Gohman  // calls finalizers which can have arbitrary side effects.
26249fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26259fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // These are initialized lazily.
26269fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  RetainRVCallee = 0;
26279fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  AutoreleaseRVCallee = 0;
26289fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  ReleaseCallee = 0;
26299fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  RetainCallee = 0;
26304428069f10ac6e7efb55826437c82428d4bbe03eDan Gohman  RetainBlockCallee = 0;
26319fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  AutoreleaseCallee = 0;
26329fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26339fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return false;
26349fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
26359fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26369fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallbool ObjCARCOpt::runOnFunction(Function &F) {
26379fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (!EnableARCOpts)
26389fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    return false;
26399fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
2640c4bcd4d964327e52ceadcc9be270718d758f8535Dan Gohman  // If nothing in the Module uses ARC, don't do anything.
2641c4bcd4d964327e52ceadcc9be270718d758f8535Dan Gohman  if (!Run)
2642c4bcd4d964327e52ceadcc9be270718d758f8535Dan Gohman    return false;
2643c4bcd4d964327e52ceadcc9be270718d758f8535Dan Gohman
26449fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  Changed = false;
26459fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26460d3582b1d1bedde39f964420edd237583bc5a010Michael Gottesman  DEBUG(dbgs() << "ObjCARCOpt: Visiting Function: " << F.getName() << "\n");
26470d3582b1d1bedde39f964420edd237583bc5a010Michael Gottesman
26489fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  PA.setAA(&getAnalysis<AliasAnalysis>());
26499fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26509fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // This pass performs several distinct transformations. As a compile-time aid
26519fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // when compiling code that isn't ObjC, skip these if the relevant ObjC
26529fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // library functions aren't declared.
26539fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26549fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Preliminary optimizations. This also computs UsedInThisFunction.
26559fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  OptimizeIndividualCalls(F);
26569fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26579fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Optimizations for weak pointers.
26589fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (UsedInThisFunction & ((1 << IC_LoadWeak) |
26599fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                            (1 << IC_LoadWeakRetained) |
26609fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                            (1 << IC_StoreWeak) |
26619fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                            (1 << IC_InitWeak) |
26629fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                            (1 << IC_CopyWeak) |
26639fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                            (1 << IC_MoveWeak) |
26649fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                            (1 << IC_DestroyWeak)))
26659fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    OptimizeWeakCalls(F);
26669fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26679fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Optimizations for retain+release pairs.
26689fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  if (UsedInThisFunction & ((1 << IC_Retain) |
26699fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                            (1 << IC_RetainRV) |
26709fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall                            (1 << IC_RetainBlock)))
26719fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    if (UsedInThisFunction & (1 << IC_Release))
26729fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // Run OptimizeSequences until it either stops making changes or
26739fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      // no retain+release pair nesting is detected.
26749fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall      while (OptimizeSequences(F)) {}
26759fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26769fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  // Optimizations if objc_autorelease is used.
26770daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman  if (UsedInThisFunction & ((1 << IC_Autorelease) |
26780daef3d90278d6c110f9af1e9f806fd05450ff48Dan Gohman                            (1 << IC_AutoreleaseRV)))
26799fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall    OptimizeReturns(F);
26809fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26810d3582b1d1bedde39f964420edd237583bc5a010Michael Gottesman  DEBUG(dbgs() << "\n");
26820d3582b1d1bedde39f964420edd237583bc5a010Michael Gottesman
26839fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  return Changed;
26849fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
26859fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
26869fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCallvoid ObjCARCOpt::releaseMemory() {
26879fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall  PA.clear();
26889fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall}
26899fbd318d36e618fb08fb53bb48b7c848e617a8a7John McCall
269081c6121699a66b3e84f7b794b375095a39584701Michael Gottesman/// @}
269181c6121699a66b3e84f7b794b375095a39584701Michael Gottesman///
2692