//===--- Local.h - Local SIL transformations. -------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_SILOPTIMIZER_UTILS_LOCAL_H
#define SWIFT_SILOPTIMIZER_UTILS_LOCAL_H

#include "swift/Basic/ArrayRefView.h"
#include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
#include "swift/SILOptimizer/Analysis/SimplifyInstruction.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILBuilder.h"
#include "swift/SIL/SILCloner.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Allocator.h"
#include <functional>
#include <utility>

namespace swift {

class DominanceInfo;

/// Transform a Use Range (Operand*) into a User Range (SILInstruction*)
using UserTransform = std::function<SILInstruction *(Operand *)>;
using ValueBaseUserRange =
  TransformRange<IteratorRange<ValueBase::use_iterator>, UserTransform>;

inline ValueBaseUserRange makeUserRange(
    iterator_range<ValueBase::use_iterator> R) {
  auto toUser = [](Operand *O) { return O->getUser(); };
  return makeTransformRange(makeIteratorRange(R.begin(), R.end()),
                            UserTransform(toUser));
}

using DeadInstructionSet = llvm::SmallSetVector<SILInstruction *, 8>;

/// \brief Create a retain of \p Ptr before the \p InsertPt.
SILInstruction *createIncrementBefore(SILValue Ptr, SILInstruction *InsertPt);

/// \brief Create a release of \p Ptr before the \p InsertPt.
SILInstruction *createDecrementBefore(SILValue Ptr, SILInstruction *InsertPt);

/// \brief For each of the given instructions, if they are dead delete them
/// along with their dead operands.
///
/// \param I The instruction to be deleted.
/// \param Force If Force is set, don't check if the top level instructions
///        are considered dead - delete them regardless.
/// \param C a callback called whenever an instruction is deleted.
void
recursivelyDeleteTriviallyDeadInstructions(
  ArrayRef<SILInstruction*> I, bool Force = false,
  std::function<void(SILInstruction *)> C = [](SILInstruction *){});

/// \brief If the given instruction is dead, delete it along with its dead
/// operands.
///
/// \param I The instruction to be deleted.
/// \param Force If Force is set, don't check if the top level instruction is
///        considered dead - delete it regardless.
/// \param C a callback called whenever an instruction is deleted.
void
recursivelyDeleteTriviallyDeadInstructions(
  SILInstruction *I,
  bool Force = false,
  std::function<void(SILInstruction *)> C = [](SILInstruction *){});

/// \brief Perform a fast local check to see if the instruction is dead.
///
/// This routine only examines the state of the instruction at hand.
bool isInstructionTriviallyDead(SILInstruction *I);

/// \brief Return true if this is a release instruction that's not going to
/// free the object.
bool isIntermediateRelease(SILInstruction *I,
                           ConsumedArgToEpilogueReleaseMatcher &ERM); 

/// \brief Recursively collect all the uses and transitive uses of the
/// instruction.
void
collectUsesOfValue(SILValue V, llvm::SmallPtrSetImpl<SILInstruction *> &Insts);

/// \brief Recursively erase all of the uses of the instruction (but not the
/// instruction itself)
void eraseUsesOfInstruction(
    SILInstruction *Inst,
    std::function<void(SILInstruction *)> C = [](SILInstruction *){});

/// \brief Recursively erase all of the uses of the value (but not the
/// value itself)
void eraseUsesOfValue(SILValue V);

FullApplySite findApplyFromDevirtualizedResult(SILInstruction *I);

/// Check that this is a partial apply of a reabstraction thunk and return the
/// argument of the partial apply if it is.
SILValue isPartialApplyOfReabstractionThunk(PartialApplyInst *PAI);

/// Cast a value into the expected, ABI compatible type if necessary.
/// This may happen e.g. when:
/// - a type of the return value is a subclass of the expected return type.
/// - actual return type and expected return type differ in optionality.
/// - both types are tuple-types and some of the elements need to be casted.
///
/// If CheckOnly flag is set, then this function only checks if the
/// required casting is possible. If it is not possible, then None
/// is returned.
/// If CheckOnly is not set, then a casting code is generated and the final
/// casted value is returned.
Optional<SILValue> castValueToABICompatibleType(SILBuilder *B, SILLocation Loc,
                                                SILValue Value,
                                                SILType SrcTy,
                                                SILType DestTy,
                                                bool CheckOnly = false);

/// Check if the optimizer can cast a value into the expected,
/// ABI compatible type if necessary.
bool canCastValueToABICompatibleType(SILModule &M,
                                     SILType SrcTy, SILType DestTy);

/// Returns a project_box if it is the next instruction after \p ABI and
/// and has \p ABI as operand. Otherwise it creates a new project_box right
/// after \p ABI and returns it.
ProjectBoxInst *getOrCreateProjectBox(AllocBoxInst *ABI);

/// Replace an apply with an instruction that produces the same value,
/// then delete the apply and the instructions that produce its callee
/// if possible.
void replaceDeadApply(ApplySite Old, ValueBase *New);

/// \brief Return true if the substitution map contains a
/// substitution that is an unbound generic type.
bool hasUnboundGenericTypes(TypeSubstitutionMap &SubsMap);

/// Return true if the substitution list contains a substitution
/// that is an unbound generic.
bool hasUnboundGenericTypes(ArrayRef<Substitution> Subs);

/// \brief Return true if the substitution map contains a
/// substitution that refers to the dynamic Self type.
bool hasDynamicSelfTypes(TypeSubstitutionMap &SubsMap);

/// \brief Return true if the substitution list contains a
/// substitution that refers to the dynamic Self type.
bool hasDynamicSelfTypes(ArrayRef<Substitution> Subs);

/// \brief Return true if any call inside the given function may bind dynamic
/// 'Self' to a generic argument of the callee.
bool mayBindDynamicSelf(SILFunction *F);

/// \brief Move an ApplyInst's FuncRef so that it dominates the call site.
void placeFuncRef(ApplyInst *AI, DominanceInfo *DT);

/// \brief Add an argument, \p val, to the branch-edge that is pointing into
/// block \p Dest. Return a new instruction and do not erase the old
/// instruction.
TermInst *addArgumentToBranch(SILValue Val, SILBasicBlock *Dest,
                              TermInst *Branch);

/// Handle the mechanical aspects of removing an unreachable block.
void removeDeadBlock(SILBasicBlock *BB);

/// Remove all instructions in the body of \p BB in safe manner by using
/// undef.
void clearBlockBody(SILBasicBlock *BB);

/// \brief Get the linkage to be used for specializations of a function with
/// the given linkage.
SILLinkage getSpecializedLinkage(SILFunction *F, SILLinkage L);

/// Tries to optimize a given apply instruction if it is a concatenation of
/// string literals. Returns a new instruction if optimization was possible.
SILInstruction *tryToConcatenateStrings(ApplyInst *AI, SILBuilder &B);


/// Tries to perform jump-threading on all checked_cast_br instruction in
/// function \p Fn.
bool tryCheckedCastBrJumpThreading(SILFunction *Fn, DominanceInfo *DT,
                          SmallVectorImpl<SILBasicBlock *> &BlocksForWorklist);

void recalcDomTreeForCCBOpt(DominanceInfo *DT, SILFunction &F);

/// A structure containing callbacks that are called when an instruction is
/// removed or added.
struct InstModCallbacks {
  using CallbackTy = std::function<void (SILInstruction *)>;
  CallbackTy DeleteInst = [](SILInstruction *I) {
    I->eraseFromParent();
  };
  CallbackTy CreatedNewInst = [](SILInstruction *){};

