//===--- CastOptimizer.cpp ------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
///
/// \file
///
/// This file contains local cast optimizations and simplifications.
///
//===----------------------------------------------------------------------===//

#include "swift/SILOptimizer/Utils/CastOptimizer.h"
#include "swift/AST/GenericSignature.h"
#include "swift/AST/Module.h"
#include "swift/AST/SubstitutionMap.h"
#include "swift/SIL/BasicBlockUtils.h"
#include "swift/SIL/DebugUtils.h"
#include "swift/SIL/DynamicCasts.h"
#include "swift/SIL/InstructionUtils.h"
#include "swift/SIL/SILArgument.h"
#include "swift/SIL/SILBuilder.h"
#include "swift/SIL/SILModule.h"
#include "swift/SIL/SILUndef.h"
#include "swift/SIL/TypeLowering.h"
#include "swift/SILOptimizer/Analysis/ARCAnalysis.h"
#include "swift/SILOptimizer/Analysis/Analysis.h"
#include "swift/SILOptimizer/Analysis/DominanceAnalysis.h"
#include "swift/SILOptimizer/Utils/CFGOptUtils.h"
#include "swift/SILOptimizer/Utils/InstOptUtils.h"
#include "swift/SILOptimizer/Utils/SILOptFunctionBuilder.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include <deque>

using namespace swift;

//===----------------------------------------------------------------------===//
//                  ObjC -> Swift Bridging Cast Optimization
//===----------------------------------------------------------------------===//

static SILFunction *
getObjCToSwiftBridgingFunction(SILOptFunctionBuilder &funcBuilder,
                               SILDynamicCastInst dynamicCast) {
  // inline constructor.
  auto *bridgeFuncDecl = [&]() -> FuncDecl * {
    auto &astContext = dynamicCast.getModule().getASTContext();
    if (dynamicCast.isConditional()) {
      return astContext.getConditionallyBridgeFromObjectiveCBridgeable();
    }
    return astContext.getForceBridgeFromObjectiveCBridgeable();
  }();

  assert(bridgeFuncDecl && "Bridging function doesn't exist?!");

  SILDeclRef funcDeclRef(bridgeFuncDecl, SILDeclRef::Kind::Func);

  // Lookup a function from the stdlib.
  return funcBuilder.getOrCreateFunction(dynamicCast.getLocation(), funcDeclRef,
                                         ForDefinition_t::NotForDefinition);
}

static SubstitutionMap lookupBridgeToObjCProtocolSubs(SILModule &mod,
                                                      CanType target) {
  auto bridgedProto =
      mod.getASTContext().getProtocol(KnownProtocolKind::ObjectiveCBridgeable);
  auto conf = mod.getSwiftModule()->lookupConformance(target, bridgedProto);
  return SubstitutionMap::getProtocolSubstitutions(conf.getRequirement(),
                                                   target, conf);
}

/// Given that our insertion point is at the cast that we are trying to
/// optimize, convert our incoming value to something that can be passed to the
/// bridge call.
static std::pair<SILValue, SILInstruction *>
convertObjectToLoadableBridgeableType(SILBuilderWithScope &builder,
                                      SILDynamicCastInst dynamicCast,
                                      SILValue src) {
  auto *f = dynamicCast.getFunction();
  auto loc = dynamicCast.getLocation();
  bool isConditional = dynamicCast.isConditional();

  SILValue load =
      builder.emitLoadValueOperation(loc, src, LoadOwnershipQualifier::Take);

  SILType silBridgedTy = *dynamicCast.getLoweredBridgedTargetObjectType();

  // If we are not conditional...
  if (!isConditional) {
    // and our loaded type is our bridged type, just return the load as our
    // SILValue and signal to our caller that we did not create a new cast
    // instruction by returning nullptr as second.
    if (load->getType() == silBridgedTy) {
      return {load, nullptr};
    }

    // Otherwise, just perform an unconditional checked cast to the sil bridged
    // ty. We return the cast as our value and as our new cast instruction.
    auto *cast =
        builder.createUnconditionalCheckedCast(loc, load, silBridgedTy,
                                               dynamicCast.getBridgedTargetType());
    return {cast, cast};
  }

  SILBasicBlock *castSuccessBB =
      f->createBasicBlockAfter(dynamicCast.getInstruction()->getParent());
  castSuccessBB->createPhiArgument(silBridgedTy, OwnershipKind::Owned);

  // If we /are/ conditional and we do not need to bridge the load to the sil,
  // then we just create our cast success block and branch from the end of the
  // cast instruction block to the cast success block. We leave our insertion
  // point in the cast success block since when we return, we are going to
  // insert the bridge call/switch there. We return the argument of the cast
  // success block as the value to be passed to the bridging function.
  if (load->getType() == silBridgedTy) {
    castSuccessBB->moveAfter(dynamicCast.getInstruction()->getParent());
    builder.createBranch(loc, castSuccessBB, load);
    builder.setInsertionPoint(castSuccessBB);
    return {castSuccessBB->getArgument(0), nullptr};
  }

  auto *castFailBB = ([&]() -> SILBasicBlock * {
    auto *failureBB = dynamicCast.getFailureBlock();
    SILBuilderWithScope failureBBBuilder(&(*failureBB->begin()), builder);
    return splitBasicBlockAndBranch(failureBBBuilder, &(*failureBB->begin()),
                                    nullptr, nullptr);
  }());

  // Now that we have created the failure bb, move our cast success block right
  // after the checked_cast_br bb.
  castSuccessBB->moveAfter(dynamicCast.getInstruction()->getParent());

  // Ok, we need to perform the full cast optimization. This means that we are
  // going to replace the cast terminator in inst_block with a checked_cast_br.
  auto *ccbi = builder.createCheckedCastBranch(loc, false, load, silBridgedTy,
                                               dynamicCast.getBridgedTargetType(),
                                               castSuccessBB, castFailBB);
  splitEdge(ccbi, /* EdgeIdx to CastFailBB */ 1);

  // Now that we have split the edge to cast fail bb, add the default argument
  // for the checked_cast_br. Then we need to handle our error conditions,
  // namely we destroy on take_always and otherwise store the value back into
  // the memory location that we took it out of.
  {
    auto *newFailureBlock = ccbi->getFailureBB();
    SILValue defaultArg;
    if (builder.hasOwnership()) {
      defaultArg = newFailureBlock->createPhiArgument(load->getType(),
                                                      OwnershipKind::Owned);
    } else {
      defaultArg = ccbi->getOperand();
    }

    // This block should be properly terminated already due to our method of
    // splitting the failure block, so we can use begin() safely.
    SILBuilderWithScope failureBuilder(newFailureBlock->begin());

    switch (dynamicCast.getBridgedConsumptionKind()) {
    case CastConsumptionKind::TakeAlways:
      failureBuilder.emitDestroyValueOperation(loc, defaultArg);
      break;
    case CastConsumptionKind::TakeOnSuccess:
    case CastConsumptionKind::CopyOnSuccess:
      // Without ownership, we do not need to consume the taken value.
      if (failureBuilder.hasOwnership()) {
        failureBuilder.emitStoreValueOperation(loc, defaultArg, src,
                                               StoreOwnershipQualifier::Init);
      }
      break;
    case CastConsumptionKind::BorrowAlways:
      llvm_unreachable("this should never occur here");
    }
  }

  builder.setInsertionPoint(castSuccessBB);
  return {castSuccessBB->getArgument(0), ccbi};
}

