//===- ObjCARCContract.cpp - ObjC ARC Optimization ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \file
/// This file defines late ObjC ARC optimizations. ARC stands for Automatic
/// Reference Counting and is a system for managing reference counts for objects
/// in Objective C.
///
/// This specific file mainly deals with ``contracting'' multiple lower level
/// operations into singular higher level operations through pattern matching.
///
/// WARNING: This file knows about certain library functions. It recognizes them
/// by name, and hardwires knowledge of their semantics.
///
/// WARNING: This file knows about how certain Objective-C library functions are
/// used. Naive LLVM IR transformations which would otherwise be
/// behavior-preserving may break these assumptions.
///
//===----------------------------------------------------------------------===//

// TODO: ObjCARCContract could insert PHI nodes when uses aren't
// dominated by single calls.

#include "ARCRuntimeEntryPoints.h"
#include "DependencyAnalysis.h"
#include "ObjCARC.h"
#include "ProvenanceAnalysis.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/Analysis/ObjCARCUtil.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/EHPersonalities.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
#include "llvm/Transforms/ObjCARC.h"

using namespace llvm;
using namespace llvm::objcarc;

#define DEBUG_TYPE "objc-arc-contract"

STATISTIC(NumPeeps,       "Number of calls peephole-optimized");
STATISTIC(NumStoreStrongs, "Number objc_storeStrong calls formed");

static cl::opt<cl::boolOrDefault> UseObjCClaimRV(
    "arc-contract-use-objc-claim-rv",
    cl::desc(
        "Enable generation of calls to objc_claimAutoreleasedReturnValue"));

//===----------------------------------------------------------------------===//
//                                Declarations
//===----------------------------------------------------------------------===//

namespace {
/// Late ARC optimizations
///
/// These change the IR in a way that makes it difficult to be analyzed by
/// ObjCARCOpt, so it's run late.

class ObjCARCContract {
  bool Changed;
  bool CFGChanged = false;
  AAResults *AA;
  DominatorTree *DT;
  ProvenanceAnalysis PA;
  ARCRuntimeEntryPoints EP;
  BundledRetainClaimRVs *BundledInsts = nullptr;

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

  /// Whether objc_claimAutoreleasedReturnValue is available.
  bool HasClaimRV = false;

  /// The inline asm string to insert between calls and RetainRV calls to make
  /// the optimization work on targets which need it.
  const MDString *RVInstMarker;

  /// The set of inserted objc_storeStrong calls. If at the end of walking the
  /// function we have found no alloca instructions, these calls can be marked
  /// "tail".
  SmallPtrSet<CallInst *, 8> StoreStrongCalls;

  /// Returns true if we eliminated Inst.
  bool tryToPeepholeInstruction(
      Function &F, Instruction *Inst, inst_iterator &Iter,
      bool &TailOkForStoreStrong,
      const DenseMap<BasicBlock *, ColorVector> &BlockColors);

  bool optimizeRetainCall(Function &F, Instruction *Retain);

  bool contractAutorelease(Function &F, Instruction *Autorelease,
                           ARCInstKind Class);

  void tryToContractReleaseIntoStoreStrong(
      Instruction *Release, inst_iterator &Iter,
      const DenseMap<BasicBlock *, ColorVector> &BlockColors);

public:
  bool init(Module &M);
  bool run(Function &F, AAResults *AA, DominatorTree *DT);
  bool hasCFGChanged() const { return CFGChanged; }
};

class ObjCARCContractLegacyPass : public FunctionPass {
public:
  void getAnalysisUsage(AnalysisUsage &AU) const override;
  bool runOnFunction(Function &F) override;

  static char ID;
  ObjCARCContractLegacyPass() : FunctionPass(ID) {
    initializeObjCARCContractLegacyPassPass(*PassRegistry::getPassRegistry());
  }
};
}

//===----------------------------------------------------------------------===//
//                               Implementation
//===----------------------------------------------------------------------===//

