//===--- SILCloner.h - Defines the SILCloner class --------------*- C++ -*-===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See 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/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 SILVisitor { friend class SILVisitor; public: using SILVisitor::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); } /// 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(ValueBase *V) { if (auto I = dyn_cast(V)) { // Update the set of available opened archetypes with the opened // archetypes used by the current instruction. doPreProcess(I); } } #define VALUE(CLASS, PARENT) \ void visit##CLASS(CLASS *I) { \ llvm_unreachable("SILCloner visiting non-instruction?"); \ } #define INST(CLASS, PARENT, TEXTUALNAME, MEMBEHAVIOR, RELEASINGBEHAVIOR) \ 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(CanType 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); } Substitution getOpSubstitution(Substitution sub) { return asImpl().remapSubstitution(sub); } Substitution remapSubstitution(Substitution sub) { CanType newReplacement = asImpl().getOpASTType(sub.getReplacement()->getCanonicalType()); return Substitution(newReplacement, sub.getConformances()); } ArrayRef getOpSubstitutions(ArrayRef Subs) { MutableArrayRef newSubsBuf; auto copySubs = [&]{ if (!newSubsBuf.empty()) return; newSubsBuf = getBuilder().getASTContext() .template Allocate(Subs.size()); memcpy(newSubsBuf.data(), Subs.data(), sizeof(Substitution) * Subs.size()); Subs = newSubsBuf; }; for (unsigned i = 0, e = Subs.size(); i < e; ++i) { Substitution newSub = asImpl().getOpSubstitution(Subs[i]); if (newSub != Subs[i]) { copySubs(); newSubsBuf[i] = newSub; } } return Subs; } SILType getTypeInClonedContext(SILType Ty) { // Substitute opened existential types, if we have any. if (!OpenedExistentialSubs.empty()) { auto &F = getBuilder().getFunction(); Ty = SILType::substType(F.getModule(), F.getModule().getSwiftModule(), OpenedExistentialSubs, Ty); } return Ty; } SILType getOpType(SILType Ty) { Ty = getTypeInClonedContext(Ty); return asImpl().remapType(Ty); } CanType getASTTypeInClonedContext(CanType ty) { // Substitute opened existential types, if we have any. if (!OpenedExistentialSubs.empty()) { auto &F = getBuilder().getFunction(); ty = ty.subst(F.getModule().getSwiftModule(), OpenedExistentialSubs, None)->getCanonicalType(); } return ty; } CanType getOpASTType(CanType ty) { ty = getASTTypeInClonedContext(ty); return asImpl().remapASTType(ty); } /// Remap an entire set of conformances. /// /// Returns the passed-in conformances array if none of the elements /// changed. ArrayRef getOpConformances(CanType type, ArrayRef oldConformances) { Substitution sub(type, oldConformances); Substitution mappedSub = asImpl().remapSubstitution(sub); ArrayRef newConformances = mappedSub.getConformances(); // Use the existing conformances array if possible. if (oldConformances == newConformances) return oldConformances; return type->getASTContext().AllocateCopy(newConformances); } ProtocolConformanceRef getOpConformance(CanType ty, ProtocolConformanceRef conformance) { return asImpl().remapConformance(ty, conformance); } 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, CanType To) { OpenedExistentialSubs[From] = To; } protected: SILBuilder Builder; SILBasicBlock *InsertBeforeBB; llvm::DenseMap ValueMap; llvm::DenseMap InstructionMap; // 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 (SILInstruction* I = dyn_cast(Value)) { auto II = InstructionMap.find(I); if (II != InstructionMap.end()) return SILValue(II->second); llvm_unreachable("Unmapped instruction while cloning?"); } // If we have undef, just remap the type. if (SILUndef *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"); InstructionMap.insert(std::make_pair(Orig, Cloned)); } /// \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()->getArguments()) { SILValue MappedArg = MappedBB->createArgument(getOpType(Arg->getType())); 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->replaceAllUsesWithUndef(); 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()), getOpType(Inst->getSubstCalleeSILType()), getOpType(Inst->getType()), getOpSubstitutions(Inst->getSubstitutions()), Args, Inst->isNonThrowing())); } 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()), getOpType(Inst->getSubstCalleeSILType()), getOpSubstitutions(Inst->getSubstitutions()), Args, getOpBasicBlock(Inst->getNormalBB()), getOpBasicBlock(Inst->getErrorBB()))); } 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()), getOpType(Inst->getSubstCalleeSILType()), getOpSubstitutions(Inst->getSubstitutions()), Args, getOpType(Inst->getType()))); } 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::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::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->getSrc()), getOpValue(Inst->getDest()))); } 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())); } 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::visitIsNonnullInst(IsNonnullInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createIsNonnull(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } 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, Inst->getConsumptionKind(), SrcValue, SrcType, DestValue, TargetType)); } 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::visitCopyValueInst(CopyValueInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createCopyValue(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::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::visitSetDeallocatingInst(SetDeallocatingInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createSetDeallocating(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getAtomicity())); } 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::visitClassMethodInst(ClassMethodInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createClassMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template void SILCloner::visitSuperMethodInst(SuperMethodInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createSuperMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template void SILCloner::visitWitnessMethodInst(WitnessMethodInst *Inst) { auto conformance = getOpConformance(Inst->getLookupType(), Inst->getConformance()); auto lookupType = Inst->getLookupType(); auto newLookupType = getOpASTType(lookupType); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess( Inst, getBuilder() .createWitnessMethod( getOpLocation(Inst->getLoc()), newLookupType, conformance, Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template void SILCloner::visitDynamicMethodInst(DynamicMethodInst *Inst) { getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createDynamicMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template void SILCloner::visitOpenExistentialAddrInst(OpenExistentialAddrInst *Inst) { // Create a new archetype for this opened existential type. auto archetypeTy = Inst->getType().getSwiftRValueType()->castTo(); assert(OpenedExistentialSubs.count(archetypeTy) == 0 && "Already substituted opened existential archetype?"); registerOpenedExistentialRemapping( archetypeTy, ArchetypeType::getOpened(archetypeTy->getOpenedExistentialType())); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createOpenExistentialAddr(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::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:: visitInitExistentialMetatypeInst(InitExistentialMetatypeInst *Inst) { auto conformances = getOpConformances(Inst->getFormalErasedObjectType(), 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::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::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::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)); } template void SILCloner::visitCheckedCastBranchInst(CheckedCastBranchInst *Inst) { SILBasicBlock *OpSuccBB = getOpBasicBlock(Inst->getSuccessBB()); SILBasicBlock *OpFailBB = getOpBasicBlock(Inst->getFailureBB()); getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope())); doPostProcess(Inst, getBuilder().createCheckedCastBranch(getOpLocation(Inst->getLoc()), Inst->isExact(), 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())); doPostProcess(Inst, getBuilder().createCheckedCastAddrBranch(getOpLocation(Inst->getLoc()), Inst->getConsumptionKind(), SrcValue, SrcType, DestValue, TargetType, OpSuccBB, OpFailBB)); } 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()))); } } // end namespace swift #endif