  InstModCallbacks(CallbackTy DeleteInst, CallbackTy CreatedNewInst)
    : DeleteInst(DeleteInst), CreatedNewInst(CreatedNewInst) {}
  InstModCallbacks() = default;
  ~InstModCallbacks() = default;
  InstModCallbacks(const InstModCallbacks &) = default;
  InstModCallbacks(InstModCallbacks &&) = default;
};

/// If Closure is a partial_apply or thin_to_thick_function with only local
/// ref count users and a set of post-dominating releases:
///
/// 1. Remove all ref count operations and the closure.
/// 2. Add each one of the last release locations insert releases for the
///    captured args if we have a partial_apply.
///
/// In the future this should be extended to be less conservative with users.
bool
tryDeleteDeadClosure(SILInstruction *Closure,
                     InstModCallbacks Callbacks = InstModCallbacks());

/// Given a SILValue argument to a partial apply \p Arg and the associated
/// parameter info for that argument, perform the necessary cleanups to Arg when
/// one is attempting to delete the partial apply.
void releasePartialApplyCapturedArg(
    SILBuilder &Builder, SILLocation Loc, SILValue Arg, SILParameterInfo PInfo,
    InstModCallbacks Callbacks = InstModCallbacks());

/// This computes the lifetime of a single SILValue.
///
/// This does not compute a set of jointly postdominating use points. Instead it
/// assumes that the value's existing uses already jointly postdominate the
/// definition. This makes sense for values that are returned +1 from an
/// instruction, like partial_apply, and therefore must be released on all paths
/// via strong_release or apply.
class ValueLifetimeAnalysis {
public:

  /// The lifetime frontier for the value. It is the list of instructions
  /// following the last uses of the value. All the frontier instructions
  /// end the value's lifetime.
  typedef llvm::SmallVector<SILInstruction *, 4> Frontier;

  /// Constructor for the value \p Def with a specific set of users of Def's
  /// users.
  ValueLifetimeAnalysis(SILValue Def, ArrayRef<SILInstruction*> UserList) :
      DefValue(Def), UserSet(UserList.begin(), UserList.end()) {
    propagateLiveness();
  }

  /// Constructor for the value \p Def considering all the value's uses.
  ValueLifetimeAnalysis(SILValue Def) : DefValue(Def) {
    for (Operand *Op : Def->getUses()) {
      UserSet.insert(Op->getUser());
    }
    propagateLiveness();
  }

  enum Mode {
    /// Don't split critical edges if the frontier instructions are located on
    /// a critical edges. Instead fail.
    DontModifyCFG,
    
    /// Split critical edges if the frontier instructions are located on
    /// a critical edges.
    AllowToModifyCFG,
    
    /// Ignore exit edges from the lifetime region at all.
    IgnoreExitEdges
  };

  /// Computes and returns the lifetime frontier for the value in \p Fr.
  /// Returns true if all instructions in the frontier could be found in
  /// non-critical edges.
  /// Returns false if some frontier instructions are located on critical edges.
  /// In this case, if \p mode is AllowToModifyCFG, those critical edges are
  /// split, otherwise nothing is done and the returned \p Fr is not valid.
  bool computeFrontier(Frontier &Fr, Mode mode);

  /// Returns true if the instruction \p Inst is located within the value's
  /// lifetime.
  /// It is assumed that \p Inst is located after the value's definition.
  bool isWithinLifetime(SILInstruction *Inst);

  /// For debug dumping.
  void dump() const;

private:

  /// The value.
  SILValue DefValue;

  /// The set of blocks where the value is live.
  llvm::SmallSetVector<SILBasicBlock *, 16> LiveBlocks;

  /// The set of instructions where the value is used, or the users-list
  /// provided with the constructor.
  llvm::SmallPtrSet<SILInstruction*, 16> UserSet;

  /// Propagates the liveness information up the control flow graph.
  void propagateLiveness();

