//===--- SILCloner.h - Defines the SILCloner class --------------*- C++ -*-===// // // 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 // //===----------------------------------------------------------------------===// // // This file defines the SILCloner class, used for cloning SIL instructions. // //===----------------------------------------------------------------------===// #ifndef SWIFT_SIL_SILCLONER_H #define SWIFT_SIL_SILCLONER_H #include "swift/AST/ProtocolConformance.h" #include "swift/SIL/SILOpenedArchetypesTracker.h" #include "swift/SIL/SILBuilder.h" #include "swift/SIL/SILDebugScope.h" #include "swift/SIL/SILVisitor.h" namespace swift { /// SILCloner - Abstract SIL visitor which knows how to clone instructions and /// whose behavior can be customized by subclasses via the CRTP. This is meant /// to be subclassed to implement inlining, function specialization, and other /// operations requiring cloning (while possibly modifying, at the same time) /// instruction sequences. /// /// By default, this visitor will not do anything useful when called on a /// basic block, or function; subclasses that want to handle those should /// implement the appropriate visit functions and/or provide other entry points. template class SILCloner : protected SILInstructionVisitor { friend class SILVisitorBase; friend class SILInstructionVisitor; public: using SILInstructionVisitor::asImpl; explicit SILCloner(SILFunction &F, SILOpenedArchetypesTracker &OpenedArchetypesTracker) : Builder(F), InsertBeforeBB(nullptr), OpenedArchetypesTracker(OpenedArchetypesTracker) { Builder.setOpenedArchetypesTracker(&OpenedArchetypesTracker); } explicit SILCloner(SILFunction &F) : Builder(F), InsertBeforeBB(nullptr), OpenedArchetypesTracker(&F) { Builder.setOpenedArchetypesTracker(&OpenedArchetypesTracker); } explicit SILCloner(SILGlobalVariable *GlobVar) : Builder(GlobVar), InsertBeforeBB(nullptr), OpenedArchetypesTracker(nullptr) { } /// Clients of SILCloner who want to know about any newly created /// instructions can install a SmallVector into the builder to collect them. void setTrackingList(SmallVectorImpl *II) { getBuilder().setTrackingList(II); } SmallVectorImpl *getTrackingList() { return getBuilder().getTrackingList(); } SILBuilder &getBuilder() { return Builder; } protected: void beforeVisit(SILInstruction *I) { // Update the set of available opened archetypes with the opened // archetypes used by the current instruction. doPreProcess(I); } #define INST(CLASS, PARENT) \ void visit##CLASS(CLASS *I); #include "swift/SIL/SILNodes.def" void visitSILBasicBlock(SILBasicBlock* BB); void visitSILFunction(SILFunction *F); // Derived classes of SILCloner using the CRTP can implement the following // functions to customize behavior; the remap functions are called before // cloning to modify constructor arguments and the post process function is // called afterwards on the result. SILLocation remapLocation(SILLocation Loc) { return Loc; } const SILDebugScope *remapScope(const SILDebugScope *DS) { return DS; } SILType remapType(SILType Ty) { return Ty; } CanType remapASTType(CanType Ty) { return Ty; } ProtocolConformanceRef remapConformance(Type Ty, ProtocolConformanceRef C){ return C; } SILValue remapValue(SILValue Value); SILFunction *remapFunction(SILFunction *Func) { return Func; } SILBasicBlock *remapBasicBlock(SILBasicBlock *BB); void postProcess(SILInstruction *Orig, SILInstruction *Cloned); SILLocation getOpLocation(SILLocation Loc) { return asImpl().remapLocation(Loc); } const SILDebugScope *getOpScope(const SILDebugScope *DS) { return asImpl().remapScope(DS); } SmallVector getOpSubstitutions(SubstitutionList Subs) { SmallVector NewSubs; for (auto Sub : Subs) { NewSubs.push_back(getOpSubstitution(Sub)); } return NewSubs; } SILType getTypeInClonedContext(SILType Ty) { auto objectTy = Ty.getSwiftRValueType(); // Do not substitute opened existential types, if we do not have any. if (!objectTy->hasOpenedExistential()) return Ty; // Do not substitute opened existential types, if it is not required. // This is often the case when cloning basic blocks inside the same // function. if (OpenedExistentialSubs.empty()) return Ty; // Substitute opened existential types, if we have any. return Ty.subst( Builder.getModule(), QueryTypeSubstitutionMapOrIdentity{OpenedExistentialSubs}, MakeAbstractConformanceForGenericType()); } SILType getOpType(SILType Ty) { Ty = getTypeInClonedContext(Ty); return asImpl().remapType(Ty); } CanType getASTTypeInClonedContext(Type ty) { // Do not substitute opened existential types, if we do not have any. if (!ty->hasOpenedExistential()) return ty->getCanonicalType(); // Do not substitute opened existential types, if it is not required. // This is often the case when cloning basic blocks inside the same // function. if (OpenedExistentialSubs.empty()) return ty->getCanonicalType(); return ty.subst( QueryTypeSubstitutionMapOrIdentity{OpenedExistentialSubs}, MakeAbstractConformanceForGenericType() )->getCanonicalType(); } CanType getOpASTType(CanType ty) { ty = getASTTypeInClonedContext(ty); return asImpl().remapASTType(ty); } ProtocolConformanceRef getOpConformance(Type ty, ProtocolConformanceRef conformance) { auto newConformance = conformance.subst(ty, [&](SubstitutableType *t) -> Type { if (t->isOpenedExistential()) { auto found = OpenedExistentialSubs.find( t->castTo()); if (found != OpenedExistentialSubs.end()) return found->second; return t; } return t; }, MakeAbstractConformanceForGenericType()); return asImpl().remapConformance(getASTTypeInClonedContext(ty), newConformance); } ArrayRef getOpConformances(Type ty, ArrayRef conformances) { SmallVector newConformances; for (auto conformance : conformances) newConformances.push_back(getOpConformance(ty, conformance)); return ty->getASTContext().AllocateCopy(newConformances); } Substitution getOpSubstitution(Substitution sub) { CanType newReplacement = getOpASTType(sub.getReplacement()->getCanonicalType()); auto conformances = getOpConformances(sub.getReplacement(), sub.getConformances()); return Substitution(newReplacement, conformances); } SILValue getOpValue(SILValue Value) { return asImpl().remapValue(Value); } template SmallVector getOpValueArray(ArrayRefType Values) { SmallVector Ret(Values.size()); for (unsigned i = 0, e = Values.size(); i != e; ++i) Ret[i] = asImpl().remapValue(Values[i]); return Ret; } SILFunction *getOpFunction(SILFunction *Func) { return asImpl().remapFunction(Func); } SILBasicBlock *getOpBasicBlock(SILBasicBlock *BB) { return asImpl().remapBasicBlock(BB); } void addBlockWithUnreachable(SILBasicBlock *BB) { BlocksWithUnreachables.insert(BB); } void cleanUp(SILFunction *F); public: void doPreProcess(SILInstruction *Orig) { // Extend the set of available opened archetypes by the opened archetypes // used by the instruction being cloned. auto TypeDependentOperands = Orig->getTypeDependentOperands(); Builder.getOpenedArchetypes().addOpenedArchetypeOperands( TypeDependentOperands); } void doPostProcess(SILInstruction *Orig, SILInstruction *Cloned) { asImpl().postProcess(Orig, Cloned); assert((Orig->getDebugScope() ? Cloned->getDebugScope()!=nullptr : true) && "cloned instruction dropped debug scope"); } // Register a re-mapping for opened existentials. void registerOpenedExistentialRemapping(ArchetypeType *From, ArchetypeType *To) { auto result = OpenedExistentialSubs.insert(std::make_pair(CanArchetypeType(From), CanType(To))); assert(result.second); (void) result; } protected: SILBuilder Builder; SILBasicBlock *InsertBeforeBB; llvm::DenseMap ValueMap; // Use MapVector to ensure that the order of block predecessors is // deterministic. llvm::MapVector BBMap; TypeSubstitutionMap OpenedExistentialSubs; SILOpenedArchetypesTracker OpenedArchetypesTracker; /// Set of basic blocks where unreachable was inserted. SmallPtrSet BlocksWithUnreachables; }; /// \brief A SILBuilder that automatically invokes postprocess on each /// inserted instruction. template class SILBuilderWithPostProcess : public SILBuilder { SomeSILCloner &SC; SILInstruction *Orig; SmallVector InsertedInstrs; public: SILBuilderWithPostProcess(SomeSILCloner *sc, SILInstruction *Orig) : SILBuilder(sc->getBuilder().getInsertionBB(), &InsertedInstrs), SC(*sc), Orig(Orig) { setInsertionPoint(SC.getBuilder().getInsertionBB(), SC.getBuilder().getInsertionPoint()); setOpenedArchetypesTracker(SC.getBuilder().getOpenedArchetypesTracker()); } ~SILBuilderWithPostProcess() { for (auto *I : InsertedInstrs) { SC.doPostProcess(Orig, I); } } }; /// SILClonerWithScopes - a SILCloner that automatically clones /// SILDebugScopes. In contrast to inline scopes, this generates a /// deep copy of the scope tree. template class SILClonerWithScopes : public SILCloner { friend class SILCloner; public: SILClonerWithScopes(SILFunction &To, SILOpenedArchetypesTracker &OpenedArchetypesTracker, bool Disable = false) : SILCloner(To, OpenedArchetypesTracker) { // We only want to do this when we generate cloned functions, not // when we inline. // FIXME: This is due to having TypeSubstCloner inherit from // SILClonerWithScopes, and having TypeSubstCloner be used // both by passes that clone whole functions and ones that // inline functions. if (Disable) return; scopeCloner.reset(new ScopeCloner(To)); } SILClonerWithScopes(SILFunction &To, bool Disable = false) : SILCloner(To) { // We only want to do this when we generate cloned functions, not // when we inline. // FIXME: This is due to having TypeSubstCloner inherit from // SILClonerWithScopes, and having TypeSubstCloner be used // both by passes that clone whole functions and ones that // inline functions. if (Disable) return; scopeCloner.reset(new ScopeCloner(To)); } private: std::unique_ptr scopeCloner; protected: /// Clone the SILDebugScope for the cloned function. void postProcess(SILInstruction *Orig, SILInstruction *Cloned) { SILCloner::postProcess(Orig, Cloned); } const SILDebugScope *remapScope(const SILDebugScope *DS) { return scopeCloner ? scopeCloner->getOrCreateClonedScope(DS) : DS; } }; template SILValue SILCloner::remapValue(SILValue Value) { auto VI = ValueMap.find(Value); if (VI != ValueMap.end()) return VI->second; // If we have undef, just remap the type. if (auto *U = dyn_cast(Value)) { auto type = getOpType(U->getType()); ValueBase *undef = (type == U->getType() ? U : SILUndef::get(type, Builder.getModule())); return SILValue(undef); } llvm_unreachable("Unmapped value while cloning?"); } template SILBasicBlock* SILCloner::remapBasicBlock(SILBasicBlock *BB) { SILBasicBlock *MappedBB = BBMap[BB]; assert(MappedBB && "Unmapped basic block while cloning?"); return MappedBB; } template void SILCloner::postProcess(SILInstruction *orig, SILInstruction *cloned) { assert((orig->getDebugScope() ? cloned->getDebugScope()!=nullptr : true) && "cloned function dropped debug scope"); // It sometimes happens that an instruction with no results gets mapped // to an instruction with results, e.g. when specializing a cast. // Just ignore this. auto origResults = orig->getResults(); if (origResults.empty()) return; // Otherwise, map the results over one-by-one. auto clonedResults = cloned->getResults(); assert(origResults.size() == clonedResults.size()); for (auto i : indices(origResults)) { SILValue origResult = origResults[i], clonedResult = clonedResults[i]; auto insertion = ValueMap.insert(std::make_pair(origResult, clonedResult)); if (!insertion.second) insertion.first->second = clonedResult; } } /// \brief Recursively visit a callee's BBs in depth-first preorder (only /// processing blocks on the first visit), mapping newly visited BBs to new BBs /// in the caller and cloning all instructions into the caller other than /// terminators which should be handled separately later by subclasses template void SILCloner::visitSILBasicBlock(SILBasicBlock* BB) { SILFunction &F = getBuilder().getFunction(); // Iterate over and visit all instructions other than the terminator to clone. for (auto I = BB->begin(), E = --BB->end(); I != E; ++I) { asImpl().visit(&*I); } // Iterate over successors to do the depth-first search. for (auto &Succ : BB->getSuccessors()) { auto BBI = BBMap.find(Succ); // Only visit a successor that has not already been visited. if (BBI == BBMap.end()) { // Map the successor to a new BB. auto *MappedBB = F.createBasicBlock(); BBMap.insert(std::make_pair(Succ.getBB(), MappedBB)); // Create new arguments for each of the original block's arguments. for (auto *Arg : Succ.getBB()->getPHIArguments()) { SILValue MappedArg = MappedBB->createPHIArgument( getOpType(Arg->getType()), Arg->getOwnershipKind()); ValueMap.insert(std::make_pair(Arg, MappedArg)); } // Also, move the new mapped BB to the right position in the caller if (InsertBeforeBB) F.getBlocks().splice(SILFunction::iterator(InsertBeforeBB), F.getBlocks(), SILFunction::iterator(MappedBB)); // Set the insertion point to the new mapped BB getBuilder().setInsertionPoint(MappedBB); // Recurse into the successor visitSILBasicBlock(Succ.getBB()); } } } /// \brief Clean-up after cloning. template void SILCloner::cleanUp(SILFunction *F) { // Remove any code after unreachable instructions. // NOTE: It is unfortunate that it essentially duplicates // the code from sil-combine, but doing so allows for // avoiding any cross-layer invocations between SIL and // SILOptimizer layers. for (auto *BB : BlocksWithUnreachables) { for (auto &I : *BB) { if (!isa(&I)) continue; // Collect together all the instructions after this point llvm::SmallVector ToRemove; for (auto Inst = BB->rbegin(); &*Inst != &I; ++Inst) ToRemove.push_back(&*Inst); for (auto *Inst : ToRemove) { // Replace any non-dead results with SILUndef values Inst->replaceAllUsesOfAllResultsWithUndef(); Inst->eraseFromParent(); } } } BlocksWithUnreachables.clear(); } template void SILCloner::visitSILFunction(SILFunction *F) { for (auto &BB : *F) asImpl().visitSILBasicBlock(&BB); cleanUp(F); } template void SILCloner::visitAllocStackInst(AllocStackInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createAllocStack(getOpLocation(Inst->getLoc()), getOpType(Inst->getElementType()))); } template void SILCloner::visitAllocRefInst(AllocRefInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); auto CountArgs = getOpValueArray<8>(OperandValueArrayRef(Inst-> getTailAllocatedCounts())); SmallVector ElemTypes; for (SILType OrigElemType : Inst->getTailAllocatedTypes()) { ElemTypes.push_back(getOpType(OrigElemType)); } auto *NewInst = getBuilder().createAllocRef(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Inst->isObjC(), Inst->canAllocOnStack(), ElemTypes, CountArgs); doPostProcess(Inst, NewInst); } template void SILCloner::visitAllocRefDynamicInst(AllocRefDynamicInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); auto CountArgs = getOpValueArray<8>(OperandValueArrayRef(Inst-> getTailAllocatedCounts())); SmallVector ElemTypes; for (SILType OrigElemType : Inst->getTailAllocatedTypes()) { ElemTypes.push_back(getOpType(OrigElemType)); } auto *NewInst = getBuilder().createAllocRefDynamic( getOpLocation(Inst->getLoc()), getOpValue(Inst->getMetatypeOperand()), getOpType(Inst->getType()), Inst->isObjC(), ElemTypes, CountArgs); doPostProcess(Inst, NewInst); } template void SILCloner::visitAllocBoxInst(AllocBoxInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createAllocBox(getOpLocation(Inst->getLoc()), this->getOpType(Inst->getType()).template castTo())); } template void SILCloner::visitAllocExistentialBoxInst( AllocExistentialBoxInst *Inst) { auto origExistentialType = Inst->getExistentialType(); auto origFormalType = Inst->getFormalConcreteType(); auto conformances = getOpConformances(origFormalType, Inst->getConformances()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createAllocExistentialBox(getOpLocation(Inst->getLoc()), getOpType(origExistentialType), getOpASTType(origFormalType), conformances)); } template void SILCloner::visitAllocValueBufferInst(AllocValueBufferInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createAllocValueBuffer(getOpLocation(Inst->getLoc()), getOpType(Inst->getValueType()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitBuiltinInst(BuiltinInst *Inst) { auto Args = getOpValueArray<8>(Inst->getArguments()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createBuiltin(getOpLocation(Inst->getLoc()), Inst->getName(), getOpType(Inst->getType()), getOpSubstitutions(Inst->getSubstitutions()), Args)); } template void SILCloner::visitApplyInst(ApplyInst *Inst) { auto Args = getOpValueArray<8>(Inst->getArguments()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createApply(getOpLocation(Inst->getLoc()), getOpValue(Inst->getCallee()), getOpSubstitutions(Inst->getSubstitutions()), Args, Inst->isNonThrowing(), GenericSpecializationInformation::create( Inst, getBuilder()))); } template void SILCloner::visitTryApplyInst(TryApplyInst *Inst) { auto Args = getOpValueArray<8>(Inst->getArguments()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createTryApply(getOpLocation(Inst->getLoc()), getOpValue(Inst->getCallee()), getOpSubstitutions(Inst->getSubstitutions()), Args, getOpBasicBlock(Inst->getNormalBB()), getOpBasicBlock(Inst->getErrorBB()), GenericSpecializationInformation::create( Inst, getBuilder()))); } template void SILCloner::visitPartialApplyInst(PartialApplyInst *Inst) { auto Args = getOpValueArray<8>(Inst->getArguments()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createPartialApply( getOpLocation(Inst->getLoc()), getOpValue(Inst->getCallee()), getOpSubstitutions(Inst->getSubstitutions()), Args, Inst->getType() .getSwiftRValueType() ->getAs() ->getCalleeConvention(), GenericSpecializationInformation::create(Inst, getBuilder()))); } template void SILCloner::visitBeginApplyInst(BeginApplyInst *Inst) { auto Args = getOpValueArray<8>(Inst->getArguments()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createBeginApply(getOpLocation(Inst->getLoc()), getOpValue(Inst->getCallee()), getOpSubstitutions(Inst->getSubstitutions()), Args, Inst->isNonThrowing(), GenericSpecializationInformation::create( Inst, getBuilder()))); } template void SILCloner::visitAbortApplyInst(AbortApplyInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createAbortApply(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitEndApplyInst(EndApplyInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createEndApply(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitFunctionRefInst(FunctionRefInst *Inst) { SILFunction *OpFunction = getOpFunction(Inst->getReferencedFunction()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createFunctionRef(getOpLocation(Inst->getLoc()), OpFunction)); } template void SILCloner::visitAllocGlobalInst(AllocGlobalInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createAllocGlobal(getOpLocation(Inst->getLoc()), Inst->getReferencedGlobal())); } template void SILCloner::visitGlobalAddrInst(GlobalAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createGlobalAddr(getOpLocation(Inst->getLoc()), Inst->getReferencedGlobal())); } template void SILCloner::visitGlobalValueInst(GlobalValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createGlobalValue(getOpLocation(Inst->getLoc()), Inst->getReferencedGlobal())); } template void SILCloner::visitIntegerLiteralInst(IntegerLiteralInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createIntegerLiteral(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Inst->getValue())); } template void SILCloner::visitFloatLiteralInst(FloatLiteralInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createFloatLiteral(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Inst->getValue())); } template void SILCloner::visitStringLiteralInst(StringLiteralInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStringLiteral(getOpLocation(Inst->getLoc()), Inst->getValue(), Inst->getEncoding())); } template void SILCloner::visitConstStringLiteralInst( ConstStringLiteralInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createConstStringLiteral( getOpLocation(Inst->getLoc()), Inst->getValue(), Inst->getEncoding())); } template void SILCloner::visitLoadInst(LoadInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createLoad(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getOwnershipQualifier())); } template void SILCloner::visitLoadBorrowInst(LoadBorrowInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createLoadBorrow(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitBeginBorrowInst(BeginBorrowInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createBeginBorrow(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitStoreInst(StoreInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStore(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()), Inst->getOwnershipQualifier())); } template void SILCloner::visitStoreBorrowInst(StoreBorrowInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStoreBorrow(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()))); } template void SILCloner::visitEndBorrowInst(EndBorrowInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createEndBorrow(getOpLocation(Inst->getLoc()), getOpValue(Inst->getBorrowedValue()), getOpValue(Inst->getOriginalValue()))); } template void SILCloner::visitEndBorrowArgumentInst( EndBorrowArgumentInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createEndBorrowArgument( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitBeginAccessInst(BeginAccessInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createBeginAccess(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAccessKind(), Inst->getEnforcement())); } template void SILCloner::visitEndAccessInst(EndAccessInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createEndAccess(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->isAborting())); } template void SILCloner::visitBeginUnpairedAccessInst( BeginUnpairedAccessInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createBeginUnpairedAccess(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSource()), getOpValue(Inst->getBuffer()), Inst->getAccessKind(), Inst->getEnforcement())); } template void SILCloner::visitEndUnpairedAccessInst( EndUnpairedAccessInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createEndUnpairedAccess(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getEnforcement(), Inst->isAborting())); } template void SILCloner::visitAssignInst(AssignInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createAssign(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()))); } template void SILCloner::visitMarkUninitializedInst(MarkUninitializedInst *Inst) { SILValue OpValue = getOpValue(Inst->getOperand()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createMarkUninitialized(getOpLocation(Inst->getLoc()), OpValue, Inst->getKind())); } template void SILCloner::visitMarkUninitializedBehaviorInst( MarkUninitializedBehaviorInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createMarkUninitializedBehavior( getOpLocation(Inst->getLoc()), getOpValue(Inst->getInitStorageFunc()), getOpSubstitutions(Inst->getInitStorageSubstitutions()), getOpValue(Inst->getStorage()), getOpValue(Inst->getSetterFunc()), getOpSubstitutions(Inst->getSetterSubstitutions()), getOpValue(Inst->getSelf()), getOpType(Inst->getType()))); } template void SILCloner::visitMarkFunctionEscapeInst(MarkFunctionEscapeInst *Inst){ auto OpElements = getOpValueArray<8>(Inst->getElements()); auto OpLoc = getOpLocation(Inst->getLoc()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createMarkFunctionEscape(OpLoc, OpElements)); } template void SILCloner::visitDebugValueInst(DebugValueInst *Inst) { // We cannot inline/clone debug intrinsics without a scope. If they // describe function arguments there is no way to determine which // function they belong to. if (!Inst->getDebugScope()) return; // Since we want the debug info to survive, we do not remap the location here. getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDebugValue( Inst->getLoc(), getOpValue(Inst->getOperand()), Inst->getVarInfo())); } template void SILCloner::visitDebugValueAddrInst(DebugValueAddrInst *Inst) { // We cannot inline/clone debug intrinsics without a scope. If they // describe function arguments there is no way to determine which // function they belong to. if (!Inst->getDebugScope()) return; // Do not remap the location for a debug Instruction. SILValue OpValue = getOpValue(Inst->getOperand()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDebugValueAddr( Inst->getLoc(), OpValue, Inst->getVarInfo())); } template void SILCloner::visitLoadUnownedInst(LoadUnownedInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createLoadUnowned(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->isTake())); } template void SILCloner::visitStoreUnownedInst(StoreUnownedInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStoreUnowned(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()), Inst->isInitializationOfDest())); } template void SILCloner::visitLoadWeakInst(LoadWeakInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createLoadWeak(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->isTake())); } template void SILCloner::visitStoreWeakInst(StoreWeakInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStoreWeak(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()), Inst->isInitializationOfDest())); } template void SILCloner::visitCopyAddrInst(CopyAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createCopyAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()), Inst->isTakeOfSrc(), Inst->isInitializationOfDest())); } template void SILCloner::visitBindMemoryInst(BindMemoryInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createBindMemory(getOpLocation(Inst->getLoc()), getOpValue(Inst->getBase()), getOpValue(Inst->getIndex()), getOpType(Inst->getBoundType()))); } template void SILCloner::visitConvertFunctionInst(ConvertFunctionInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createConvertFunction(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitThinFunctionToPointerInst( ThinFunctionToPointerInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createThinFunctionToPointer(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitPointerToThinFunctionInst( PointerToThinFunctionInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createPointerToThinFunction(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitUpcastInst(UpcastInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUpcast(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitAddressToPointerInst(AddressToPointerInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createAddressToPointer(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitPointerToAddressInst(PointerToAddressInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createPointerToAddress(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()), Inst->isStrict(), Inst->isInvariant())); } template void SILCloner:: visitUncheckedRefCastInst(UncheckedRefCastInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUncheckedRefCast(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner:: visitUncheckedRefCastAddrInst(UncheckedRefCastAddrInst *Inst) { SILLocation OpLoc = getOpLocation(Inst->getLoc()); SILValue SrcValue = getOpValue(Inst->getSrc()); SILValue DestValue = getOpValue(Inst->getDest()); CanType SrcType = getOpASTType(Inst->getSourceType()); CanType TargetType = getOpASTType(Inst->getTargetType()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder(). createUncheckedRefCastAddr(OpLoc, SrcValue, SrcType, DestValue, TargetType)); } template void SILCloner:: visitUncheckedAddrCastInst(UncheckedAddrCastInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUncheckedAddrCast(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner:: visitUncheckedTrivialBitCastInst(UncheckedTrivialBitCastInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUncheckedTrivialBitCast(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner:: visitUncheckedBitwiseCastInst(UncheckedBitwiseCastInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUncheckedBitwiseCast(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner:: visitRefToBridgeObjectInst(RefToBridgeObjectInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createRefToBridgeObject(getOpLocation(Inst->getLoc()), getOpValue(Inst->getConverted()), getOpValue(Inst->getBitsOperand()))); } template void SILCloner:: visitBridgeObjectToRefInst(BridgeObjectToRefInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createBridgeObjectToRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getConverted()), getOpType(Inst->getType()))); } template void SILCloner:: visitBridgeObjectToWordInst(BridgeObjectToWordInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createBridgeObjectToWord(getOpLocation(Inst->getLoc()), getOpValue(Inst->getConverted()), getOpType(Inst->getType()))); } template void SILCloner::visitRefToRawPointerInst(RefToRawPointerInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createRefToRawPointer(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitRawPointerToRefInst(RawPointerToRefInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createRawPointerToRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitRefToUnownedInst(RefToUnownedInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createRefToUnowned(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitUnownedToRefInst(UnownedToRefInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUnownedToRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitRefToUnmanagedInst(RefToUnmanagedInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createRefToUnmanaged(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitUnmanagedToRefInst(UnmanagedToRefInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUnmanagedToRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner:: visitThinToThickFunctionInst(ThinToThickFunctionInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createThinToThickFunction(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner:: visitThickToObjCMetatypeInst(ThickToObjCMetatypeInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createThickToObjCMetatype(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner:: visitObjCToThickMetatypeInst(ObjCToThickMetatypeInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createObjCToThickMetatype(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitUnconditionalCheckedCastInst( UnconditionalCheckedCastInst *Inst) { SILLocation OpLoc = getOpLocation(Inst->getLoc()); SILValue OpValue = getOpValue(Inst->getOperand()); SILType OpType = getOpType(Inst->getType()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUnconditionalCheckedCast(OpLoc, OpValue, OpType)); } template void SILCloner::visitUnconditionalCheckedCastAddrInst( UnconditionalCheckedCastAddrInst *Inst) { SILLocation OpLoc = getOpLocation(Inst->getLoc()); SILValue SrcValue = getOpValue(Inst->getSrc()); SILValue DestValue = getOpValue(Inst->getDest()); CanType SrcType = getOpASTType(Inst->getSourceType()); CanType TargetType = getOpASTType(Inst->getTargetType()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUnconditionalCheckedCastAddr(OpLoc, SrcValue, SrcType, DestValue, TargetType)); } template void SILCloner::visitUnconditionalCheckedCastValueInst( UnconditionalCheckedCastValueInst *Inst) { SILLocation OpLoc = getOpLocation(Inst->getLoc()); SILValue OpValue = getOpValue(Inst->getOperand()); SILType OpType = getOpType(Inst->getType()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createUnconditionalCheckedCastValue(OpLoc, OpValue, OpType)); } template void SILCloner::visitRetainValueInst(RetainValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createRetainValue(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitRetainValueAddrInst(RetainValueAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createRetainValueAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitUnmanagedRetainValueInst( UnmanagedRetainValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createUnmanagedRetainValue( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitCopyValueInst(CopyValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createCopyValue(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitCopyUnownedValueInst( CopyUnownedValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createCopyUnownedValue( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitReleaseValueInst(ReleaseValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createReleaseValue(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitReleaseValueAddrInst( ReleaseValueAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createReleaseValueAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitUnmanagedReleaseValueInst( UnmanagedReleaseValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createUnmanagedReleaseValue( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitDestroyValueInst(DestroyValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createDestroyValue(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitAutoreleaseValueInst( AutoreleaseValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createAutoreleaseValue(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitUnmanagedAutoreleaseValueInst( UnmanagedAutoreleaseValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createUnmanagedAutoreleaseValue( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitSetDeallocatingInst(SetDeallocatingInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createSetDeallocating(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitObjectInst(ObjectInst *Inst) { auto Elements = getOpValueArray<8>(Inst->getAllElements()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createObject(getOpLocation(Inst->getLoc()), Inst->getType(), Elements, Inst->getBaseElements().size())); } template void SILCloner::visitStructInst(StructInst *Inst) { auto Elements = getOpValueArray<8>(Inst->getElements()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStruct(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Elements)); } template void SILCloner::visitTupleInst(TupleInst *Inst) { auto Elements = getOpValueArray<8>(Inst->getElements()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createTuple(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Elements)); } template void SILCloner::visitEnumInst(EnumInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createEnum(getOpLocation(Inst->getLoc()), Inst->hasOperand() ? getOpValue(Inst->getOperand()) : SILValue(), Inst->getElement(), getOpType(Inst->getType()))); } template void SILCloner::visitInitEnumDataAddrInst(InitEnumDataAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createInitEnumDataAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getElement(), getOpType(Inst->getType()))); } template void SILCloner::visitUncheckedEnumDataInst(UncheckedEnumDataInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUncheckedEnumData(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getElement(), getOpType(Inst->getType()))); } template void SILCloner::visitUncheckedTakeEnumDataAddrInst(UncheckedTakeEnumDataAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUncheckedTakeEnumDataAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getElement(), getOpType(Inst->getType()))); } template void SILCloner::visitInjectEnumAddrInst(InjectEnumAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createInjectEnumAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getElement())); } template void SILCloner::visitMetatypeInst(MetatypeInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createMetatype(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()))); } template void SILCloner::visitValueMetatypeInst(ValueMetatypeInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createValueMetatype(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), getOpValue(Inst->getOperand()))); } template void SILCloner:: visitExistentialMetatypeInst(ExistentialMetatypeInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createExistentialMetatype(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitTupleExtractInst(TupleExtractInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createTupleExtract(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getFieldNo(), getOpType(Inst->getType()))); } template void SILCloner::visitTupleElementAddrInst(TupleElementAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createTupleElementAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getFieldNo(), getOpType(Inst->getType()))); } template void SILCloner::visitStructExtractInst(StructExtractInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStructExtract(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getField(), getOpType(Inst->getType()))); } template void SILCloner::visitStructElementAddrInst(StructElementAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStructElementAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getField(), getOpType(Inst->getType()))); } template void SILCloner::visitRefElementAddrInst(RefElementAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createRefElementAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getField(), getOpType(Inst->getType()))); } template void SILCloner::visitRefTailAddrInst(RefTailAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createRefTailAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitDestructureStructInst( DestructureStructInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createDestructureStruct(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitDestructureTupleInst( DestructureTupleInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createDestructureTuple(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitClassMethodInst(ClassMethodInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createClassMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), Inst->getType())); } template void SILCloner::visitSuperMethodInst(SuperMethodInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createSuperMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), Inst->getType())); } template void SILCloner::visitObjCMethodInst(ObjCMethodInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createObjCMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpType(Inst->getType()))); } template void SILCloner::visitObjCSuperMethodInst(ObjCSuperMethodInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createObjCSuperMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), Inst->getType())); } template void SILCloner::visitWitnessMethodInst(WitnessMethodInst *Inst) { auto lookupType = Inst->getLookupType(); auto conformance = getOpConformance(lookupType, Inst->getConformance()); auto newLookupType = getOpASTType(lookupType); if (conformance.isConcrete()) { CanType Ty = conformance.getConcrete()->getType()->getCanonicalType(); if (Ty != newLookupType) { assert(Ty->isExactSuperclassOf(newLookupType) && "Should only create upcasts for sub class."); // We use the super class as the new look up type. newLookupType = Ty; } } getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder() .createWitnessMethod( getOpLocation(Inst->getLoc()), newLookupType, conformance, Inst->getMember(), Inst->getType())); } template void SILCloner::visitOpenExistentialAddrInst(OpenExistentialAddrInst *Inst) { // Create a new archetype for this opened existential type. auto archetypeTy = Inst->getType().getSwiftRValueType()->castTo(); registerOpenedExistentialRemapping( archetypeTy, ArchetypeType::getOpened(archetypeTy->getOpenedExistentialType())); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createOpenExistentialAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()), Inst->getAccessKind())); } template void SILCloner::visitOpenExistentialValueInst( OpenExistentialValueInst *Inst) { // Create a new archetype for this opened existential type. auto archetypeTy = Inst->getType().getSwiftRValueType()->castTo(); registerOpenedExistentialRemapping( archetypeTy, ArchetypeType::getOpened(archetypeTy->getOpenedExistentialType())); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createOpenExistentialValue( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner:: visitOpenExistentialMetatypeInst(OpenExistentialMetatypeInst *Inst) { // Create a new archetype for this opened existential type. CanType openedType = Inst->getType().getSwiftRValueType(); CanType exType = Inst->getOperand()->getType().getSwiftRValueType(); while (auto exMetatype = dyn_cast(exType)) { exType = exMetatype.getInstanceType(); openedType = cast(openedType).getInstanceType(); } auto archetypeTy = cast(openedType); registerOpenedExistentialRemapping( archetypeTy, ArchetypeType::getOpened(archetypeTy->getOpenedExistentialType())); if (!Inst->getOperand()->getType().canUseExistentialRepresentation( Inst->getModule(), ExistentialRepresentation::Class)) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createOpenExistentialMetatype( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); return; } getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createOpenExistentialMetatype(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner:: visitOpenExistentialRefInst(OpenExistentialRefInst *Inst) { // Create a new archetype for this opened existential type. auto archetypeTy = Inst->getType().getSwiftRValueType()->castTo(); registerOpenedExistentialRemapping( archetypeTy, ArchetypeType::getOpened(archetypeTy->getOpenedExistentialType())); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createOpenExistentialRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner:: visitOpenExistentialBoxInst(OpenExistentialBoxInst *Inst) { // Create a new archetype for this opened existential type. auto archetypeTy = Inst->getType().getSwiftRValueType()->castTo(); registerOpenedExistentialRemapping( archetypeTy, ArchetypeType::getOpened(archetypeTy->getOpenedExistentialType())); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createOpenExistentialBox(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner:: visitOpenExistentialBoxValueInst(OpenExistentialBoxValueInst *Inst) { // Create a new archetype for this opened existential type. auto archetypeTy = Inst->getType().getSwiftRValueType()->castTo(); registerOpenedExistentialRemapping( archetypeTy, ArchetypeType::getOpened(archetypeTy->getOpenedExistentialType())); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createOpenExistentialBoxValue(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitInitExistentialAddrInst(InitExistentialAddrInst *Inst) { CanType origFormalType = Inst->getFormalConcreteType(); auto conformances = getOpConformances(origFormalType, Inst->getConformances()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createInitExistentialAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpASTType(origFormalType), getOpType(Inst->getLoweredConcreteType()), conformances)); } template void SILCloner::visitInitExistentialValueInst( InitExistentialValueInst *Inst) { CanType origFormalType = Inst->getFormalConcreteType(); auto conformances = getOpConformances(origFormalType, Inst->getConformances()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createInitExistentialValue( getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), getOpASTType(origFormalType), getOpValue(Inst->getOperand()), conformances)); } template void SILCloner:: visitInitExistentialMetatypeInst(InitExistentialMetatypeInst *Inst) { auto origFormalType = Inst->getFormalErasedObjectType(); auto conformances = getOpConformances(origFormalType, Inst->getConformances()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createInitExistentialMetatype(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()), conformances)); } template void SILCloner:: visitInitExistentialRefInst(InitExistentialRefInst *Inst) { CanType origFormalType = Inst->getFormalConcreteType(); auto conformances = getOpConformances(origFormalType, Inst->getConformances()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createInitExistentialRef(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), getOpASTType(origFormalType), getOpValue(Inst->getOperand()), conformances)); } template void SILCloner::visitDeinitExistentialAddrInst(DeinitExistentialAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDeinitExistentialAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitDeinitExistentialValueInst( DeinitExistentialValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder().createDeinitExistentialValue( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitCopyBlockInst(CopyBlockInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, Builder.createCopyBlock(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitStrongRetainInst(StrongRetainInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStrongRetain(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitFixLifetimeInst(FixLifetimeInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createFixLifetime(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitEndLifetimeInst(EndLifetimeInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createEndLifetime(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitUncheckedOwnershipConversionInst( UncheckedOwnershipConversionInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); ValueOwnershipKind Kind = SILValue(Inst).getOwnershipKind(); if (getOpValue(Inst->getOperand()).getOwnershipKind() == ValueOwnershipKind::Trivial) { Kind = ValueOwnershipKind::Trivial; } doPostProcess(Inst, getBuilder().createUncheckedOwnershipConversion( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Kind)); } template void SILCloner::visitMarkDependenceInst(MarkDependenceInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createMarkDependence(getOpLocation(Inst->getLoc()), getOpValue(Inst->getValue()), getOpValue(Inst->getBase()))); } template void SILCloner::visitStrongPinInst(StrongPinInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStrongPin(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitStrongUnpinInst(StrongUnpinInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStrongUnpin(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitStrongReleaseInst(StrongReleaseInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStrongRelease(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner:: visitStrongRetainUnownedInst(StrongRetainUnownedInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createStrongRetainUnowned(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitUnownedRetainInst(UnownedRetainInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUnownedRetain(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitUnownedReleaseInst(UnownedReleaseInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUnownedRelease(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } template void SILCloner::visitIsUniqueInst(IsUniqueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createIsUnique(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner:: visitIsUniqueOrPinnedInst(IsUniqueOrPinnedInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createIsUniqueOrPinned(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitDeallocStackInst(DeallocStackInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDeallocStack(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitDeallocRefInst(DeallocRefInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDeallocRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->canAllocOnStack())); } template void SILCloner::visitDeallocPartialRefInst(DeallocPartialRefInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDeallocPartialRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getInstance()), getOpValue(Inst->getMetatype()))); } template void SILCloner::visitDeallocValueBufferInst( DeallocValueBufferInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDeallocValueBuffer(getOpLocation(Inst->getLoc()), getOpType(Inst->getValueType()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitDeallocBoxInst(DeallocBoxInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDeallocBox(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitDeallocExistentialBoxInst( DeallocExistentialBoxInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDeallocExistentialBox(getOpLocation(Inst->getLoc()), getOpASTType(Inst->getConcreteType()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitDestroyAddrInst(DestroyAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDestroyAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitProjectValueBufferInst( ProjectValueBufferInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createProjectValueBuffer(getOpLocation(Inst->getLoc()), getOpType(Inst->getValueType()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitProjectBoxInst(ProjectBoxInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createProjectBox(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getFieldIndex())); } template void SILCloner::visitProjectExistentialBoxInst( ProjectExistentialBoxInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createProjectExistentialBox(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitCondFailInst(CondFailInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createCondFail(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitIndexAddrInst(IndexAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createIndexAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getBase()), getOpValue(Inst->getIndex()))); } template void SILCloner::visitTailAddrInst(TailAddrInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createTailAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getBase()), getOpValue(Inst->getIndex()), getOpType(Inst->getType()))); } template void SILCloner::visitIndexRawPointerInst(IndexRawPointerInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createIndexRawPointer(getOpLocation(Inst->getLoc()), getOpValue(Inst->getBase()), getOpValue(Inst->getIndex()))); } template void SILCloner::visitUnreachableInst(UnreachableInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUnreachable(getOpLocation(Inst->getLoc()))); } template void SILCloner::visitReturnInst(ReturnInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createReturn(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitThrowInst(ThrowInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createThrow(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitUnwindInst(UnwindInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createUnwind(getOpLocation(Inst->getLoc()))); } template void SILCloner::visitYieldInst(YieldInst *Inst) { auto Values = getOpValueArray<8>(Inst->getYieldedValues()); auto ResumeBB = getOpBasicBlock(Inst->getResumeBB()); auto UnwindBB = getOpBasicBlock(Inst->getUnwindBB()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createYield(getOpLocation(Inst->getLoc()), Values, ResumeBB, UnwindBB)); } template void SILCloner::visitBranchInst(BranchInst *Inst) { auto Args = getOpValueArray<8>(Inst->getArgs()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createBranch(getOpLocation(Inst->getLoc()), getOpBasicBlock(Inst->getDestBB()), Args)); } template void SILCloner::visitCondBranchInst(CondBranchInst *Inst) { auto TrueArgs = getOpValueArray<8>(Inst->getTrueArgs()); auto FalseArgs = getOpValueArray<8>(Inst->getFalseArgs()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createCondBranch(getOpLocation(Inst->getLoc()), getOpValue(Inst->getCondition()), getOpBasicBlock(Inst->getTrueBB()), TrueArgs, getOpBasicBlock(Inst->getFalseBB()), FalseArgs, Inst->getTrueBBCount(), Inst->getFalseBBCount())); } template void SILCloner::visitCheckedCastBranchInst(CheckedCastBranchInst *Inst) { SILBasicBlock *OpSuccBB = getOpBasicBlock(Inst->getSuccessBB()); SILBasicBlock *OpFailBB = getOpBasicBlock(Inst->getFailureBB()); auto TrueCount = Inst->getTrueBBCount(); auto FalseCount = Inst->getFalseBBCount(); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createCheckedCastBranch( getOpLocation(Inst->getLoc()), Inst->isExact(), getOpValue(Inst->getOperand()), getOpType(Inst->getCastType()), OpSuccBB, OpFailBB, TrueCount, FalseCount)); } template void SILCloner::visitCheckedCastValueBranchInst( CheckedCastValueBranchInst *Inst) { SILBasicBlock *OpSuccBB = getOpBasicBlock(Inst->getSuccessBB()); SILBasicBlock *OpFailBB = getOpBasicBlock(Inst->getFailureBB()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createCheckedCastValueBranch( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getCastType()), OpSuccBB, OpFailBB)); } template void SILCloner::visitCheckedCastAddrBranchInst( CheckedCastAddrBranchInst *Inst) { SILBasicBlock *OpSuccBB = getOpBasicBlock(Inst->getSuccessBB()); SILBasicBlock *OpFailBB = getOpBasicBlock(Inst->getFailureBB()); SILValue SrcValue = getOpValue(Inst->getSrc()); SILValue DestValue = getOpValue(Inst->getDest()); CanType SrcType = getOpASTType(Inst->getSourceType()); CanType TargetType = getOpASTType(Inst->getTargetType()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); auto TrueCount = Inst->getTrueBBCount(); auto FalseCount = Inst->getFalseBBCount(); doPostProcess(Inst, getBuilder().createCheckedCastAddrBranch( getOpLocation(Inst->getLoc()), Inst->getConsumptionKind(), SrcValue, SrcType, DestValue, TargetType, OpSuccBB, OpFailBB, TrueCount, FalseCount)); } template void SILCloner::visitSwitchValueInst(SwitchValueInst *Inst) { SILBasicBlock *DefaultBB = nullptr; if (Inst->hasDefault()) DefaultBB = getOpBasicBlock(Inst->getDefaultBB()); SmallVector, 8> CaseBBs; for (int i = 0, e = Inst->getNumCases(); i != e; ++i) CaseBBs.push_back(std::make_pair(getOpValue(Inst->getCase(i).first), getOpBasicBlock(Inst->getCase(i).second))); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createSwitchValue(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), DefaultBB, CaseBBs)); } template void SILCloner::visitSwitchEnumInst(SwitchEnumInst *Inst) { SILBasicBlock *DefaultBB = nullptr; if (Inst->hasDefault()) DefaultBB = getOpBasicBlock(Inst->getDefaultBB()); SmallVector, 8> CaseBBs; for (unsigned i = 0, e = Inst->getNumCases(); i != e; ++i) CaseBBs.push_back(std::make_pair(Inst->getCase(i).first, getOpBasicBlock(Inst->getCase(i).second))); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createSwitchEnum(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), DefaultBB, CaseBBs)); } template void SILCloner:: visitSwitchEnumAddrInst(SwitchEnumAddrInst *Inst) { SILBasicBlock *DefaultBB = nullptr; if (Inst->hasDefault()) DefaultBB = getOpBasicBlock(Inst->getDefaultBB()); SmallVector, 8> CaseBBs; for (unsigned i = 0, e = Inst->getNumCases(); i != e; ++i) CaseBBs.push_back(std::make_pair(Inst->getCase(i).first, getOpBasicBlock(Inst->getCase(i).second))); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createSwitchEnumAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), DefaultBB, CaseBBs)); } template void SILCloner::visitSelectEnumInst(SelectEnumInst *Inst) { SILValue DefaultResult; if (Inst->hasDefault()) DefaultResult = getOpValue(Inst->getDefaultResult()); SmallVector, 8> CaseResults; for (unsigned i = 0, e = Inst->getNumCases(); i != e; ++i) CaseResults.push_back(std::make_pair(Inst->getCase(i).first, getOpValue(Inst->getCase(i).second))); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createSelectEnum(getOpLocation(Inst->getLoc()), getOpValue(Inst->getEnumOperand()), getOpType(Inst->getType()), DefaultResult, CaseResults)); } template void SILCloner::visitSelectEnumAddrInst(SelectEnumAddrInst *Inst) { SILValue DefaultResult; if (Inst->hasDefault()) DefaultResult = getOpValue(Inst->getDefaultResult()); SmallVector, 8> CaseResults; for (unsigned i = 0, e = Inst->getNumCases(); i != e; ++i) CaseResults.push_back(std::make_pair(Inst->getCase(i).first, getOpValue(Inst->getCase(i).second))); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createSelectEnumAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getEnumOperand()), getOpType(Inst->getType()), DefaultResult, CaseResults)); } template void SILCloner::visitSelectValueInst(SelectValueInst *Inst) { SILValue DefaultResult; if (Inst->hasDefault()) DefaultResult = getOpValue(Inst->getDefaultResult()); SmallVector, 8> CaseResults; for (unsigned i = 0, e = Inst->getNumCases(); i != e; ++i) CaseResults.push_back(std::make_pair(getOpValue(Inst->getCase(i).first), getOpValue(Inst->getCase(i).second))); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createSelectValue(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()), DefaultResult, CaseResults)); } template void SILCloner::visitDynamicMethodBranchInst( DynamicMethodBranchInst *Inst) { SILBasicBlock *OpHasMethodBB = getOpBasicBlock(Inst->getHasMethodBB()); SILBasicBlock *OpHasNoMethodBB = getOpBasicBlock(Inst->getNoMethodBB()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDynamicMethodBranch( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), OpHasMethodBB, OpHasNoMethodBB)); } template void SILCloner::visitProjectBlockStorageInst( ProjectBlockStorageInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createProjectBlockStorage( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitInitBlockStorageHeaderInst( InitBlockStorageHeaderInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createInitBlockStorageHeader( getOpLocation(Inst->getLoc()), getOpValue(Inst->getBlockStorage()), getOpValue(Inst->getInvokeFunction()), getOpType(Inst->getType()), getOpSubstitutions(Inst->getSubstitutions()))); } template void SILCloner::visitObjCMetatypeToObjectInst( ObjCMetatypeToObjectInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createObjCMetatypeToObject( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitObjCExistentialMetatypeToObjectInst( ObjCExistentialMetatypeToObjectInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createObjCExistentialMetatypeToObject( getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitObjCProtocolInst(ObjCProtocolInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createObjCProtocol( getOpLocation(Inst->getLoc()), Inst->getProtocol(), getOpType(Inst->getType()))); } template void SILCloner::visitKeyPathInst(KeyPathInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); SmallVector opValues; for (auto &op : Inst->getAllOperands()) opValues.push_back(getOpValue(op.get())); doPostProcess(Inst, getBuilder().createKeyPath( getOpLocation(Inst->getLoc()), Inst->getPattern(), getOpSubstitutions(Inst->getSubstitutions()), opValues, getOpType(Inst->getType()))); } } // end namespace swift #endif