/// Turn objc_retain into objc_retainAutoreleasedReturnValue if the operand is a
/// return value. We do this late so we do not disrupt the dataflow analysis in
/// ObjCARCOpt.
bool ObjCARCContract::optimizeRetainCall(Function &F, Instruction *Retain) {
  const auto *Call = dyn_cast<CallBase>(GetArgRCIdentityRoot(Retain));
  if (!Call)
    return false;
  if (Call->getParent() != Retain->getParent())
    return false;

  // Check that the call is next to the retain.
  BasicBlock::const_iterator I = ++Call->getIterator();
  while (IsNoopInstruction(&*I))
    ++I;
  if (&*I != Retain)
    return false;

  // Turn it to an objc_retainAutoreleasedReturnValue.
  Changed = true;
  ++NumPeeps;

  LLVM_DEBUG(
      dbgs() << "Transforming objc_retain => "
                "objc_retainAutoreleasedReturnValue since the operand is a "
                "return value.\nOld: "
             << *Retain << "\n");

  // We do not have to worry about tail calls/does not throw since
  // retain/retainRV have the same properties.
  Function *Decl = EP.get(ARCRuntimeEntryPointKind::RetainRV);
  cast<CallInst>(Retain)->setCalledFunction(Decl);

  LLVM_DEBUG(dbgs() << "New: " << *Retain << "\n");
  return true;
}

/// Merge an autorelease with a retain into a fused call.
bool ObjCARCContract::contractAutorelease(Function &F, Instruction *Autorelease,
                                          ARCInstKind Class) {
  const Value *Arg = GetArgRCIdentityRoot(Autorelease);

  // Check that there are no instructions between the retain and the autorelease
  // (such as an autorelease_pop) which may change the count.
  DependenceKind DK = Class == ARCInstKind::AutoreleaseRV
                          ? RetainAutoreleaseRVDep
                          : RetainAutoreleaseDep;
  auto *Retain = dyn_cast_or_null<CallInst>(
      findSingleDependency(DK, Arg, Autorelease->getParent(), Autorelease, PA));

  if (!Retain || GetBasicARCInstKind(Retain) != ARCInstKind::Retain ||
      GetArgRCIdentityRoot(Retain) != Arg)
    return false;

  Changed = true;
  ++NumPeeps;

  LLVM_DEBUG(dbgs() << "    Fusing retain/autorelease!\n"
                       "        Autorelease:"
                    << *Autorelease
                    << "\n"
                       "        Retain: "
                    << *Retain << "\n");

  Function *Decl = EP.get(Class == ARCInstKind::AutoreleaseRV
                              ? ARCRuntimeEntryPointKind::RetainAutoreleaseRV
                              : ARCRuntimeEntryPointKind::RetainAutorelease);
  Retain->setCalledFunction(Decl);

  LLVM_DEBUG(dbgs() << "        New RetainAutorelease: " << *Retain << "\n");

  EraseInstruction(Autorelease);
  return true;
}