  /// Returns the last use of the value in the live block \p BB.
  SILInstruction *findLastUserInBlock(SILBasicBlock *BB);
};

/// Base class for BB cloners.
class BaseThreadingCloner : public SILClonerWithScopes<BaseThreadingCloner> {
  friend class SILVisitor<BaseThreadingCloner>;
  friend class SILCloner<BaseThreadingCloner>;

  protected:
  SILBasicBlock *FromBB, *DestBB;

  public:
  // A map of old to new available values.
  SmallVector<std::pair<ValueBase *, SILValue>, 16> AvailVals;

  /// If WithinFunction is true, the debug scopes of the cloned
  /// instructions will not be updated.
  BaseThreadingCloner(SILFunction &To, bool WithinFunction)
      : SILClonerWithScopes(To, WithinFunction), FromBB(nullptr),
        DestBB(nullptr) {}

  BaseThreadingCloner(SILFunction &To, SILBasicBlock *From, SILBasicBlock *Dest)
      : SILClonerWithScopes(To, From->getParent() == &To), FromBB(From),
        DestBB(Dest) {}

  void process(SILInstruction *I) { visit(I); }

  SILBasicBlock *remapBasicBlock(SILBasicBlock *BB) { return BB; }

  SILValue remapValue(SILValue Value) {
    // If this is a use of an instruction in another block, then just use it.
    if (auto SI = dyn_cast<SILInstruction>(Value)) {
      if (SI->getParent() != FromBB)
        return Value;
    } else if (auto BBArg = dyn_cast<SILArgument>(Value)) {
      if (BBArg->getParent() != FromBB)
        return Value;
    } else {
      assert(isa<SILUndef>(Value) && "Unexpected Value kind");
      return Value;
    }

    return SILCloner<BaseThreadingCloner>::remapValue(Value);
  }

  void postProcess(SILInstruction *Orig, SILInstruction *Cloned) {
    DestBB->push_back(Cloned);
    SILCloner<BaseThreadingCloner>::postProcess(Orig, Cloned);
    // A terminator defines no values. Keeping terminators in the AvailVals list
    // is problematic because terminators get replaced during SSA update.
    if (!isa<TermInst>(Orig))
      AvailVals.push_back(std::make_pair(Orig, SILValue(Cloned)));
  }
};

/// Clone a basic block to edge \p BI.
class EdgeThreadingCloner : public BaseThreadingCloner {
public:
  EdgeThreadingCloner(BranchInst *BI)
      : BaseThreadingCloner(*BI->getFunction(),
                            BI->getDestBB(), nullptr) {
    DestBB = createEdgeBlockAndRedirectBranch(BI);
  }

  SILBasicBlock *createEdgeBlockAndRedirectBranch(BranchInst *BI) {
    auto *Fn = BI->getFunction();
    auto *SrcBB = BI->getParent();
    auto *DestBB = BI->getDestBB();
    auto *EdgeBB = new (Fn->getModule()) SILBasicBlock(Fn, SrcBB);

    // Create block arguments.
    unsigned ArgIdx = 0;
    for (auto Arg : BI->getArgs()) {
      assert(Arg->getType() == DestBB->getBBArg(ArgIdx)->getType() &&
             "Types must match");
      auto *BlockArg = EdgeBB->createBBArg(Arg->getType());
      ValueMap[DestBB->getBBArg(ArgIdx)] = SILValue(BlockArg);
      AvailVals.push_back(std::make_pair(DestBB->getBBArg(ArgIdx), BlockArg));
      ++ArgIdx;
    }

    // Redirect the branch.
    SILBuilderWithScope(BI).createBranch(BI->getLoc(), EdgeBB, BI->getArgs());
    BI->eraseFromParent();
    return EdgeBB;
  }