/// Create a call of _forceBridgeFromObjectiveC_bridgeable or
/// _conditionallyBridgeFromObjectiveC_bridgeable which converts an ObjC
/// instance into a corresponding Swift type, conforming to
/// _ObjectiveCBridgeable.
///
/// Control Flow Modification Model
/// ===============================
///
/// NOTE: In the following we assume that our src type is not address only. We
/// do not support optimizing such source types today.
///
/// Unconditional Casts
/// -------------------
///
/// In the case of unconditional casts, we do not touch the CFG at all. We
/// perform the following optimizations:
///
/// 1. If the bridged type and the src type equal, we replace the cast with the
///    apply.
///
/// 2. If src is an address and bridged type has the matching object type to
///    src, just load the value and again replace the cast with the apply.
///
/// 3. If src is an address and after loading still doesn't match bridged type,
///    insert an unconditional_checked_cast before calling the apply.
///
/// Conditional Casts
/// -----------------
///
/// In the case of a conditional const (i.e. checked_cast_addr_br), we transform
/// the following CFG:
///
/// ```
///    InstBlock (checked_cast_addr_br) -> FailureBB -> FailureSucc
///        \
///         \----------------------------> SuccessBB -> SuccessSucc
/// ```
///
/// to a CFG of the following form:
///
/// ```
///   InstBlock (checked_cast_br) -> CastFailBB -> FailureBB -> FailureSucc
///        |                                          ^
///        \-> CastSuccessBB (bridge call + switch) --|
///                 |
///                 \-> BridgeSuccessBB -> SuccessBB -> SuccessSucc
/// ```
///
/// NOTE: That if the underlying src type matches the type of the underlying
/// bridge source object, we can omit the initial checked_cast_br and just load
/// the value + branch to the CastSuccessBB. This results instead in the
/// following CFG:
///
/// ```
///   InstBlock (br)                             FailureBB -> FailureSucc
///        |                                          ^
///        \-> CastSuccessBB (bridge call + switch) --|
///                 |
///                 \-> BridgeSuccessBB -> SuccessBB -> SuccessSucc
/// ```
///
SILInstruction *
CastOptimizer::optimizeBridgedObjCToSwiftCast(SILDynamicCastInst dynamicCast) {
  auto kind = dynamicCast.getKind();
  (void)kind;
  assert(((kind == SILDynamicCastKind::CheckedCastAddrBranchInst) ||
          (kind == SILDynamicCastKind::UnconditionalCheckedCastAddrInst)) &&
         "Unsupported dynamic cast kind");

  CanType target = dynamicCast.getTargetFormalType();
  auto &mod = dynamicCast.getModule();

  // AnyHashable is a special case that we do not handle since we only handle
  // objc targets in this function. Bailout early.
  if (auto dt = target.getNominalOrBoundGenericNominal()) {
    if (dt == mod.getASTContext().getAnyHashableDecl()) {
      return nullptr;
    }
  }

  SILValue src = dynamicCast.getSource();

  SILInstruction *Inst = dynamicCast.getInstruction();
  auto *F = Inst->getFunction();

  // Check if we have a source type that is address only. We do not support that
  // today.
  if (src->getType().isAddressOnly(*F)) {
    return nullptr;
  }

  bool isConditional = dynamicCast.isConditional();
  SILValue Dest = dynamicCast.getDest();
  SILBasicBlock *SuccessBB = dynamicCast.getSuccessBlock();
  SILBasicBlock *FailureBB = dynamicCast.getFailureBlock();
  auto Loc = Inst->getLoc();

  // The conformance to _BridgedToObjectiveC is statically known.
  // Retrieve the bridging operation to be used if a static conformance
  // to _BridgedToObjectiveC can be proven.
  SILFunction *bridgingFunc =
      getObjCToSwiftBridgingFunction(functionBuilder, dynamicCast);
  if (!bridgingFunc)
    return nullptr;

  auto paramTypes = bridgingFunc->getLoweredFunctionType()->getParameters();
  (void)paramTypes;
  assert(paramTypes[0].getConvention() ==
             ParameterConvention::Direct_Guaranteed &&
         "Parameter should be @guaranteed");

  SILBuilderWithScope Builder(Inst, builderContext);

  // Generate a load for the source argument since as part of our optimization
  // we are going to promote the cast to work with objects instead of
  // addresses. Additionally, if we have an objc object that is not bridgeable,
  // but that could be converted to something that is bridgeable, we try to
  // convert to the bridgeable type.
  SILValue srcOp;
  SILInstruction *newI;
  std::tie(srcOp, newI) =
      convertObjectToLoadableBridgeableType(Builder, dynamicCast, src);

  // Now emit the a cast from the casted ObjC object into a target type.
  // This is done by means of calling _forceBridgeFromObjectiveC or
  // _conditionallyBridgeFromObjectiveC_bridgeable from the Target type.
  auto *funcRef = Builder.createFunctionRefFor(Loc, bridgingFunc);
  SubstitutionMap subMap = lookupBridgeToObjCProtocolSubs(mod, target);

  auto MetaTy = MetatypeType::get(target, MetatypeRepresentation::Thick);
  auto SILMetaTy = F->getTypeLowering(MetaTy).getLoweredType();
  auto *MetaTyVal = Builder.createMetatype(Loc, SILMetaTy);

  // Temporary to hold the intermediate result.
  AllocStackInst *Tmp = nullptr;
  CanType OptionalTy;
  SILValue outOptionalParam;
  if (isConditional) {
    // Create a temporary
    OptionalTy = OptionalType::get(Dest->getType().getASTType())
                     ->getImplementationType()
                     ->getCanonicalType();
    Tmp = Builder.createAllocStack(Loc,
                                   SILType::getPrimitiveObjectType(OptionalTy));
    outOptionalParam = Tmp;
  } else {
    outOptionalParam = Dest;
  }

  // Emit a retain.
  SILValue srcArg = Builder.emitCopyValueOperation(Loc, srcOp);

  SmallVector<SILValue, 1> Args;
  Args.push_back(outOptionalParam);
  Args.push_back(srcArg);
  Args.push_back(MetaTyVal);

  auto *AI = Builder.createApply(Loc, funcRef, subMap, Args);

  // If we have guaranteed normal arguments, insert the destroy.
  //
  // TODO: Is it safe to just eliminate the initial retain?
  Builder.emitDestroyOperation(Loc, srcArg);

  // If we have an unconditional_checked_cast_addr, return early. We do not need
  // to handle any conditional code.
  if (isa<UnconditionalCheckedCastAddrInst>(Inst)) {
    // Destroy the source value as unconditional_checked_cast_addr would.
    Builder.emitDestroyOperation(Loc, srcOp);
    eraseInstAction(Inst);
    return (newI) ? newI : AI;
  }

  auto *CCABI = cast<CheckedCastAddrBranchInst>(Inst);
  switch (CCABI->getConsumptionKind()) {
  case CastConsumptionKind::TakeAlways:
    Builder.emitDestroyOperation(Loc, srcOp);
    break;
  case CastConsumptionKind::TakeOnSuccess: {
    {
      // Insert a release in the success BB.
      SILBuilderWithScope successBuilder(SuccessBB->begin());
      successBuilder.emitDestroyOperation(Loc, srcOp);
    }
    {
      // And a store in the failure BB.
      if (Builder.hasOwnership()) {
        SILBuilderWithScope failureBuilder(FailureBB->begin());
        SILValue writeback = srcOp;
        SILType srcType = src->getType().getObjectType();
        if (writeback->getType() != srcType) {
          writeback =
              failureBuilder.createUncheckedRefCast(Loc, writeback, srcType);
        }
        failureBuilder.emitStoreValueOperation(Loc, writeback, src,
                                               StoreOwnershipQualifier::Init);
      }
    }
    break;
  }
  case CastConsumptionKind::BorrowAlways:
    llvm_unreachable("checked_cast_addr_br never has BorrowAlways");
  case CastConsumptionKind::CopyOnSuccess:
    // If we are performing copy_on_success, store the value back into memory
    // here since we loaded it. We may need to cast back to the actual
    // underlying type.
    if (Builder.hasOwnership()) {
      SILValue writeback = srcOp;
      SILType srcType = src->getType().getObjectType();
      if (writeback->getType() != srcType) {
        writeback = Builder.createUncheckedRefCast(Loc, writeback, srcType);
      }
      Builder.emitStoreValueOperation(Loc, writeback, src,
                                      StoreOwnershipQualifier::Init);
    }
    break;
  }

  // Results should be checked in case we process a conditional
  // case. E.g. casts from NSArray into [SwiftType] may fail, i.e. return .None.
  if (isConditional) {
    // Copy the temporary into Dest.
    // Load from the optional.
    auto *SomeDecl = Builder.getASTContext().getOptionalSomeDecl();

    auto *BridgeSuccessBB =
        Inst->getFunction()->createBasicBlockAfter(Builder.getInsertionBB());
    SmallVector<std::pair<EnumElementDecl *, SILBasicBlock *>, 2> CaseBBs;
    CaseBBs.emplace_back(SomeDecl, BridgeSuccessBB);
    CaseBBs.emplace_back(mod.getASTContext().getOptionalNoneDecl(), FailureBB);

    Builder.createSwitchEnumAddr(Loc, outOptionalParam, nullptr, CaseBBs);

    Builder.setInsertionPoint(FailureBB->begin());
    Builder.createDeallocStack(Loc, Tmp);

    Builder.setInsertionPoint(BridgeSuccessBB);
    auto Addr = Builder.createUncheckedTakeEnumDataAddr(Loc, outOptionalParam,
                                                        SomeDecl);

    Builder.createCopyAddr(Loc, Addr, Dest, IsTake, IsInitialization);

    Builder.createDeallocStack(Loc, Tmp);
    SmallVector<SILValue, 1> SuccessBBArgs;
    Builder.createBranch(Loc, SuccessBB, SuccessBBArgs);
  }

  eraseInstAction(Inst);
  return (newI) ? newI : AI;
}