static StoreInst *findSafeStoreForStoreStrongContraction(LoadInst *Load,
                                                         Instruction *Release,
                                                         ProvenanceAnalysis &PA,
                                                         AAResults *AA) {
  StoreInst *Store = nullptr;
  bool SawRelease = false;

  // Get the location associated with Load.
  MemoryLocation Loc = MemoryLocation::get(Load);
  auto *LocPtr = Loc.Ptr->stripPointerCasts();

  // Walk down to find the store and the release, which may be in either order.
  for (auto I = std::next(BasicBlock::iterator(Load)),
            E = Load->getParent()->end();
       I != E; ++I) {
    // If we found the store we were looking for and saw the release,
    // break. There is no more work to be done.
    if (Store && SawRelease)
      break;

    // Now we know that we have not seen either the store or the release. If I
    // is the release, mark that we saw the release and continue.
    Instruction *Inst = &*I;
    if (Inst == Release) {
      SawRelease = true;
      continue;
    }

    // Otherwise, we check if Inst is a "good" store. Grab the instruction class
    // of Inst.
    ARCInstKind Class = GetBasicARCInstKind(Inst);

    // If we have seen the store, but not the release...
    if (Store) {
      // We need to make sure that it is safe to move the release from its
      // current position to the store. This implies proving that any
      // instruction in between Store and the Release conservatively can not use
      // the RCIdentityRoot of Release. If we can prove we can ignore Inst, so
      // continue...
      if (!CanUse(Inst, Load, PA, Class)) {
        continue;
      }

      // Otherwise, be conservative and return nullptr.
      return nullptr;
    }

    // Ok, now we know we have not seen a store yet.

    // If Inst is a retain, we don't care about it as it doesn't prevent moving
    // the load to the store.
    //
    // TODO: This is one area where the optimization could be made more
    // aggressive.
    if (IsRetain(Class))
      continue;

    // See if Inst can write to our load location, if it can not, just ignore
    // the instruction.
    if (!isModSet(AA->getModRefInfo(Inst, Loc)))
      continue;

    Store = dyn_cast<StoreInst>(Inst);

    // If Inst can, then check if Inst is a simple store. If Inst is not a
    // store or a store that is not simple, then we have some we do not
    // understand writing to this memory implying we can not move the load
    // over the write to any subsequent store that we may find.
    if (!Store || !Store->isSimple())
      return nullptr;

    // Then make sure that the pointer we are storing to is Ptr. If so, we
    // found our Store!
    if (Store->getPointerOperand()->stripPointerCasts() == LocPtr)
      continue;

    // Otherwise, we have an unknown store to some other ptr that clobbers
    // Loc.Ptr. Bail!
    return nullptr;
  }

  // If we did not find the store or did not see the release, fail.
  if (!Store || !SawRelease)
    return nullptr;

  // We succeeded!
  return Store;
}

static Instruction *
findRetainForStoreStrongContraction(Value *New, StoreInst *Store,
                                    Instruction *Release,
                                    ProvenanceAnalysis &PA) {
  // Walk up from the Store to find the retain.
  BasicBlock::iterator I = Store->getIterator();
  BasicBlock::iterator Begin = Store->getParent()->begin();
  while (I != Begin && GetBasicARCInstKind(&*I) != ARCInstKind::Retain) {
    Instruction *Inst = &*I;

    // It is only safe to move the retain to the store if we can prove
    // conservatively that nothing besides the release can decrement reference
    // counts in between the retain and the store.
    if (CanDecrementRefCount(Inst, New, PA) && Inst != Release)
      return nullptr;
    --I;
  }
  Instruction *Retain = &*I;
  if (GetBasicARCInstKind(Retain) != ARCInstKind::Retain)
    return nullptr;
  if (GetArgRCIdentityRoot(Retain) != New)
    return nullptr;
  return Retain;
}