  SILBasicBlock *getEdgeBB() {
    // DestBB really is the edge basic block we created to clone instructions
    // to.
    return DestBB;
  }
};

/// Helper class for cloning of basic blocks.
class BasicBlockCloner : public BaseThreadingCloner {
  public:
    BasicBlockCloner(SILBasicBlock *From, SILBasicBlock *To = nullptr,
                     bool WithinFunction = true)
        : BaseThreadingCloner(To ? *To->getParent() : *From->getParent(),
                              WithinFunction) {
      FromBB = From;
      if (To == nullptr) {
        // Create a new BB that is to be used as a target
        // for cloning.
        To = From->getParent()->createBasicBlock();
        for (auto *Arg : FromBB->getBBArgs()) {
          To->createBBArg(Arg->getType(), Arg->getDecl());
        }
      }
      DestBB = To;

      // Populate the value map so that uses of the BBArgs in the SrcBB are
      // replaced with the BBArgs of the DestBB.
      for (unsigned i = 0, e = FromBB->bbarg_size(); i != e; ++i) {
        ValueMap[FromBB->getBBArg(i)] = DestBB->getBBArg(i);
        AvailVals.push_back(
            std::make_pair(FromBB->getBBArg(i), DestBB->getBBArg(i)));
      }
    }

    // Clone all instructions of the FromBB into DestBB
    void clone() {
      for (auto &I : *FromBB)
        process(&I);
    }

    SILBasicBlock *getDestBB() { return DestBB; }
};

/// Helper function to perform SSA updates in case of jump threading. Set
/// 'NeedToSplitCriticalEdges' to false if all critical edges are split,
/// otherwise this call will try to split all critical edges.
void updateSSAAfterCloning(BaseThreadingCloner &Cloner, SILBasicBlock *SrcBB,
                           SILBasicBlock *DestBB,
                           bool NeedToSplitCriticalEdges = true);

/// \brief This is a helper class used to optimize casts.
class CastOptimizer {
  // Callback to be called when uses of an instruction should be replaced.
  std::function<void (SILInstruction *I, ValueBase *V)> ReplaceInstUsesAction;

  // Callback to call when an instruction needs to be erased.
  std::function<void (SILInstruction *)> EraseInstAction;

  // Callback to call after an optimization was performed based on the fact
  // that a cast will succeed.
  std::function<void ()> WillSucceedAction;

  // Callback to call after an optimization was performed based on the fact
  // that a cast will fail.
  std::function<void ()> WillFailAction;

  /// Optimize a cast from a bridged ObjC type into
  /// a corresponding Swift type implementing _ObjectiveCBridgeable.
  SILInstruction *
  optimizeBridgedObjCToSwiftCast(SILInstruction *Inst,
      bool isConditional,
      SILValue Src,
      SILValue Dest,
      CanType Source,
      CanType Target,
      Type BridgedSourceTy,
      Type BridgedTargetTy,
      SILBasicBlock *SuccessBB,
      SILBasicBlock *FailureBB);

  /// Optimize a cast from a Swift type implementing _ObjectiveCBridgeable
  /// into a bridged ObjC type.
  SILInstruction *
  optimizeBridgedSwiftToObjCCast(SILInstruction *Inst,
      CastConsumptionKind ConsumptionKind,
      bool isConditional,
      SILValue Src,
      SILValue Dest,
      CanType Source,
      CanType Target,
      Type BridgedSourceTy,
      Type BridgedTargetTy,
      SILBasicBlock *SuccessBB,
      SILBasicBlock *FailureBB);

  void deleteInstructionsAfterUnreachable(SILInstruction *UnreachableInst,
                                          SILInstruction *TrapInst);

public:
  CastOptimizer(std::function<void (SILInstruction *I, ValueBase *V)> ReplaceInstUsesAction,
                std::function<void (SILInstruction *)> EraseAction,
                std::function<void ()> WillSucceedAction,
                std::function<void ()> WillFailAction = [](){})
    : ReplaceInstUsesAction(ReplaceInstUsesAction),
      EraseInstAction(EraseAction),
      WillSucceedAction(WillSucceedAction),
      WillFailAction(WillFailAction) {}