//===----------------------------------------------------------------------===//
//                  Swift -> ObjC Bridging Cast Optimization
//===----------------------------------------------------------------------===//

static bool canOptimizeCast(const swift::Type &BridgedTargetTy,
                            swift::SILModule &M,
                            swift::SILFunctionConventions &substConv,
                            TypeExpansionContext context) {
  // DestTy is the type which we want to convert to
  SILType DestTy =
      SILType::getPrimitiveObjectType(BridgedTargetTy->getCanonicalType());
  // ConvTy  is the return type of the _bridgeToObjectiveCImpl()
  auto ConvTy = substConv.getSILResultType(context).getObjectType();
  if (ConvTy == DestTy) {
    // Destination is the same type
    return true;
  }
  // Check if a superclass/subclass of the source operand
  if (DestTy.isExactSuperclassOf(ConvTy)) {
    return true;
  }
  if (ConvTy.isExactSuperclassOf(DestTy)) {
    return true;
  }
  // check if it is a bridgeable CF type
  if (ConvTy.getASTType() ==
      getNSBridgedClassOfCFClass(M.getSwiftModule(),
                                 DestTy.getASTType())) {
    return true;
  }
  if (DestTy.getASTType() ==
      getNSBridgedClassOfCFClass(M.getSwiftModule(),
                                 ConvTy.getASTType())) {
    return true;
  }
  // All else failed - can't optimize this case
  return false;
}

static Optional<std::pair<SILFunction *, SubstitutionMap>>
findBridgeToObjCFunc(SILOptFunctionBuilder &functionBuilder,
                     SILDynamicCastInst dynamicCast) {
  CanType sourceFormalType = dynamicCast.getSourceFormalType();
  auto loc = dynamicCast.getLocation();
  auto &mod = dynamicCast.getModule();
  auto bridgedProto =
      mod.getASTContext().getProtocol(KnownProtocolKind::ObjectiveCBridgeable);

  auto conf = mod.getSwiftModule()->lookupConformance(
    sourceFormalType, bridgedProto);
  assert(conf && "_ObjectiveCBridgeable conformance should exist");
  (void)conf;

  // Generate code to invoke _bridgeToObjectiveC
  ModuleDecl *modDecl =
      mod.getASTContext().getLoadedModule(mod.getASTContext().Id_Foundation);
  if (!modDecl)
    return None;
  SmallVector<ValueDecl *, 2> results;
  modDecl->lookupMember(results,
                        sourceFormalType.getNominalOrBoundGenericNominal(),
                        mod.getASTContext().Id_bridgeToObjectiveC,
                        Identifier());
  ArrayRef<ValueDecl *> resultsRef(results);
  if (resultsRef.empty()) {
    mod.getSwiftModule()->lookupMember(
        results, sourceFormalType.getNominalOrBoundGenericNominal(),
        mod.getASTContext().Id_bridgeToObjectiveC, Identifier());
    resultsRef = results;
  }
  if (resultsRef.size() != 1)
    return None;

  auto *resultDecl = results.front();
  auto memberDeclRef = SILDeclRef(resultDecl);
  auto *bridgedFunc = functionBuilder.getOrCreateFunction(
      loc, memberDeclRef, ForDefinition_t::NotForDefinition);

  // Get substitutions, if source is a bound generic type.
  auto subMap = sourceFormalType->getContextSubstitutionMap(
      mod.getSwiftModule(), resultDecl->getDeclContext());

  // Implementation of _bridgeToObjectiveC could not be found.
  if (!bridgedFunc)
    return None;

  if (dynamicCast.getFunction()->isSerialized() &&
      !bridgedFunc->hasValidLinkageForFragileRef())
    return None;

  if (bridgedFunc->getLoweredFunctionType()
          ->getSingleResult()
          .isFormalIndirect())
    return None;
  return std::make_pair(bridgedFunc, subMap);
}

static SILValue computeFinalCastedValue(SILBuilderWithScope &builder,
                                        SILDynamicCastInst dynamicCast,
                                        ApplyInst *newAI) {
  auto loc = dynamicCast.getLocation();
  auto convTy = newAI->getType();
  bool isConditional = dynamicCast.isConditional();
  auto destLoweredTy = dynamicCast.getTargetLoweredType().getObjectType();
  auto destFormalTy = dynamicCast.getTargetFormalType();
  assert(destLoweredTy == dynamicCast.getLoweredBridgedTargetObjectType() &&
         "Expected Dest Type to be the same as BridgedTargetTy");

  auto &m = dynamicCast.getModule();
  if (convTy == destLoweredTy) {
    return newAI;
  }

  if (destLoweredTy.isExactSuperclassOf(convTy)) {
    return builder.createUpcast(loc, newAI, destLoweredTy);
  }

  if (convTy.isExactSuperclassOf(destLoweredTy)) {
    // If we are not conditional, we are ok with the downcast via checked cast
    // fails since we will trap.
    if (!isConditional) {
      return builder.createUnconditionalCheckedCast(loc, newAI,
                                                    destLoweredTy, destFormalTy);
    }

    // Otherwise if we /are/ emitting a conditional cast, make sure that we
    // handle the failure gracefully.
    //
    // Since we are being returned the value at +1, we need to destroy the
    // newAI on failure.
    auto *failureBB = dynamicCast.getFailureBlock();
    {
      SILBuilderWithScope innerBuilder(&*failureBB->begin(), builder);
      auto valueToDestroy = ([&]() -> SILValue {
        if (!innerBuilder.hasOwnership())
          return newAI;
        return failureBB->createPhiArgument(newAI->getType(),
                                            OwnershipKind::Owned);
      }());
      innerBuilder.emitDestroyOperation(loc, valueToDestroy);
    }

    auto *condBrSuccessBB =
        newAI->getFunction()->createBasicBlockAfter(newAI->getParent());
    condBrSuccessBB->createPhiArgument(destLoweredTy, OwnershipKind::Owned);
    builder.createCheckedCastBranch(loc, /* isExact*/ false, newAI,
                                    destLoweredTy, destFormalTy,
                                    condBrSuccessBB, failureBB);
    builder.setInsertionPoint(condBrSuccessBB, condBrSuccessBB->begin());
    return condBrSuccessBB->getArgument(0);
  }

  if (convTy.getASTType() ==
          getNSBridgedClassOfCFClass(m.getSwiftModule(), destLoweredTy.getASTType()) ||
      destLoweredTy.getASTType() ==
          getNSBridgedClassOfCFClass(m.getSwiftModule(), convTy.getASTType())) {
    // Handle NS <-> CF toll-free bridging here.
    return SILValue(builder.createUncheckedRefCast(loc, newAI, destLoweredTy));
  }

  llvm_unreachable(
      "optimizeBridgedSwiftToObjCCast: should never reach this condition: if "
      "the Destination does not have the same type, is not a bridgeable CF "
      "type and isn't a superclass/subclass of the source operand we should "
      "have bailed earlier.");
}