/// Attempt to merge an objc_release with a store, load, and objc_retain to form
/// an objc_storeStrong. An objc_storeStrong:
///
///   objc_storeStrong(i8** %old_ptr, i8* new_value)
///
/// is equivalent to the following IR sequence:
///
///   ; Load old value.
///   %old_value = load i8** %old_ptr               (1)
///
///   ; Increment the new value and then release the old value. This must occur
///   ; in order in case old_value releases new_value in its destructor causing
///   ; us to potentially have a dangling ptr.
///   tail call i8* @objc_retain(i8* %new_value)    (2)
///   tail call void @objc_release(i8* %old_value)  (3)
///
///   ; Store the new_value into old_ptr
///   store i8* %new_value, i8** %old_ptr           (4)
///
/// The safety of this optimization is based around the following
/// considerations:
///
///  1. We are forming the store strong at the store. Thus to perform this
///     optimization it must be safe to move the retain, load, and release to
///     (4).
///  2. We need to make sure that any re-orderings of (1), (2), (3), (4) are
///     safe.
void ObjCARCContract::tryToContractReleaseIntoStoreStrong(
    Instruction *Release, inst_iterator &Iter,
    const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
  // See if we are releasing something that we just loaded.
  auto *Load = dyn_cast<LoadInst>(GetArgRCIdentityRoot(Release));
  if (!Load || !Load->isSimple())
    return;

  // For now, require everything to be in one basic block.
  BasicBlock *BB = Release->getParent();
  if (Load->getParent() != BB)
    return;

  // First scan down the BB from Load, looking for a store of the RCIdentityRoot
  // of Load's
  StoreInst *Store =
      findSafeStoreForStoreStrongContraction(Load, Release, PA, AA);
  // If we fail, bail.
  if (!Store)
    return;

  // Then find what new_value's RCIdentity Root is.
  Value *New = GetRCIdentityRoot(Store->getValueOperand());

  // Then walk up the BB and look for a retain on New without any intervening
  // instructions which conservatively might decrement ref counts.
  Instruction *Retain =
      findRetainForStoreStrongContraction(New, Store, Release, PA);

  // If we fail, bail.
  if (!Retain)
    return;

  Changed = true;
  ++NumStoreStrongs;

  LLVM_DEBUG(
      llvm::dbgs() << "    Contracting retain, release into objc_storeStrong.\n"
                   << "        Old:\n"
                   << "            Store:   " << *Store << "\n"
                   << "            Release: " << *Release << "\n"
                   << "            Retain:  " << *Retain << "\n"
                   << "            Load:    " << *Load << "\n");

  Value *Args[] = {Load->getPointerOperand(), New};
  Function *Decl = EP.get(ARCRuntimeEntryPointKind::StoreStrong);
  CallInst *StoreStrong = objcarc::createCallInstWithColors(
      Decl, Args, "", Store->getIterator(), BlockColors);
  StoreStrong->setDoesNotThrow();
  StoreStrong->setDebugLoc(Store->getDebugLoc());

  // We can't set the tail flag yet, because we haven't yet determined
  // whether there are any escaping allocas. Remember this call, so that
  // we can set the tail flag once we know it's safe.
  StoreStrongCalls.insert(StoreStrong);

  LLVM_DEBUG(llvm::dbgs() << "        New Store Strong: " << *StoreStrong
                          << "\n");

  if (&*Iter == Retain) ++Iter;
  if (&*Iter == Store) ++Iter;
  Store->eraseFromParent();
  Release->eraseFromParent();
  EraseInstruction(Retain);
  if (Load->use_empty())
    Load->eraseFromParent();
}