  // This constructor is used in
  // 'SILOptimizer/Mandatory/ConstantPropagation.cpp'. MSVC2015 compiler
  // couldn't use the single constructor version which has three default
  // arguments. It seems the number of the default argument with lambda is
  // limited.
  CastOptimizer(std::function<void (SILInstruction *I, ValueBase *V)> ReplaceInstUsesAction,
                std::function<void (SILInstruction *)> EraseAction = [](SILInstruction*){})
    : CastOptimizer(ReplaceInstUsesAction, EraseAction, [](){}, [](){}) {}

  /// Simplify checked_cast_br. It may change the control flow.
  SILInstruction *
  simplifyCheckedCastBranchInst(CheckedCastBranchInst *Inst);

  /// Simplify checked_cast_addr_br. It may change the control flow.
  SILInstruction *
  simplifyCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *Inst);

  /// Optimize checked_cast_br. This cannot change the control flow.
  SILInstruction *
  optimizeCheckedCastBranchInst(CheckedCastBranchInst *Inst);

  /// Optimize checked_cast_addr_br. This cannot change the control flow.
  SILInstruction *
  optimizeCheckedCastAddrBranchInst(CheckedCastAddrBranchInst *Inst);

  /// Optimize unconditional_checked_cast. This cannot change the control flow.
  ValueBase *
  optimizeUnconditionalCheckedCastInst(UnconditionalCheckedCastInst *Inst);

  /// Optimize unconditional_checked_cast_addr. This cannot change the control
  /// flow.
  SILInstruction *
  optimizeUnconditionalCheckedCastAddrInst(UnconditionalCheckedCastAddrInst *Inst);

  /// Check if it is a bridged cast and optimize it.
  /// May change the control flow.
  SILInstruction *
  optimizeBridgedCasts(SILInstruction *Inst,
      CastConsumptionKind ConsumptionKind,
      bool isConditional,
      SILValue Src,
      SILValue Dest,
      CanType Source,
      CanType Target,
      SILBasicBlock *SuccessBB,
      SILBasicBlock *FailureBB);

};

// Helper class that provides a callback that can be used in
// inliners/cloners for collecting new call sites.
class CloneCollector {
public:
  typedef std::pair<SILInstruction *, SILInstruction *> value_type;
  typedef std::function<void(SILInstruction *, SILInstruction *)> CallbackType;
  typedef std::function<bool (SILInstruction *)> FilterType;

private:
  FilterType Filter;

  // Pairs of collected instructions; (new, old)
  llvm::SmallVector<value_type, 4> InstructionPairs;

  void collect(SILInstruction *Old, SILInstruction *New) {
    if (Filter(New))
      InstructionPairs.push_back(std::make_pair(New, Old));
  }

public:
  CloneCollector(FilterType Filter) : Filter(Filter) {}

  CallbackType getCallback() {
    return std::bind(&CloneCollector::collect, this, std::placeholders::_1,
                     std::placeholders::_2);
  }

  llvm::SmallVectorImpl<value_type> &getInstructionPairs() {
    return InstructionPairs;
  }
};