/// Create a call of _bridgeToObjectiveC which converts an _ObjectiveCBridgeable
/// instance into a bridged ObjC type.
SILInstruction *
CastOptimizer::optimizeBridgedSwiftToObjCCast(SILDynamicCastInst dynamicCast) {
  SILInstruction *Inst = dynamicCast.getInstruction();
  const SILFunction *F = Inst->getFunction();
  CastConsumptionKind ConsumptionKind = dynamicCast.getBridgedConsumptionKind();
  bool isConditional = dynamicCast.isConditional();
  SILValue Src = dynamicCast.getSource();
  SILValue Dest = dynamicCast.getDest();
  CanType BridgedTargetTy = dynamicCast.getBridgedTargetType();
  SILBasicBlock *SuccessBB = dynamicCast.getSuccessBlock();
  SILBasicBlock *FailureBB = dynamicCast.getFailureBlock();
  auto &M = Inst->getModule();
  auto Loc = Inst->getLoc();

  bool AddressOnlyType = false;
  if (!Src->getType().isLoadable(*F) || !Dest->getType().isLoadable(*F)) {
    AddressOnlyType = true;
  }

  // Find the _BridgedToObjectiveC protocol.
  SILFunction *bridgedFunc = nullptr;
  SubstitutionMap subMap;
  {
    auto result = findBridgeToObjCFunc(functionBuilder, dynamicCast);
    if (!result)
      return nullptr;
    std::tie(bridgedFunc, subMap) = result.getValue();
  }

  SILType SubstFnTy = bridgedFunc->getLoweredType().substGenericArgs(
      M, subMap, TypeExpansionContext(*F));
  SILFunctionConventions substConv(SubstFnTy.castTo<SILFunctionType>(), M);

  // Check that this is a case that the authors of this code thought it could
  // handle.
  if (!canOptimizeCast(BridgedTargetTy, M, substConv,
                       F->getTypeExpansionContext())) {
    return nullptr;
  }

  SILBuilderWithScope Builder(Inst, builderContext);
  auto FnRef = Builder.createFunctionRefFor(Loc, bridgedFunc);
  auto ParamTypes = SubstFnTy.castTo<SILFunctionType>()->getParameters();
  SILValue oldSrc;
  if (Src->getType().isAddress() && !substConv.isSILIndirect(ParamTypes[0])) {
    // Create load
    oldSrc = Src;
    Src =
        Builder.emitLoadValueOperation(Loc, Src, LoadOwnershipQualifier::Take);
  }

  // Compensate different owning conventions of the replaced cast instruction
  // and the inserted conversion function.
  bool needReleaseAfterCall = false;
  bool needReleaseInSuccess = false;
  switch (ParamTypes[0].getConvention()) {
  case ParameterConvention::Direct_Guaranteed:
  case ParameterConvention::Indirect_In_Guaranteed:
    switch (ConsumptionKind) {
    case CastConsumptionKind::TakeAlways:
      needReleaseAfterCall = true;
      break;
    case CastConsumptionKind::TakeOnSuccess:
      needReleaseInSuccess = true;
      break;
    case CastConsumptionKind::BorrowAlways:
      llvm_unreachable("Should never hit this");
    case CastConsumptionKind::CopyOnSuccess:
      // We assume that our caller is correct and will treat our argument as
      // being immutable, so we do not need to do anything here.
      break;
    }
    break;
  case ParameterConvention::Direct_Owned:
  case ParameterConvention::Indirect_In:
  case ParameterConvention::Indirect_In_Constant:
    // Currently this
    // cannot appear, because the _bridgeToObjectiveC protocol witness method
    // always receives the this pointer (= the source) as guaranteed.
    // If it became possible (perhaps with the advent of ownership and
    // explicit +1 annotations), the implementation should look something
    // like this:
    /*
    switch (ConsumptionKind) {
      case CastConsumptionKind::TakeAlways:
        break;
      case CastConsumptionKind::TakeOnSuccess:
        needRetainBeforeCall = true;
        needReleaseInSuccess = true;
        break;
      case CastConsumptionKind::CopyOnSuccess:
        needRetainBeforeCall = true;
        break;
    }
    break;
     */
    llvm_unreachable("this should never happen so is currently untestable");
  case ParameterConvention::Direct_Unowned:
    assert(!AddressOnlyType &&
           "AddressOnlyType with Direct_Unowned is not supported");
    break;
  case ParameterConvention::Indirect_Inout:
  case ParameterConvention::Indirect_InoutAliasable:
    // TODO handle remaining indirect argument types
    return nullptr;
  }

  // Generate a code to invoke the bridging function.
  auto *NewAI = Builder.createApply(Loc, FnRef, subMap, Src);

  // First if we are going to destroy the value unconditionally, just insert the
  // destroy right after the call. This handles some of the conditional cases
  // and /all/ of the consuming unconditional cases.
  if (needReleaseAfterCall) {
    Builder.emitDestroyOperation(Loc, Src);
  } else {
    if (SuccessBB) {
      SILBuilderWithScope succBuilder(&*SuccessBB->begin(), Builder);
      if (needReleaseInSuccess) {
        succBuilder.emitDestroyOperation(Loc, Src);
      } else {
        if (oldSrc) {
          succBuilder.emitStoreValueOperation(Loc, Src, oldSrc,
                                              StoreOwnershipQualifier::Init);
        }
      }
      SILBuilderWithScope failBuilder(&*FailureBB->begin(), Builder);
      if (oldSrc) {
        failBuilder.emitStoreValueOperation(Loc, Src, oldSrc,
                                            StoreOwnershipQualifier::Init);
      }
    } else {
      if (oldSrc) {
        Builder.emitStoreValueOperation(Loc, Src, oldSrc,
                                        StoreOwnershipQualifier::Init);
      }
    }
  }

  if (!Dest)
    return NewAI;

  // If it is addr cast then store the result into the dest.
  //
  // NOTE: We assume that dest was uninitialized when passed to us.
  SILValue castedValue = computeFinalCastedValue(Builder, dynamicCast, NewAI);
  auto qual = Builder.hasOwnership() ? StoreOwnershipQualifier::Init
                                     : StoreOwnershipQualifier::Unqualified;
  SILInstruction *NewI = Builder.createStore(Loc, castedValue, Dest, qual);
  if (isConditional && NewI->getParent() != NewAI->getParent()) {
    Builder.createBranch(Loc, SuccessBB);
  }

  eraseInstAction(Inst);
  return NewI;
}

//===----------------------------------------------------------------------===//
//               Top Level Bridge Cast Optimization Entrypoint
//===----------------------------------------------------------------------===//

/// Make use of the fact that some of these casts cannot fail.  For
/// example, if the ObjC type is exactly the expected _ObjectiveCType
/// type, then it would always succeed for NSString, NSNumber, etc.
/// Casts from NSArray, NSDictionary and NSSet may fail.
///
/// If ObjC class is not exactly _ObjectiveCType, then its conversion
/// to a required _ObjectiveCType may fail.
SILInstruction *
CastOptimizer::optimizeBridgedCasts(SILDynamicCastInst dynamicCast) {
  CanType source = dynamicCast.getSourceFormalType();
  CanType target = dynamicCast.getTargetFormalType();
  auto &M = dynamicCast.getModule();

  // To apply the bridged optimizations, we should ensure that types are not
  // existential (and keep in mind that generic parameters can be existentials),
  // and that one of the types is a class and another one is a struct.
  if (source.isAnyExistentialType() || target.isAnyExistentialType() ||
      source->is<ArchetypeType>() || target->is<ArchetypeType>() ||
      (source.getClassOrBoundGenericClass() &&
       !target.getStructOrBoundGenericStruct()) ||
      (target.getClassOrBoundGenericClass() &&
       !source.getStructOrBoundGenericStruct()))
    return nullptr;

  // Casts involving non-bound generic types cannot be optimized.
  if (source->hasArchetype() || target->hasArchetype())
    return nullptr;

  CanType CanBridgedSourceTy = dynamicCast.getBridgedSourceType();
  CanType CanBridgedTargetTy = dynamicCast.getBridgedTargetType();

  // If we were unable to bridge either of our source/target types, return
  // nullptr.
  if (!CanBridgedSourceTy || !CanBridgedTargetTy)
    return nullptr;

  if (CanBridgedSourceTy == source && CanBridgedTargetTy == target) {
    // Both source and target type are ObjC types.
    return nullptr;
  }

  if (CanBridgedSourceTy != source && CanBridgedTargetTy != target) {
    // Both source and target type are Swift types.
    return nullptr;
  }

  if ((CanBridgedSourceTy && CanBridgedSourceTy->getAnyNominal() ==
                                 M.getASTContext().getNSErrorDecl()) ||
      (CanBridgedTargetTy && CanBridgedTargetTy->getAnyNominal() ==
                                 M.getASTContext().getNSErrorDecl())) {
    // FIXME: Can't optimize bridging with NSError.
    return nullptr;
  }

  // Check what kind of conversion it is? ObjC->Swift or Swift-ObjC?
  if (CanBridgedTargetTy != target) {
    // This is an ObjC to Swift cast.
    return optimizeBridgedObjCToSwiftCast(dynamicCast);
  } else {
    // This is a Swift to ObjC cast
    return optimizeBridgedSwiftToObjCCast(dynamicCast);
  }

  llvm_unreachable("Unknown kind of bridging");
}

//===----------------------------------------------------------------------===//
//                         Cast Optimizer Public API
//===----------------------------------------------------------------------===//