bool ObjCARCContract::tryToPeepholeInstruction(
    Function &F, Instruction *Inst, inst_iterator &Iter,
    bool &TailOkForStoreStrongs,
    const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
  // Only these library routines return their argument. In particular,
  // objc_retainBlock does not necessarily return its argument.
  ARCInstKind Class = GetBasicARCInstKind(Inst);
  switch (Class) {
  case ARCInstKind::FusedRetainAutorelease:
  case ARCInstKind::FusedRetainAutoreleaseRV:
    return false;
  case ARCInstKind::Autorelease:
  case ARCInstKind::AutoreleaseRV:
    return contractAutorelease(F, Inst, Class);
  case ARCInstKind::Retain:
    // Attempt to convert retains to retainrvs if they are next to function
    // calls.
    if (!optimizeRetainCall(F, Inst))
      return false;
    // If we succeed in our optimization, fall through.
    [[fallthrough]];
  case ARCInstKind::RetainRV:
  case ARCInstKind::UnsafeClaimRV: {
    // Return true if this is a bundled retainRV/claimRV call, which is always
    // redundant with the attachedcall in the bundle, and is going to be erased
    // at the end of this pass.  This avoids undoing objc-arc-expand and
    // replacing uses of the retainRV/claimRV call's argument with its result.
    if (BundledInsts->contains(Inst))
      return true;

    // If this isn't a bundled call, and the target doesn't need a special
    // inline-asm marker, we're done: return now, and undo objc-arc-expand.
    if (!RVInstMarker)
      return false;

    // The target needs a special inline-asm marker.  Insert it.

    BasicBlock::iterator BBI = Inst->getIterator();
    BasicBlock *InstParent = Inst->getParent();

    // Step up to see if the call immediately precedes the RV call.
    // If it's an invoke, we have to cross a block boundary. And we have
    // to carefully dodge no-op instructions.
    do {
      if (BBI == InstParent->begin()) {
        BasicBlock *Pred = InstParent->getSinglePredecessor();
        if (!Pred)
          goto decline_rv_optimization;
        BBI = Pred->getTerminator()->getIterator();
        break;
      }
      --BBI;
    } while (IsNoopInstruction(&*BBI));

    if (GetRCIdentityRoot(&*BBI) == GetArgRCIdentityRoot(Inst)) {
      LLVM_DEBUG(dbgs() << "Adding inline asm marker for the return value "
                           "optimization.\n");
      Changed = true;
      InlineAsm *IA =
          InlineAsm::get(FunctionType::get(Type::getVoidTy(Inst->getContext()),
                                           /*isVarArg=*/false),
                         RVInstMarker->getString(),
                         /*Constraints=*/"", /*hasSideEffects=*/true);

      objcarc::createCallInstWithColors(IA, {}, "", Inst->getIterator(),
                                        BlockColors);
    }
  decline_rv_optimization:
    return false;
  }
  case ARCInstKind::InitWeak: {
    // objc_initWeak(p, null) => *p = null
    CallInst *CI = cast<CallInst>(Inst);
    if (IsNullOrUndef(CI->getArgOperand(1))) {
      Value *Null = ConstantPointerNull::get(cast<PointerType>(CI->getType()));
      Changed = true;
      new StoreInst(Null, CI->getArgOperand(0), CI->getIterator());

      LLVM_DEBUG(dbgs() << "OBJCARCContract: Old = " << *CI << "\n"
                        << "                 New = " << *Null << "\n");

      CI->replaceAllUsesWith(Null);
      CI->eraseFromParent();
    }
    return true;
  }
  case ARCInstKind::Release:
    // Try to form an objc store strong from our release. If we fail, there is
    // nothing further to do below, so continue.
    tryToContractReleaseIntoStoreStrong(Inst, Iter, BlockColors);
    return true;
  case ARCInstKind::User:
    // Be conservative if the function has any alloca instructions.
    // Technically we only care about escaping alloca instructions,
    // but this is sufficient to handle some interesting cases.
    if (isa<AllocaInst>(Inst))
      TailOkForStoreStrongs = false;
    return true;
  case ARCInstKind::IntrinsicUser:
    // Remove calls to @llvm.objc.clang.arc.use(...).
    Changed = true;
    Inst->eraseFromParent();
    return true;
  default:
    if (auto *CI = dyn_cast<CallInst>(Inst))
      if (CI->getIntrinsicID() == Intrinsic::objc_clang_arc_noop_use) {
        // Remove calls to @llvm.objc.clang.arc.noop.use(...).
        Changed = true;
        CI->eraseFromParent();
      }
    return true;
  }
}

/// Should we use objc_claimAutoreleasedReturnValue?
static bool useClaimRuntimeCall(Module &M) {
  // Let the flag override our OS-based default.
  if (UseObjCClaimRV != cl::BOU_UNSET)
    return UseObjCClaimRV == cl::BOU_TRUE;

  Triple TT(M.getTargetTriple());

  // On x86_64, claimARV doesn't make sense, as the marker isn't actually a nop
  // there (it's needed by the calling convention).
  if (!TT.isAArch64())
    return false;

  unsigned Major = TT.getOSMajorVersion();
  switch (TT.getOS()) {
  default:
    return false;
  case Triple::IOS:
  case Triple::TvOS:
    return Major >= 16;
  case Triple::WatchOS:
    return Major >= 9;
  case Triple::BridgeOS:
    return Major >= 7;
  case Triple::MacOSX:
    return Major >= 13;
  case Triple::Darwin:
    return Major >= 21;
  }

  return false;
}

//===----------------------------------------------------------------------===//
//                              Top Level Driver
//===----------------------------------------------------------------------===//

bool ObjCARCContract::init(Module &M) {
  Run = ModuleHasARC(M);
  if (!Run)
    return false;

  EP.init(&M);

  HasClaimRV = useClaimRuntimeCall(M);

  // Initialize RVInstMarker.
  RVInstMarker = getRVInstMarker(M);

  return false;
}

