//===- DependencyAnalysis.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 special dependency analysis routines used in Objective C
/// ARC Optimizations.
///
/// WARNING: This file knows about certain library functions. It recognizes them
/// by name, and hardwires knowledge of their semantics.
///
/// WARNING: This file knows about how certain Objective-C library functions are
/// used. Naive LLVM IR transformations which would otherwise be
/// behavior-preserving may break these assumptions.
///
//===----------------------------------------------------------------------===//

#include "DependencyAnalysis.h"
#include "ObjCARC.h"
#include "ProvenanceAnalysis.h"
#include "llvm/IR/CFG.h"

using namespace llvm;
using namespace llvm::objcarc;

#define DEBUG_TYPE "objc-arc-dependency"

/// Test whether the given instruction can result in a reference count
/// modification (positive or negative) for the pointer's object.
bool llvm::objcarc::CanAlterRefCount(const Instruction *Inst, const Value *Ptr,
                                     ProvenanceAnalysis &PA,
                                     ARCInstKind Class) {
  switch (Class) {
  case ARCInstKind::Autorelease:
  case ARCInstKind::AutoreleaseRV:
  case ARCInstKind::IntrinsicUser:
  case ARCInstKind::User:
    // These operations never directly modify a reference count.
    return false;
  default: break;
  }

  const auto *Call = cast<CallBase>(Inst);

  // See if AliasAnalysis can help us with the call.
  FunctionModRefBehavior MRB = PA.getAA()->getModRefBehavior(Call);
  if (AliasAnalysis::onlyReadsMemory(MRB))
    return false;
  if (AliasAnalysis::onlyAccessesArgPointees(MRB)) {
    const DataLayout &DL = Inst->getModule()->getDataLayout();
    for (const Value *Op : Call->args()) {
      if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) &&
          PA.related(Ptr, Op, DL))
        return true;
    }
    return false;
  }

  // Assume the worst.
  return true;
}

bool llvm::objcarc::CanDecrementRefCount(const Instruction *Inst,
                                         const Value *Ptr,
                                         ProvenanceAnalysis &PA,
                                         ARCInstKind Class) {
  // First perform a quick check if Class can not touch ref counts.
  if (!CanDecrementRefCount(Class))
    return false;

  // Otherwise, just use CanAlterRefCount for now.
  return CanAlterRefCount(Inst, Ptr, PA, Class);
}

/// Test whether the given instruction can "use" the given pointer's object in a
/// way that requires the reference count to be positive.
bool llvm::objcarc::CanUse(const Instruction *Inst, const Value *Ptr,
                           ProvenanceAnalysis &PA, ARCInstKind Class) {
  // ARCInstKind::Call operations (as opposed to
  // ARCInstKind::CallOrUser) never "use" objc pointers.
  if (Class == ARCInstKind::Call)
    return false;

  const DataLayout &DL = Inst->getModule()->getDataLayout();

  // Consider various instructions which may have pointer arguments which are
  // not "uses".
  if (const ICmpInst *ICI = dyn_cast<ICmpInst>(Inst)) {
    // Comparing a pointer with null, or any other constant, isn't really a use,
    // because we don't care what the pointer points to, or about the values
    // of any other dynamic reference-counted pointers.
    if (!IsPotentialRetainableObjPtr(ICI->getOperand(1), *PA.getAA()))
      return false;
  } else if (const auto *CS = dyn_cast<CallBase>(Inst)) {
    // For calls, just check the arguments (and not the callee operand).
    for (auto OI = CS->arg_begin(), OE = CS->arg_end(); OI != OE; ++OI) {
      const Value *Op = *OI;
      if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) &&
          PA.related(Ptr, Op, DL))
        return true;
    }
    return false;
  } else if (const StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
    // Special-case stores, because we don't care about the stored value, just
    // the store address.
    const Value *Op = GetUnderlyingObjCPtr(SI->getPointerOperand(), DL);
    // If we can't tell what the underlying object was, assume there is a
    // dependence.
    return IsPotentialRetainableObjPtr(Op, *PA.getAA()) &&
           PA.related(Op, Ptr, DL);
  }

  // Check each operand for a match.
  for (User::const_op_iterator OI = Inst->op_begin(), OE = Inst->op_end();
       OI != OE; ++OI) {
    const Value *Op = *OI;
    if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) && PA.related(Ptr, Op, DL))
      return true;
  }
  return false;
}