SILInstruction *CastOptimizer::simplifyCheckedCastAddrBranchInst(
    CheckedCastAddrBranchInst *Inst) {
  if (auto *I = optimizeCheckedCastAddrBranchInst(Inst))
    Inst = dyn_cast<CheckedCastAddrBranchInst>(I);

  if (!Inst)
    return nullptr;

  SILDynamicCastInst dynamicCast(Inst);
  auto Loc = dynamicCast.getLocation();
  auto Src = dynamicCast.getSource();
  auto Dest = dynamicCast.getDest();
  auto *SuccessBB = dynamicCast.getSuccessBlock();
  auto *FailureBB = dynamicCast.getFailureBlock();

  SILBuilderWithScope Builder(Inst, builderContext);

  // Check if we can statically predict the outcome of the cast.
  auto Feasibility =
      dynamicCast.classifyFeasibility(true /*allow whole module*/);

  if (Feasibility == DynamicCastFeasibility::WillFail) {
    if (shouldDestroyOnFailure(Inst->getConsumptionKind())) {
      auto &srcTL = Builder.getTypeLowering(Src->getType());
      srcTL.emitDestroyAddress(Builder, Loc, Src);
    }
    auto NewI = Builder.createBranch(Loc, FailureBB);
    eraseInstAction(Inst);
    willFailAction();
    return NewI;
  }

  bool ResultNotUsed = isa<AllocStackInst>(Dest);
  if (ResultNotUsed) {
    for (auto Use : Dest->getUses()) {
      auto *User = Use->getUser();
      if (isa<DeallocStackInst>(User) || User == Inst)
        continue;
      ResultNotUsed = false;
      break;
    }
  }

  auto *BB = Inst->getParent();

  SILInstruction *BridgedI = nullptr;

  // To apply the bridged optimizations, we should
  // ensure that types are not existential,
  // and that not both types are classes.
  BridgedI = optimizeBridgedCasts(dynamicCast);

  if (!BridgedI) {
    // If the cast may succeed or fail, and it can't be optimized into a
    // bridging operation, then let it be.
    if (Feasibility == DynamicCastFeasibility::MaySucceed) {
      return nullptr;
    }

    assert(Feasibility == DynamicCastFeasibility::WillSucceed);

    // Replace by unconditional_addr_cast, followed by a branch.
    // The unconditional_addr_cast can be skipped, if the result of a cast
    // is not used afterwards.
    if (ResultNotUsed) {
      if (shouldTakeOnSuccess(Inst->getConsumptionKind())) {
        auto &srcTL = Builder.getTypeLowering(Src->getType());
        srcTL.emitDestroyAddress(Builder, Loc, Src);
      }
      eraseInstAction(Inst);
      Builder.setInsertionPoint(BB);
      auto *NewI = Builder.createBranch(Loc, SuccessBB);
      willSucceedAction();
      return NewI;
    }

    // Since it is an addr cast, only address types are handled here.
    if (!Src->getType().isAddress() || !Dest->getType().isAddress()) {
      return nullptr;
    }

    // Both TakeOnSuccess and TakeAlways can be reduced to an
    // UnconditionalCheckedCast, since the failure path is irrelevant.
    AllocStackInst *copiedSrc = nullptr;
    switch (Inst->getConsumptionKind()) {
    case CastConsumptionKind::BorrowAlways:
      llvm_unreachable("checked_cast_addr_br never has BorrowAlways");
    case CastConsumptionKind::CopyOnSuccess:
      if (!Src->getType().isTrivial(*BB->getParent())) {
        copiedSrc = Builder.createAllocStack(Loc, Src->getType());
        Builder.createCopyAddr(Loc, Src, copiedSrc, IsNotTake, IsInitialization);
        Src = copiedSrc;
      }
      break;
    case CastConsumptionKind::TakeAlways:
    case CastConsumptionKind::TakeOnSuccess:
      break;
    }

    bool result = emitSuccessfulIndirectUnconditionalCast(
      Builder, Builder.getModule().getSwiftModule(), Loc, Src,
      Inst->getSourceFormalType(), Dest, Inst->getTargetFormalType(), Inst);
    (void)result;
    assert(result && "emit cannot fail for an checked_cast_addr_br");

    if (copiedSrc)
      Builder.createDeallocStack(Loc, copiedSrc);
    eraseInstAction(Inst);
  }
  SILInstruction *NewI = &BB->back();
  if (!isa<TermInst>(NewI)) {
    Builder.setInsertionPoint(BB);
    NewI = Builder.createBranch(Loc, SuccessBB);
  }
  willSucceedAction();
  return NewI;
}

SILInstruction *
CastOptimizer::simplifyCheckedCastBranchInst(CheckedCastBranchInst *Inst) {
  if (Inst->isExact()) {
    SILDynamicCastInst dynamicCast(Inst);
    auto *ARI = dyn_cast<AllocRefInst>(stripUpCasts(dynamicCast.getSource()));
    if (!ARI)
      return nullptr;

    // We know the dynamic type of the operand.
    SILBuilderWithScope Builder(Inst, builderContext);
    auto Loc = dynamicCast.getLocation();

    if (ARI->getType() == dynamicCast.getTargetLoweredType()) {
      // This exact cast will succeed.
      SmallVector<SILValue, 1> Args;
      Args.push_back(ARI);
      auto *NewI =
          Builder.createBranch(Loc, dynamicCast.getSuccessBlock(), Args);
      eraseInstAction(Inst);
      willSucceedAction();
      return NewI;
    }

    // This exact cast will fail. With ownership enabled, we pass a copy of the
    // original casts value to the failure block.
    TinyPtrVector<SILValue> Args;
    if (Builder.hasOwnership())
      Args.push_back(dynamicCast.getSource());
    auto *NewI = Builder.createBranch(Loc, dynamicCast.getFailureBlock(), Args);
    eraseInstAction(Inst);
    willFailAction();
    return NewI;
  }

  if (auto *I = optimizeCheckedCastBranchInst(Inst))
    Inst = dyn_cast<CheckedCastBranchInst>(I);

  if (!Inst)
    return nullptr;

  SILDynamicCastInst dynamicCast(Inst);
  auto TargetLoweredType = dynamicCast.getTargetLoweredType();
  auto TargetFormalType = dynamicCast.getTargetFormalType();
  auto Loc = dynamicCast.getLocation();
  auto *SuccessBB = dynamicCast.getSuccessBlock();
  auto Op = dynamicCast.getSource();
  auto *F = dynamicCast.getFunction();

  // Check if we can statically predict the outcome of the cast.
  auto Feasibility =
      dynamicCast.classifyFeasibility(false /*allow whole module*/);
  if (Feasibility == DynamicCastFeasibility::MaySucceed) {
    return nullptr;
  }

  SILBuilderWithScope Builder(Inst, builderContext);
  if (Feasibility == DynamicCastFeasibility::WillFail) {
    TinyPtrVector<SILValue> Args;
    if (Builder.hasOwnership())
      Args.push_back(Inst->getOperand());
    auto *NewI = Builder.createBranch(Loc, dynamicCast.getFailureBlock(), Args);
    eraseInstAction(Inst);
    willFailAction();
    return NewI;
  }

  assert(Feasibility == DynamicCastFeasibility::WillSucceed);

  bool ResultNotUsed = SuccessBB->getArgument(0)->use_empty();
  SILValue CastedValue;
  if (Op->getType() != TargetLoweredType) {
    // Apply the bridged cast optimizations.
    //
    // TODO: Bridged casts cannot be expressed by checked_cast_br yet.
    // Should we ever support it, please review this code.
    auto BridgedI = optimizeBridgedCasts(dynamicCast);

    if (BridgedI) {
      llvm_unreachable(
          "Bridged casts cannot be expressed by checked_cast_br yet");
    } else {
      // Replace by unconditional_cast, followed by a branch.
      // The unconditional_cast can be skipped, if the result of a cast
      // is not used afterwards.
      if (!ResultNotUsed) {
        if (!dynamicCast.canUseScalarCheckedCastInstructions())
          return nullptr;

        CastedValue =
            emitSuccessfulScalarUnconditionalCast(Builder, Loc, dynamicCast);
      } else {
        CastedValue = SILUndef::get(TargetLoweredType, *F);
      }
      if (!CastedValue)
        CastedValue =
            Builder.createUnconditionalCheckedCast(
              Loc, Op, TargetLoweredType, TargetFormalType);
    }

  } else {
    // No need to cast.
    CastedValue = Op;
  }

  auto *NewI = Builder.createBranch(Loc, SuccessBB, CastedValue);
  eraseInstAction(Inst);
  willSucceedAction();
  return NewI;
}