bool ObjCARCContract::run(Function &F, AAResults *A, DominatorTree *D) {
  if (!Run)
    return false;

  if (!EnableARCOpts)
    return false;

  Changed = CFGChanged = false;
  AA = A;
  DT = D;
  PA.setAA(A);
  BundledRetainClaimRVs BRV(EP, /*ContractPass=*/true, HasClaimRV);
  BundledInsts = &BRV;

  std::pair<bool, bool> R = BundledInsts->insertAfterInvokes(F, DT);
  Changed |= R.first;
  CFGChanged |= R.second;

  DenseMap<BasicBlock *, ColorVector> BlockColors;
  if (F.hasPersonalityFn() &&
      isScopedEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
    BlockColors = colorEHFunclets(F);

  LLVM_DEBUG(llvm::dbgs() << "**** ObjCARC Contract ****\n");

  // Track whether it's ok to mark objc_storeStrong calls with the "tail"
  // keyword. Be conservative if the function has variadic arguments.
  // It seems that functions which "return twice" are also unsafe for the
  // "tail" argument, because they are setjmp, which could need to
  // return to an earlier stack state.
  bool TailOkForStoreStrongs =
      !F.isVarArg() && !F.callsFunctionThatReturnsTwice();

  // For ObjC library calls which return their argument, replace uses of the
  // argument with uses of the call return value, if it dominates the use. This
  // reduces register pressure.
  for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) {
    Instruction *Inst = &*I++;

    LLVM_DEBUG(dbgs() << "Visiting: " << *Inst << "\n");

    if (auto *CI = dyn_cast<CallInst>(Inst))
      if (objcarc::hasAttachedCallOpBundle(CI)) {
        BundledInsts->insertRVCallWithColors(I->getIterator(), CI, BlockColors);
        --I;
        Changed = true;
      }

    // First try to peephole Inst. If there is nothing further we can do in
    // terms of undoing objc-arc-expand, process the next inst.
    if (tryToPeepholeInstruction(F, Inst, I, TailOkForStoreStrongs,
                                 BlockColors))
      continue;

    // Otherwise, try to undo objc-arc-expand.

    // Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts
    // and such; to do the replacement, the argument must have type i8*.

    // Function for replacing uses of Arg dominated by Inst.
    auto ReplaceArgUses = [Inst, this](Value *Arg) {
      // If we're compiling bugpointed code, don't get in trouble.
      if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
        return;

      // Look through the uses of the pointer.
      for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
           UI != UE; ) {
        // Increment UI now, because we may unlink its element.
        Use &U = *UI++;
        unsigned OperandNo = U.getOperandNo();

        // If the call's return value dominates a use of the call's argument
        // value, rewrite the use to use the return value. We check for
        // reachability here because an unreachable call is considered to
        // trivially dominate itself, which would lead us to rewriting its
        // argument in terms of its return value, which would lead to
        // infinite loops in GetArgRCIdentityRoot.
        if (!DT->isReachableFromEntry(U) || !DT->dominates(Inst, U))
          continue;

        Changed = true;
        Instruction *Replacement = Inst;
        Type *UseTy = U.get()->getType();
        if (PHINode *PHI = dyn_cast<PHINode>(U.getUser())) {
          // For PHI nodes, insert the bitcast in the predecessor block.
          unsigned ValNo = PHINode::getIncomingValueNumForOperand(OperandNo);
          BasicBlock *IncomingBB = PHI->getIncomingBlock(ValNo);
          if (Replacement->getType() != UseTy) {
            // A catchswitch is both a pad and a terminator, meaning a basic
            // block with a catchswitch has no insertion point. Keep going up
            // the dominator tree until we find a non-catchswitch.
            BasicBlock *InsertBB = IncomingBB;
            while (isa<CatchSwitchInst>(InsertBB->getFirstNonPHIIt())) {
              InsertBB = DT->getNode(InsertBB)->getIDom()->getBlock();
            }

            assert(DT->dominates(Inst, &InsertBB->back()) &&
                   "Invalid insertion point for bitcast");
            Replacement = new BitCastInst(Replacement, UseTy, "",
                                          InsertBB->back().getIterator());
          }

          // While we're here, rewrite all edges for this PHI, rather
          // than just one use at a time, to minimize the number of
          // bitcasts we emit.
          for (unsigned i = 0, e = PHI->getNumIncomingValues(); i != e; ++i)
            if (PHI->getIncomingBlock(i) == IncomingBB) {
              // Keep the UI iterator valid.
              if (UI != UE &&
                  &PHI->getOperandUse(
                      PHINode::getOperandNumForIncomingValue(i)) == &*UI)
                ++UI;
              PHI->setIncomingValue(i, Replacement);
            }
        } else {
          if (Replacement->getType() != UseTy)
            Replacement =
                new BitCastInst(Replacement, UseTy, "",
                                cast<Instruction>(U.getUser())->getIterator());
          U.set(Replacement);
        }
      }
    };

    Value *Arg = cast<CallInst>(Inst)->getArgOperand(0);

    // TODO: Change this to a do-while.
    for (;;) {
      ReplaceArgUses(Arg);

      // If Arg is a no-op casted pointer, strip one level of casts and iterate.
      if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg))
        Arg = BI->getOperand(0);
      else if (isa<GEPOperator>(Arg) &&
               cast<GEPOperator>(Arg)->hasAllZeroIndices())
        Arg = cast<GEPOperator>(Arg)->getPointerOperand();
      else if (isa<GlobalAlias>(Arg) &&
               !cast<GlobalAlias>(Arg)->isInterposable())
        Arg = cast<GlobalAlias>(Arg)->getAliasee();
      else {
        // If Arg is a PHI node, get PHIs that are equivalent to it and replace
        // their uses.
        if (PHINode *PN = dyn_cast<PHINode>(Arg)) {
          SmallVector<Value *, 1> PHIList;
          getEquivalentPHIs(*PN, PHIList);
          for (Value *PHI : PHIList)
            ReplaceArgUses(PHI);
        }
        break;
      }
    }
  }

  // If this function has no escaping allocas or suspicious vararg usage,
  // objc_storeStrong calls can be marked with the "tail" keyword.
  if (TailOkForStoreStrongs)
    for (CallInst *CI : StoreStrongCalls)
      CI->setTailCall();
  StoreStrongCalls.clear();

  return Changed;
}