/// This iterator 'looks through' one level of builtin expect users exposing all
/// users of the looked through builtin expect instruction i.e it presents a
/// view that shows all users as if there were no builtin expect instructions
/// interposed.
class IgnoreExpectUseIterator
    : public std::iterator<std::forward_iterator_tag, Operand *, ptrdiff_t> {
  ValueBaseUseIterator OrigUseChain;
  ValueBaseUseIterator CurrentIter;

  static bool isExpect(Operand *Use) {
    if (auto *BI = dyn_cast<BuiltinInst>(Use->getUser()))
      if (BI->getIntrinsicInfo().ID == llvm::Intrinsic::expect)
        return true;
    return false;
  }

  // Advance through expect users to their users until we encounter a user that
  // is not an expect.
  void advanceThroughExpects() {
    while (CurrentIter == OrigUseChain &&
           CurrentIter != ValueBaseUseIterator(nullptr) &&
           isExpect(*CurrentIter)) {
      auto *Expect = CurrentIter->getUser();
      CurrentIter = Expect->use_begin();
      // Expect with no users advance to next item in original use chain.
      if (CurrentIter == Expect->use_end())
        CurrentIter = ++OrigUseChain;
    }
  }

public:
  IgnoreExpectUseIterator(ValueBase *V)
      : OrigUseChain(V->use_begin()), CurrentIter(V->use_begin()) {
    advanceThroughExpects();
  }

  IgnoreExpectUseIterator() = default;

  Operand *operator*() const { return *CurrentIter; }
  Operand *operator->() const { return *CurrentIter; }
  SILInstruction *getUser() const { return CurrentIter->getUser(); }

  IgnoreExpectUseIterator &operator++() {
    assert(**this && "increment past end()!");
    if (OrigUseChain == CurrentIter) {
      // Use chain of the original value.
      ++OrigUseChain;
      ++CurrentIter;
      // Ignore expects.
      advanceThroughExpects();
      } else {
      // Use chain of an expect.
      ++CurrentIter;
      if (CurrentIter == ValueBaseUseIterator(nullptr)) {
        // At the end of the use chain of an expect.
        CurrentIter = ++OrigUseChain;
        advanceThroughExpects();
      }
    }
    return *this;
  }

  IgnoreExpectUseIterator operator++(int unused) {
    IgnoreExpectUseIterator Copy = *this;
    ++*this;
    return Copy;
  }
  friend bool operator==(IgnoreExpectUseIterator lhs,
                         IgnoreExpectUseIterator rhs) {
    return lhs.CurrentIter == rhs.CurrentIter;
  }
  friend bool operator!=(IgnoreExpectUseIterator lhs,
                         IgnoreExpectUseIterator rhs) {
    return !(lhs == rhs);
  }
};

inline iterator_range<IgnoreExpectUseIterator>
ignore_expect_uses(ValueBase *V) {
  return make_range(IgnoreExpectUseIterator(V),
                    IgnoreExpectUseIterator());
}

/// Run simplifyInstruction() on all of the instruction I's users if they only
/// have one result (since simplifyInstruction assumes that). Replace all uses
/// of the user with its simplification of we succeed. Returns true if we
/// succeed and false otherwise.
///
/// An example of how this is useful is in cases where one is splitting up an
/// aggregate and reforming it, the reformed aggregate may have extract
/// operations from it. These can be simplified and removed.
bool simplifyUsers(SILInstruction *I);

/// Check if a given type is a simple type, i.e. a builtin
/// integer or floating point type or a struct/tuple whose members
/// are of simple types.
bool isSimpleType(SILType SILTy, SILModule& Module);

/// Check if the value of V is computed by means of a simple initialization.
/// Store the actual SILValue into \p Val and the reversed list of instructions
/// initializing it in \p Insns.
/// The check is performed by recursively walking the computation of the
/// SIL value being analyzed.
bool analyzeStaticInitializer(SILValue V,
                              SmallVectorImpl<SILInstruction *> &Insns);

/// Replace load sequence which may contain
/// a chain of struct_element_addr followed by a load.
/// The sequence is traversed inside out, i.e.
/// starting with the innermost struct_element_addr
void replaceLoadSequence(SILInstruction *I,
                         SILInstruction *Value,
                         SILBuilder &B);


/// Do we have enough information to determine all callees that could
/// be reached by calling the function represented by Decl?
bool calleesAreStaticallyKnowable(SILModule &M, SILDeclRef Decl);

/// Hoist the address projection rooted in \p Op to \p InsertBefore.
/// Requires the projected value to dominate the insertion point.
///
/// Will look through single basic block predecessor arguments.
void hoistAddressProjections(Operand &Op, SILInstruction *InsertBefore,
                             DominanceInfo *DomTree);

} // end namespace swift

#endif