SILInstruction *CastOptimizer::simplifyCheckedCastValueBranchInst(
    CheckedCastValueBranchInst *Inst) {
  if (auto *I = optimizeCheckedCastValueBranchInst(Inst))
    Inst = dyn_cast<CheckedCastValueBranchInst>(I);

  if (!Inst)
    return nullptr;

  SILDynamicCastInst dynamicCast(Inst);
  auto SourceFormalType = dynamicCast.getSourceFormalType();
  auto TargetLoweredType = dynamicCast.getTargetLoweredType();
  auto TargetFormalType = dynamicCast.getTargetFormalType();
  auto Loc = dynamicCast.getLocation();
  auto *SuccessBB = dynamicCast.getSuccessBlock();
  auto *FailureBB = dynamicCast.getFailureBlock();
  auto Op = dynamicCast.getSource();
  auto *F = dynamicCast.getFunction();

  // Check if we can statically predict the outcome of the cast.
  auto Feasibility = dynamicCast.classifyFeasibility(false /*allow wmo opts*/);

  SILBuilderWithScope Builder(Inst, builderContext);

  if (Feasibility == DynamicCastFeasibility::WillFail) {
    auto *NewI = Builder.createBranch(Loc, FailureBB);
    eraseInstAction(Inst);
    willFailAction();
    return NewI;
  }

  // Casting will succeed.

  bool ResultNotUsed = SuccessBB->getArgument(0)->use_empty();
  SILValue CastedValue;
  if (Op->getType() != TargetLoweredType) {
    // Apply the bridged cast optimizations.
    // TODO: Bridged casts cannot be expressed by checked_cast_value_br yet.
    // Once the support for opaque values has landed, please review this
    // code.
    auto *BridgedI = optimizeBridgedCasts(dynamicCast);
    if (BridgedI) {
      llvm_unreachable(
          "Bridged casts cannot be expressed by checked_cast_value_br yet");
    } else {
      // If the cast may succeed or fail and can't be turned into a bridging
      // call, then let it be.
      if (Feasibility == DynamicCastFeasibility::MaySucceed) {
        return nullptr;
      }

      assert(Feasibility == DynamicCastFeasibility::WillSucceed);

      // Replace by unconditional_cast, followed by a branch.
      // The unconditional_cast can be skipped, if the result of a cast
      // is not used afterwards.

      if (!dynamicCast.canUseScalarCheckedCastInstructions())
        return nullptr;

      if (!ResultNotUsed) {
        CastedValue =
            emitSuccessfulScalarUnconditionalCast(Builder, Loc, dynamicCast);
      } else {
        CastedValue = SILUndef::get(TargetLoweredType, *F);
      }
    }
    if (!CastedValue)
      CastedValue = Builder.createUnconditionalCheckedCastValue(
          Loc, Op, SourceFormalType,
          TargetLoweredType, TargetFormalType);
  } else {
    // No need to cast.
    CastedValue = Op;
  }

  auto *NewI = Builder.createBranch(Loc, SuccessBB, CastedValue);
  eraseInstAction(Inst);
  willSucceedAction();
  return NewI;
}

SILInstruction *CastOptimizer::optimizeCheckedCastAddrBranchInst(
    CheckedCastAddrBranchInst *Inst) {
  auto Loc = Inst->getLoc();
  auto Src = Inst->getSrc();
  auto Dest = Inst->getDest();
  auto *SuccessBB = Inst->getSuccessBB();
  auto *FailureBB = Inst->getFailureBB();

  // If there is an unbound generic type involved in the cast, bail.
  if (Src->getType().hasArchetype() || Dest->getType().hasArchetype())
    return nullptr;

  // %1 = metatype $A.Type
  // [%2 = init_existential_metatype %1 ...]
  // %3 = alloc_stack
  // store %1 to %3 or store %2 to %3
  // checked_cast_addr_br %3 to ...
  // ->
  // %1 = metatype $A.Type
  // %c = checked_cast_br %1 to ...
  // store %c to %3 (if successful)
  if (auto *ASI = dyn_cast<AllocStackInst>(Src)) {
    // Check if the value of this alloc_stack is set only once by a store
    // instruction, used only by CCABI and then deallocated.
    bool isLegal = true;
    StoreInst *Store = nullptr;
    for (auto Use : ASI->getUses()) {
      auto *User = Use->getUser();
      if (isa<DeallocStackInst>(User) || User == Inst)
        continue;
      if (auto *SI = dyn_cast<StoreInst>(User)) {
        if (!Store) {
          Store = SI;
          continue;
        }
      }
      isLegal = false;
      break;
    }

    if (isLegal && Store) {
      // Check what was the value stored in the allocated stack slot.
      auto Src = Store->getSrc();
      MetatypeInst *MI = nullptr;
      if (auto *IEMI = dyn_cast<InitExistentialMetatypeInst>(Src)) {
        MI = dyn_cast<MetatypeInst>(IEMI->getOperand());
      }

      if (!MI)
        MI = dyn_cast<MetatypeInst>(Src);

      if (MI) {
        if (SuccessBB->getSinglePredecessorBlock() &&
            canUseScalarCheckedCastInstructions(
                Inst->getModule(), MI->getType().getASTType(),
                Inst->getTargetFormalType())) {
          SILBuilderWithScope B(Inst, builderContext);
          auto NewI = B.createCheckedCastBranch(
              Loc, false /*isExact*/, MI,
              Inst->getTargetLoweredType().getObjectType(),
              Inst->getTargetFormalType(),
              SuccessBB, FailureBB, Inst->getTrueBBCount(),
              Inst->getFalseBBCount());
          SuccessBB->createPhiArgument(Dest->getType().getObjectType(),
                                       OwnershipKind::Owned);
          B.setInsertionPoint(SuccessBB->begin());
          // Store the result
          B.createStore(Loc, SuccessBB->getArgument(0), Dest,
                        StoreOwnershipQualifier::Unqualified);
          eraseInstAction(Inst);
          return NewI;
        }
      }
    }
  }
  return nullptr;
}

SILInstruction *CastOptimizer::optimizeCheckedCastValueBranchInst(
    CheckedCastValueBranchInst *Inst) {
  // TODO
  return nullptr;
}