//===----------------------------------------------------------------------===//
//                             Misc Pass Manager
//===----------------------------------------------------------------------===//

char ObjCARCContractLegacyPass::ID = 0;
INITIALIZE_PASS_BEGIN(ObjCARCContractLegacyPass, "objc-arc-contract",
                      "ObjC ARC contraction", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
INITIALIZE_PASS_END(ObjCARCContractLegacyPass, "objc-arc-contract",
                    "ObjC ARC contraction", false, false)

void ObjCARCContractLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<AAResultsWrapperPass>();
  AU.addRequired<DominatorTreeWrapperPass>();
  AU.addPreserved<AAResultsWrapperPass>();
  AU.addPreserved<BasicAAWrapperPass>();
  AU.addPreserved<DominatorTreeWrapperPass>();
}

Pass *llvm::createObjCARCContractPass() {
  return new ObjCARCContractLegacyPass();
}

bool ObjCARCContractLegacyPass::runOnFunction(Function &F) {
  ObjCARCContract OCARCC;
  OCARCC.init(*F.getParent());
  auto *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
  auto *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
  return OCARCC.run(F, AA, DT);
}

PreservedAnalyses ObjCARCContractPass::run(Function &F,
                                           FunctionAnalysisManager &AM) {
  ObjCARCContract OCAC;
  OCAC.init(*F.getParent());

  bool Changed = OCAC.run(F, &AM.getResult<AAManager>(F),
                          &AM.getResult<DominatorTreeAnalysis>(F));
  bool CFGChanged = OCAC.hasCFGChanged();
  if (Changed) {
    PreservedAnalyses PA;
    if (!CFGChanged)
      PA.preserveSet<CFGAnalyses>();
    return PA;
  }
  return PreservedAnalyses::all();
}