/// Test if there can be dependencies on Inst through Arg. This function only
/// tests dependencies relevant for removing pairs of calls.
bool
llvm::objcarc::Depends(DependenceKind Flavor, Instruction *Inst,
                       const Value *Arg, ProvenanceAnalysis &PA) {
  // If we've reached the definition of Arg, stop.
  if (Inst == Arg)
    return true;

  switch (Flavor) {
  case NeedsPositiveRetainCount: {
    ARCInstKind Class = GetARCInstKind(Inst);
    switch (Class) {
    case ARCInstKind::AutoreleasepoolPop:
    case ARCInstKind::AutoreleasepoolPush:
    case ARCInstKind::None:
      return false;
    default:
      return CanUse(Inst, Arg, PA, Class);
    }
  }

  case AutoreleasePoolBoundary: {
    ARCInstKind Class = GetARCInstKind(Inst);
    switch (Class) {
    case ARCInstKind::AutoreleasepoolPop:
    case ARCInstKind::AutoreleasepoolPush:
      // These mark the end and begin of an autorelease pool scope.
      return true;
    default:
      // Nothing else does this.
      return false;
    }
  }

  case CanChangeRetainCount: {
    ARCInstKind Class = GetARCInstKind(Inst);
    switch (Class) {
    case ARCInstKind::AutoreleasepoolPop:
      // Conservatively assume this can decrement any count.
      return true;
    case ARCInstKind::AutoreleasepoolPush:
    case ARCInstKind::None:
      return false;
    default:
      return CanAlterRefCount(Inst, Arg, PA, Class);
    }
  }

  case RetainAutoreleaseDep:
    switch (GetBasicARCInstKind(Inst)) {
    case ARCInstKind::AutoreleasepoolPop:
    case ARCInstKind::AutoreleasepoolPush:
      // Don't merge an objc_autorelease with an objc_retain inside a different
      // autoreleasepool scope.
      return true;
    case ARCInstKind::Retain:
    case ARCInstKind::RetainRV:
      // Check for a retain of the same pointer for merging.
      return GetArgRCIdentityRoot(Inst) == Arg;
    default:
      // Nothing else matters for objc_retainAutorelease formation.
      return false;
    }

  case RetainAutoreleaseRVDep: {
    ARCInstKind Class = GetBasicARCInstKind(Inst);
    switch (Class) {
    case ARCInstKind::Retain:
    case ARCInstKind::RetainRV:
      // Check for a retain of the same pointer for merging.
      return GetArgRCIdentityRoot(Inst) == Arg;
    default:
      // Anything that can autorelease interrupts
      // retainAutoreleaseReturnValue formation.
      return CanInterruptRV(Class);
    }
  }

  case RetainRVDep:
    return CanInterruptRV(GetBasicARCInstKind(Inst));
  }

  llvm_unreachable("Invalid dependence flavor");
}

/// Walk up the CFG from StartPos (which is in StartBB) and find local and
/// non-local dependencies on Arg.
///
/// TODO: Cache results?
void
llvm::objcarc::FindDependencies(DependenceKind Flavor,
                                const Value *Arg,
                                BasicBlock *StartBB, Instruction *StartInst,
                                SmallPtrSetImpl<Instruction *> &DependingInsts,
                                SmallPtrSetImpl<const BasicBlock *> &Visited,
                                ProvenanceAnalysis &PA) {
  BasicBlock::iterator StartPos = StartInst->getIterator();

  SmallVector<std::pair<BasicBlock *, BasicBlock::iterator>, 4> Worklist;
  Worklist.push_back(std::make_pair(StartBB, StartPos));
  do {
    std::pair<BasicBlock *, BasicBlock::iterator> Pair =
      Worklist.pop_back_val();
    BasicBlock *LocalStartBB = Pair.first;
    BasicBlock::iterator LocalStartPos = Pair.second;
    BasicBlock::iterator StartBBBegin = LocalStartBB->begin();
    for (;;) {
      if (LocalStartPos == StartBBBegin) {
        pred_iterator PI(LocalStartBB), PE(LocalStartBB, false);
        if (PI == PE)
          // If we've reached the function entry, produce a null dependence.
          DependingInsts.insert(nullptr);
        else
          // Add the predecessors to the worklist.
          do {
            BasicBlock *PredBB = *PI;
            if (Visited.insert(PredBB).second)
              Worklist.push_back(std::make_pair(PredBB, PredBB->end()));
          } while (++PI != PE);
        break;
      }

      Instruction *Inst = &*--LocalStartPos;
      if (Depends(Flavor, Inst, Arg, PA)) {
        DependingInsts.insert(Inst);
        break;
      }
    }
  } while (!Worklist.empty());

  // Determine whether the original StartBB post-dominates all of the blocks we
  // visited. If not, insert a sentinal indicating that most optimizations are
  // not safe.
  for (const BasicBlock *BB : Visited) {
    if (BB == StartBB)
      continue;
    for (const BasicBlock *Succ : successors(BB))
      if (Succ != StartBB && !Visited.count(Succ)) {
        DependingInsts.insert(reinterpret_cast<Instruction *>(-1));
        return;
      }
  }
}