SILInstruction *
CastOptimizer::optimizeCheckedCastBranchInst(CheckedCastBranchInst *Inst) {
  if (Inst->isExact())
    return nullptr;

  // InstOptUtils.helper we use to simplify replacing a checked_cast_branch with
  // an optimized checked cast branch.
  auto replaceCastHelper = [](SILBuilderWithScope &B,
                              SILDynamicCastInst dynamicCast,
                              MetatypeInst *mi) -> SILInstruction * {
    // Make sure that the failure block has the new metatype type for
    // its default argument as required when we are in ossa
    // mode. Without ossa, failure blocks do not have args, so we do
    // not need to do anything.
    auto *fBlock = dynamicCast.getFailureBlock();
    if (B.hasOwnership()) {
      fBlock->replacePhiArgumentAndReplaceAllUses(0, mi->getType(),
                                                  OwnershipKind::None);
    }
    return B.createCheckedCastBranch(
        dynamicCast.getLocation(), false /*isExact*/, mi,
        dynamicCast.getTargetLoweredType(),
        dynamicCast.getTargetFormalType(),
        dynamicCast.getSuccessBlock(),
        fBlock, *dynamicCast.getSuccessBlockCount(),
        *dynamicCast.getFailureBlockCount());
  };

  SILDynamicCastInst dynamicCast(Inst);

  auto Op = dynamicCast.getSource();

  // Try to simplify checked_cond_br instructions using existential
  // metatypes by propagating a concrete type whenever it can be
  // determined statically.

  // %0 = metatype $A.Type
  // %1 = init_existential_metatype ..., %0: $A
  // checked_cast_br %1, ....
  // ->
  // %0 = metatype $A.Type
  // checked_cast_br %0 to ...
  if (auto *IEMI = dyn_cast<InitExistentialMetatypeInst>(Op)) {
    if (auto *MI = dyn_cast<MetatypeInst>(IEMI->getOperand())) {
      SILBuilderWithScope B(Inst, builderContext);
      auto *NewI = replaceCastHelper(B, dynamicCast, MI);
      eraseInstAction(Inst);
      return NewI;
    }
  }

  if (auto *EMI = dyn_cast<ExistentialMetatypeInst>(Op)) {
    // Operand of the existential_metatype instruction.
    auto Op = EMI->getOperand();
    auto EmiTy = EMI->getType();

    // %0 = alloc_stack $T
    // %1 = init_existential_addr %0: $*T, $A
    // %2 = existential_metatype $T.Type, %0: $*T
    // checked_cast_br %2 to ...
    // ->
    // %1 = metatype $A.Type
    // checked_cast_br %1 to ...

    if (auto *ASI = dyn_cast<AllocStackInst>(Op)) {
      // Should be in the same BB.
      if (ASI->getParent() != EMI->getParent())
        return nullptr;
      // Check if this alloc_stack is only initialized once by means of
      // single init_existential_addr.
      bool isLegal = true;
      // init_existential instruction used to initialize this alloc_stack.
      InitExistentialAddrInst *FoundIEI = nullptr;
      for (auto Use : getNonDebugUses(ASI)) {
        auto *User = Use->getUser();
        if (isa<ExistentialMetatypeInst>(User) || isa<DestroyAddrInst>(User) ||
            isa<DeallocStackInst>(User))
          continue;
        if (auto *IEI = dyn_cast<InitExistentialAddrInst>(User)) {
          if (!FoundIEI) {
            FoundIEI = IEI;
            continue;
          }
        }
        isLegal = false;
        break;
      }

      if (isLegal && FoundIEI) {
        // Should be in the same BB.
        if (FoundIEI->getParent() != EMI->getParent())
          return nullptr;
        // Get the type used to initialize the existential.
        auto LoweredConcreteTy = FoundIEI->getLoweredConcreteType();
        // We don't know enough at compile time about existential
        // and generic type parameters.
        if (LoweredConcreteTy.isAnyExistentialType() ||
            LoweredConcreteTy.is<ArchetypeType>())
          return nullptr;
        // Get the metatype of this type.
        auto EMT = EmiTy.castTo<AnyMetatypeType>();
        auto *MetaTy = MetatypeType::get(LoweredConcreteTy.getASTType(),
                                         EMT->getRepresentation());
        auto CanMetaTy = CanTypeWrapper<MetatypeType>(MetaTy);
        auto SILMetaTy = SILType::getPrimitiveObjectType(CanMetaTy);
        SILBuilderWithScope B(Inst, builderContext);
        B.getOpenedArchetypes().addOpenedArchetypeOperands(
            FoundIEI->getTypeDependentOperands());
        auto *MI = B.createMetatype(FoundIEI->getLoc(), SILMetaTy);
        auto *NewI = replaceCastHelper(B, dynamicCast, MI);
        eraseInstAction(Inst);
        return NewI;
      }
    }

    // %0 = alloc_ref $A
    // %1 = init_existential_ref %0: $A, $...
    // %2 = existential_metatype ..., %1 :  ...
    // checked_cast_br %2, ....
    // ->
    // %1 = metatype $A.Type
    // checked_cast_br %1, ....
    if (auto *FoundIERI = dyn_cast<InitExistentialRefInst>(Op)) {
      auto *ASRI = dyn_cast<AllocRefInst>(FoundIERI->getOperand());
      if (!ASRI)
        return nullptr;
      // Should be in the same BB.
      if (ASRI->getParent() != EMI->getParent())
        return nullptr;
      // Check if this alloc_stack is only initialized once by means of
      // a single init_existential_ref.
      bool isLegal = true;
      for (auto Use : getNonDebugUses(ASRI)) {
        auto *User = Use->getUser();
        if (isa<ExistentialMetatypeInst>(User) || isa<StrongReleaseInst>(User))
          continue;
        if (auto *IERI = dyn_cast<InitExistentialRefInst>(User)) {
          if (IERI == FoundIERI) {
            continue;
          }
        }
        isLegal = false;
        break;
      }

      if (isLegal && FoundIERI) {
        // Should be in the same BB.
        if (FoundIERI->getParent() != EMI->getParent())
          return nullptr;
        // Get the type used to initialize the existential.
        auto ConcreteTy = FoundIERI->getFormalConcreteType();
        // We don't know enough at compile time about existential
        // and generic type parameters.
        if (ConcreteTy.isAnyExistentialType() ||
            ConcreteTy->is<ArchetypeType>())
          return nullptr;
        // Get the SIL metatype of this type.
        auto EMT = EMI->getType().castTo<AnyMetatypeType>();
        auto *MetaTy = MetatypeType::get(ConcreteTy, EMT->getRepresentation());
        auto CanMetaTy = CanTypeWrapper<MetatypeType>(MetaTy);
        auto SILMetaTy = SILType::getPrimitiveObjectType(CanMetaTy);
        SILBuilderWithScope B(Inst, builderContext);
        B.getOpenedArchetypes().addOpenedArchetypeOperands(
            FoundIERI->getTypeDependentOperands());
        auto *MI = B.createMetatype(FoundIERI->getLoc(), SILMetaTy);
        auto *NewI = replaceCastHelper(B, dynamicCast, MI);
        eraseInstAction(Inst);
        return NewI;
      }
    }
  }

  return nullptr;
}

ValueBase *CastOptimizer::optimizeUnconditionalCheckedCastInst(
    UnconditionalCheckedCastInst *Inst) {
  SILDynamicCastInst dynamicCast(Inst);
  auto Loc = dynamicCast.getLocation();

  // Check if we can statically predict the outcome of the cast.
  auto Feasibility =
      dynamicCast.classifyFeasibility(false /*allowWholeModule*/);

  if (Feasibility == DynamicCastFeasibility::WillFail) {
    // Remove the cast and insert a trap, followed by an
    // unreachable instruction.
    SILBuilderWithScope Builder(Inst, builderContext);
    auto *Trap = Builder.createBuiltinTrap(Loc);
    Inst->replaceAllUsesWithUndef();
    eraseInstAction(Inst);
    Builder.setInsertionPoint(std::next(SILBasicBlock::iterator(Trap)));
    auto *UnreachableInst =
        Builder.createUnreachable(ArtificialUnreachableLocation());

    // Delete everything after the unreachable except for dealloc_stack which we
    // move before the trap.
    deleteInstructionsAfterUnreachable(UnreachableInst, Trap);

    willFailAction();
    return Trap;
  }

  if (Feasibility == DynamicCastFeasibility::WillSucceed) {

    if (Inst->use_empty()) {
      eraseInstAction(Inst);
      willSucceedAction();
      return nullptr;
    }
  }

  SILBuilderWithScope Builder(Inst, builderContext);

  // Try to apply the bridged casts optimizations
  auto NewI = optimizeBridgedCasts(dynamicCast);
  if (NewI) {
    // FIXME: I'm not sure why this is true!
    auto newValue = cast<SingleValueInstruction>(NewI);
    replaceInstUsesAction(Inst, newValue);
    eraseInstAction(Inst);
    willSucceedAction();
    return newValue;
  }

  // If the cast may succeed or fail and can't be optimized into a bridging
  // call, let it be.
  if (Feasibility == DynamicCastFeasibility::MaySucceed) {
    return nullptr;
  }

  assert(Feasibility == DynamicCastFeasibility::WillSucceed);

  if (dynamicCast.isBridgingCast())
    return nullptr;

  auto Result =
      emitSuccessfulScalarUnconditionalCast(Builder, Loc, dynamicCast);

  if (!Result) {
    // No optimization was possible.
    return nullptr;
  }

  replaceInstUsesAction(Inst, Result);
  eraseInstAction(Inst);
  willSucceedAction();
  return Result;
}

/// Deletes all instructions after \p UnreachableInst except dealloc_stack
/// instructions are moved before \p TrapInst.
void CastOptimizer::deleteInstructionsAfterUnreachable(
    SILInstruction *UnreachableInst, SILInstruction *TrapInst) {
  auto UnreachableInstIt = std::next(SILBasicBlock::iterator(UnreachableInst));
  auto *Block = TrapInst->getParent();
  while (UnreachableInstIt != Block->end()) {
    SILInstruction *CurInst = &*UnreachableInstIt;
    ++UnreachableInstIt;
    if (auto *DeallocStack = dyn_cast<DeallocStackInst>(CurInst))
      if (!isa<SILUndef>(DeallocStack->getOperand())) {
        DeallocStack->moveBefore(TrapInst);
        continue;
      }
    CurInst->replaceAllUsesOfAllResultsWithUndef();
    eraseInstAction(CurInst);
  }
}

/// TODO: Move to emitSuccessfulIndirectUnconditionalCast?
///
/// Peephole to avoid runtime calls:
/// unconditional_checked_cast_addr T in %0 : $*T to P in %1 : $*P
/// ->
/// %addr = init_existential_addr %1 : $*P, T
/// copy_addr %0 to %addr
///
/// where T is a type statically known to conform to P.
///
/// In caase P is a class existential type, it generates:
/// %val = load %0 : $*T
/// %existential = init_existential_ref %val : $T, $T, P
/// store %existential to %1 : $*P
///
/// Returns true if the optimization was possible and false otherwise.
static bool optimizeStaticallyKnownProtocolConformance(
    UnconditionalCheckedCastAddrInst *Inst) {
  auto Loc = Inst->getLoc();
  auto Src = Inst->getSrc();
  auto Dest = Inst->getDest();
  auto SourceType = Inst->getSourceFormalType();
  auto TargetType = Inst->getTargetFormalType();
  auto &Mod = Inst->getModule();

  if (TargetType->isAnyExistentialType() &&
      !SourceType->isAnyExistentialType()) {
    auto &Ctx = Mod.getASTContext();
    auto *SM = Mod.getSwiftModule();

    auto Proto = dyn_cast<ProtocolDecl>(TargetType->getAnyNominal());
    if (!Proto)
      return false;

    // SourceType is a non-existential type with a non-conditional
    // conformance to a protocol represented by the TargetType.
    //
    // TypeChecker::conformsToProtocol checks any conditional conformances. If
    // they depend on information not known until runtime, the conformance
    // will not be returned. For instance, if `X: P` where `T == Int` in `func
    // foo<T>(_: T) { ... X<T>() as? P ... }`, the cast will succeed for
    // `foo(0)` but not for `foo("string")`. There are many cases where
    // everything is completely static (`X<Int>() as? P`), in which case a
    // valid conformance will be returned.
    auto Conformance = SM->conformsToProtocol(SourceType, Proto);
    if (Conformance.isInvalid())
      return false;

    SILBuilderWithScope B(Inst);
    SmallVector<ProtocolConformanceRef, 1> NewConformances;
    NewConformances.push_back(Conformance);
    ArrayRef<ProtocolConformanceRef> Conformances =
        Ctx.AllocateCopy(NewConformances);

    auto ExistentialRepr =
        Dest->getType().getPreferredExistentialRepresentation(SourceType);

    switch (ExistentialRepr) {
    default:
      return false;
    case ExistentialRepresentation::Opaque: {
      auto ExistentialAddr = B.createInitExistentialAddr(
          Loc, Dest, SourceType, Src->getType().getObjectType(), Conformances);
      B.createCopyAddr(Loc, Src, ExistentialAddr, IsTake_t::IsTake,
                       IsInitialization_t::IsInitialization);
      break;
    }
    case ExistentialRepresentation::Class: {
      auto Value =
          B.emitLoadValueOperation(Loc, Src, LoadOwnershipQualifier::Take);
      auto Existential =
          B.createInitExistentialRef(Loc, Dest->getType().getObjectType(),
                                     SourceType, Value, Conformances);
      B.emitStoreValueOperation(Loc, Existential, Dest,
                                StoreOwnershipQualifier::Init);
      break;
    }
    case ExistentialRepresentation::Boxed: {
      auto AllocBox = B.createAllocExistentialBox(Loc, Dest->getType(),
                                                  SourceType, Conformances);
      auto Projection =
          B.createProjectExistentialBox(Loc, Src->getType(), AllocBox);
      // This needs to be a copy_addr (for now) because we must handle
      // address-only types.
      B.createCopyAddr(Loc, Src, Projection, IsTake, IsInitialization);
      B.emitStoreValueOperation(Loc, AllocBox, Dest,
                                StoreOwnershipQualifier::Init);
      break;
    }
    };
    return true;
  }
  // Not a concrete -> existential cast.
  return false;
}

SILInstruction *CastOptimizer::optimizeUnconditionalCheckedCastAddrInst(
    UnconditionalCheckedCastAddrInst *Inst) {
  SILDynamicCastInst dynamicCast(Inst);
  auto Loc = dynamicCast.getLocation();

  // Check if we can statically predict the outcome of the cast.
  auto Feasibility =
      dynamicCast.classifyFeasibility(false /*allow whole module*/);

  if (Feasibility == DynamicCastFeasibility::MaySucceed) {
    // Forced bridged casts can be still simplified here.
    // If they fail, they fail inside the conversion function.
    if (!dynamicCast.isBridgingCast())
      return nullptr;
  }

  if (Feasibility == DynamicCastFeasibility::WillFail) {
    // Remove the cast and insert a trap, followed by an
    // unreachable instruction.
    SILBuilderWithScope Builder(Inst, builderContext);
    // mem2reg's invariants get unhappy if we don't try to
    // initialize a loadable result.
    if (!dynamicCast.getTargetLoweredType().isAddressOnly(
            Builder.getFunction())) {
      auto undef = SILValue(
          SILUndef::get(dynamicCast.getTargetLoweredType().getObjectType(),
                        Builder.getFunction()));
      Builder.emitStoreValueOperation(Loc, undef, dynamicCast.getDest(),
                                      StoreOwnershipQualifier::Init);
    }
    Builder.emitDestroyAddr(Loc, Inst->getSrc());
    auto *TrapI = Builder.createBuiltinTrap(Loc);
    eraseInstAction(Inst);
    Builder.setInsertionPoint(std::next(TrapI->getIterator()));
    auto *UnreachableInst =
        Builder.createUnreachable(ArtificialUnreachableLocation());

    // Delete everything after the unreachable except for dealloc_stack which we
    // move before the trap.
    deleteInstructionsAfterUnreachable(UnreachableInst, TrapI);

    willFailAction();
  }

  if (Feasibility == DynamicCastFeasibility::WillSucceed ||
      Feasibility == DynamicCastFeasibility::MaySucceed) {

    // Check if a result of a cast is unused. If this is the case, the cast can
    // be removed even if the cast may fail at runtime.
    // Swift optimizer does not claim to be crash-preserving.
    SILValue dest = dynamicCast.getDest();
    bool ResultNotUsed = isa<AllocStackInst>(dest);
    DestroyAddrInst *DestroyDestInst = nullptr;
    if (ResultNotUsed) {
      for (auto Use : dest->getUses()) {
        auto *User = Use->getUser();
        if (isa<DeallocStackInst>(User) || User == Inst)
          continue;
        if (isa<DestroyAddrInst>(User) && !DestroyDestInst) {
          DestroyDestInst = cast<DestroyAddrInst>(User);
          continue;
        }
        ResultNotUsed = false;
        DestroyDestInst = nullptr;
        break;
      }
    }

    if (ResultNotUsed) {
      SILBuilderWithScope B(Inst, builderContext);
      B.createDestroyAddr(Loc, dynamicCast.getSource());
      if (DestroyDestInst)
        eraseInstAction(DestroyDestInst);
      eraseInstAction(Inst);
      willSucceedAction();
      return nullptr;
    }

    // Try to apply the bridged casts optimizations.
    auto NewI = optimizeBridgedCasts(dynamicCast);
    if (NewI) {
      willSucceedAction();
      return nullptr;
    }

    if (Feasibility == DynamicCastFeasibility::MaySucceed)
      return nullptr;

    assert(Feasibility == DynamicCastFeasibility::WillSucceed);

    if (optimizeStaticallyKnownProtocolConformance(Inst)) {
      eraseInstAction(Inst);
      willSucceedAction();
      return nullptr;
    }

    if (dynamicCast.isBridgingCast())
      return nullptr;

    SILBuilderWithScope Builder(Inst, builderContext);
    if (!emitSuccessfulIndirectUnconditionalCast(Builder, Loc, dynamicCast)) {
      // No optimization was possible.
      return nullptr;
    }

    eraseInstAction(Inst);
    willSucceedAction();
  }

  return nullptr;
}

/// Simplify conversions between thick and objc metatypes.
SILValue CastOptimizer::optimizeMetatypeConversion(
    ConversionInst *mci, MetatypeRepresentation representation) {
  SILValue op = mci->getOperand(0);
  // Instruction has a proper target type already.
  SILType ty = mci->getType();
  auto metatypeTy = op->getType().getAs<AnyMetatypeType>();

  if (metatypeTy->getRepresentation() != representation)
    return SILValue();

  auto loc = mci->getLoc();

  // Rematerialize the incoming metatype instruction with the outgoing type.
  auto replaceCast = [&](SILValue newValue) -> SILValue {
    assert(ty.getAs<AnyMetatypeType>()->getRepresentation() ==
           newValue->getType().getAs<AnyMetatypeType>()->getRepresentation());
    replaceValueUsesAction(mci, newValue);
    eraseInstAction(mci);
    return newValue;
  };

  if (auto *mi = dyn_cast<MetatypeInst>(op)) {
    return replaceCast(
        SILBuilderWithScope(mci, builderContext).createMetatype(loc, ty));
  }

  // For metatype instructions that require an operand, generate the new
  // metatype at the same position as the original to avoid extending the
  // lifetime of `op` past its destroy.
  if (auto *vmi = dyn_cast<ValueMetatypeInst>(op)) {
    return replaceCast(SILBuilderWithScope(vmi, builderContext)
                           .createValueMetatype(loc, ty, vmi->getOperand()));
  }

  if (auto *emi = dyn_cast<ExistentialMetatypeInst>(op)) {
    return replaceCast(
        SILBuilderWithScope(emi, builderContext)
            .createExistentialMetatype(loc, ty, emi->getOperand()));
  }

  return SILValue();
}
