//===--- SILCloner.h - Defines the SILCloner class ---------------*- C++ -*-==// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// // // This file defines the SILCloner class, used for cloning SIL instructions. // //===----------------------------------------------------------------------===// #ifndef SWIFT_SIL_SILCLONER_H #define SWIFT_SIL_SILCLONER_H #include "swift/SIL/SILBuilder.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 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: explicit SILCloner(SILFunction &F) : Builder(F), InsertBeforeBB(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(); } protected: #define VALUE(CLASS, PARENT) \ void visit##CLASS(CLASS *I) { \ llvm_unreachable("SILCloner visiting non-instruction?"); \ } #define INST(CLASS, PARENT, MEMBEHAVIOR) \ void visit##CLASS(CLASS *I); #include "swift/SIL/SILNodes.def" void visitSILBasicBlock(SILBasicBlock* BB); SILBuilder &getBuilder() { return Builder; } // 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; } SILType remapType(SILType Ty) { return Ty; } ProtocolConformance *remapConformance(SILType Ty, ProtocolConformance *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 static_cast(this)->remapLocation(Loc); } SILType getOpType(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 static_cast(this)->remapType(Ty); } ProtocolConformance *getOpConformance(SILType Ty, ProtocolConformance *Conformance) { return static_cast(this)->remapConformance(Ty, Conformance); } SILValue getOpValue(SILValue Value) { return static_cast(this)->remapValue(Value); } template SmallVector getOpValueArray(ArrayRefType Values) { SmallVector Ret(Values.size()); for (unsigned i = 0, e = Values.size(); i != e; ++i) Ret[i] = static_cast(this)->remapValue(Values[i]); return Ret; } SILFunction *getOpFunction(SILFunction *Func) { return static_cast(this)->remapFunction(Func); } SILBasicBlock *getOpBasicBlock(SILBasicBlock *BB) { return static_cast(this)->remapBasicBlock(BB); } void doPostProcess(SILInstruction *Orig, SILInstruction *Cloned) { static_cast(this)->postProcess(Orig, Cloned); } SILBuilder Builder; SILBasicBlock *InsertBeforeBB; llvm::DenseMap ValueMap; llvm::DenseMap InstructionMap; llvm::DenseMap BBMap; TypeSubstitutionMap OpenedExistentialSubs; }; template SILValue SILCloner::remapValue(SILValue Value) { auto VI = ValueMap.find(Value); if (VI != ValueMap.end()) return VI->second; if (SILInstruction* I = dyn_cast(Value.getDef())) { auto II = InstructionMap.find(I); if (II != InstructionMap.end()) return SILValue(II->second, Value.getResultNumber()); llvm_unreachable("Unmapped instruction while cloning?"); } // If we have undef, just copy it. if (SILUndef *U = dyn_cast(Value.getDef())) return SILValue(U, Value.getResultNumber()); 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) { SILDebugScope *DebugScope = Orig->getDebugScope(); if (DebugScope && !Cloned->getDebugScope()) Cloned->setDebugScope(DebugScope); 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) static_cast(this)->visit(I); // Iterate over successors to do the depth-first search. for (auto &Succ : BB->getSuccs()) { auto BBI = BBMap.find(Succ); // Only visit a successor that has not already been visisted. if (BBI == BBMap.end()) { // Map the successor to a new BB. auto MappedBB = new (F.getModule()) SILBasicBlock(&F); BBMap.insert(std::make_pair(Succ.getBB(), MappedBB)); // Create new arguments for each of the original block's arguments. for (auto &Arg : Succ.getBB()->getBBArgs()) { SILValue MappedArg = new (F.getModule()) SILArgument(getOpType(Arg->getType()), MappedBB); 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()); } } } template void SILCloner::visitAllocStackInst(AllocStackInst *Inst) { doPostProcess(Inst, Builder.createAllocStack(getOpLocation(Inst->getLoc()), getOpType(Inst->getElementType()))); } template void SILCloner::visitAllocRefInst(AllocRefInst *Inst) { doPostProcess(Inst, Builder.createAllocRef(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Inst->isObjC())); } template void SILCloner::visitAllocRefDynamicInst(AllocRefDynamicInst *Inst) { doPostProcess(Inst, Builder.createAllocRefDynamic(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()), Inst->isObjC())); } template void SILCloner::visitAllocBoxInst(AllocBoxInst *Inst) { doPostProcess(Inst, Builder.createAllocBox(getOpLocation(Inst->getLoc()), getOpType(Inst->getElementType()))); } template void SILCloner::visitAllocArrayInst(AllocArrayInst *Inst) { doPostProcess(Inst, Builder.createAllocArray(getOpLocation(Inst->getLoc()), getOpType(Inst->getElementType()), getOpValue(Inst->getNumElements()))); } template void SILCloner::visitApplyInst(ApplyInst *Inst) { auto Args = getOpValueArray<8>(Inst->getArguments()); doPostProcess(Inst, Builder.createApply(getOpLocation(Inst->getLoc()), getOpValue(Inst->getCallee()), getOpType(Inst->getSubstCalleeSILType()), getOpType(Inst->getType()), Inst->getSubstitutions(), Args, Inst->isTransparent())); } template void SILCloner::visitPartialApplyInst(PartialApplyInst *Inst) { auto Args = getOpValueArray<8>(Inst->getArguments()); doPostProcess(Inst, Builder.createPartialApply(getOpLocation(Inst->getLoc()), getOpValue(Inst->getCallee()), getOpType(Inst->getSubstCalleeSILType()), Inst->getSubstitutions(), Args, getOpType(Inst->getType()))); } template void SILCloner::visitBuiltinFunctionRefInst(BuiltinFunctionRefInst *Inst){ doPostProcess(Inst, Builder.createBuiltinFunctionRef(getOpLocation(Inst->getLoc()), Inst->getName(), getOpType(Inst->getType()))); } template void SILCloner::visitFunctionRefInst(FunctionRefInst *Inst) { doPostProcess(Inst, Builder.createFunctionRef(getOpLocation(Inst->getLoc()), getOpFunction(Inst->getReferencedFunction()))); } template void SILCloner::visitGlobalAddrInst(GlobalAddrInst *Inst) { doPostProcess(Inst, Builder.createGlobalAddr(getOpLocation(Inst->getLoc()), Inst->getGlobal(), getOpType(Inst->getType()))); } template void SILCloner::visitSILGlobalAddrInst(SILGlobalAddrInst *Inst) { doPostProcess(Inst, Builder.createSILGlobalAddr(getOpLocation(Inst->getLoc()), Inst->getReferencedGlobal())); } template void SILCloner::visitIntegerLiteralInst(IntegerLiteralInst *Inst) { doPostProcess(Inst, Builder.createIntegerLiteral(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Inst->getValue())); } template void SILCloner::visitFloatLiteralInst(FloatLiteralInst *Inst) { doPostProcess(Inst, Builder.createFloatLiteral(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Inst->getValue())); } template void SILCloner::visitStringLiteralInst(StringLiteralInst *Inst) { doPostProcess(Inst, Builder.createStringLiteral(getOpLocation(Inst->getLoc()), Inst->getValue(), Inst->getEncoding())); } template void SILCloner::visitLoadInst(LoadInst *Inst) { doPostProcess(Inst, Builder.createLoad(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitStoreInst(StoreInst *Inst) { doPostProcess(Inst, Builder.createStore(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()))); } template void SILCloner::visitAssignInst(AssignInst *Inst) { doPostProcess(Inst, Builder.createAssign(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()))); } template void SILCloner::visitMarkUninitializedInst(MarkUninitializedInst *Inst) { doPostProcess(Inst, Builder.createMarkUninitialized(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getKind())); } template void SILCloner::visitMarkFunctionEscapeInst(MarkFunctionEscapeInst *Inst){ auto Elements = getOpValueArray<8>(Inst->getElements()); doPostProcess(Inst, Builder.createMarkFunctionEscape(getOpLocation(Inst->getLoc()), Elements)); } template void SILCloner::visitDebugValueInst(DebugValueInst *Inst) { // Since we want the debug info to survive, we do not remap the location here. doPostProcess(Inst, Builder.createDebugValue(Inst->getLoc(), getOpValue(Inst->getOperand()))); } template void SILCloner::visitDebugValueAddrInst(DebugValueAddrInst *Inst) { // Do not remap the location for a debug instruction. doPostProcess(Inst, Builder.createDebugValueAddr(Inst->getLoc(), getOpValue(Inst->getOperand()))); } template void SILCloner::visitLoadWeakInst(LoadWeakInst *Inst) { doPostProcess(Inst, Builder.createLoadWeak(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->isTake())); } template void SILCloner::visitStoreWeakInst(StoreWeakInst *Inst) { doPostProcess(Inst, Builder.createStoreWeak(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()), Inst->isInitializationOfDest())); } template void SILCloner::visitCopyAddrInst(CopyAddrInst *Inst) { doPostProcess(Inst, Builder.createCopyAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()), Inst->isTakeOfSrc(), Inst->isInitializationOfDest())); } template void SILCloner::visitConvertFunctionInst(ConvertFunctionInst *Inst) { doPostProcess(Inst, Builder.createConvertFunction(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitUpcastInst(UpcastInst *Inst) { doPostProcess(Inst, Builder.createUpcast(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitAddressToPointerInst(AddressToPointerInst *Inst) { doPostProcess(Inst, Builder.createAddressToPointer(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitPointerToAddressInst(PointerToAddressInst *Inst) { doPostProcess(Inst, Builder.createPointerToAddress(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitRefToObjectPointerInst(RefToObjectPointerInst *Inst) { doPostProcess(Inst, Builder.createRefToObjectPointer(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitObjectPointerToRefInst(ObjectPointerToRefInst *Inst) { doPostProcess(Inst, Builder.createObjectPointerToRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitRefToRawPointerInst(RefToRawPointerInst *Inst) { doPostProcess(Inst, Builder.createRefToRawPointer(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitRawPointerToRefInst(RawPointerToRefInst *Inst) { doPostProcess(Inst, Builder.createRawPointerToRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitRefToUnownedInst(RefToUnownedInst *Inst) { doPostProcess(Inst, Builder.createRefToUnowned(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitUnownedToRefInst(UnownedToRefInst *Inst) { doPostProcess(Inst, Builder.createUnownedToRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitThinToThickFunctionInst(ThinToThickFunctionInst *Inst) { doPostProcess(Inst, Builder.createThinToThickFunction(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitThickToObjCMetatypeInst( ThickToObjCMetatypeInst *Inst) { doPostProcess(Inst, Builder.createThickToObjCMetatype(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitObjCToThickMetatypeInst( ObjCToThickMetatypeInst *Inst) { doPostProcess(Inst, Builder.createObjCToThickMetatype(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitBridgeToBlockInst(BridgeToBlockInst *Inst) { doPostProcess(Inst, Builder.createBridgeToBlock(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitIsNonnullInst(IsNonnullInst *Inst) { doPostProcess(Inst, Builder.createIsNonnull(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitUnconditionalCheckedCastInst( UnconditionalCheckedCastInst *Inst) { doPostProcess(Inst, Builder.createUnconditionalCheckedCast(getOpLocation(Inst->getLoc()), Inst->getCastKind(), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitRetainValueInst(RetainValueInst *Inst) { doPostProcess(Inst, Builder.createRetainValue(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitReleaseValueInst(ReleaseValueInst *Inst) { doPostProcess(Inst, Builder.createReleaseValue(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitStructInst(StructInst *Inst) { auto Elements = getOpValueArray<8>(Inst->getElements()); doPostProcess(Inst, Builder.createStruct(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Elements)); } template void SILCloner::visitTupleInst(TupleInst *Inst) { auto Elements = getOpValueArray<8>(Inst->getElements()); doPostProcess(Inst, Builder.createTuple(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Elements)); } template void SILCloner::visitEnumInst(EnumInst *Inst) { doPostProcess(Inst, Builder.createEnum(getOpLocation(Inst->getLoc()), Inst->hasOperand() ? getOpValue(Inst->getOperand()) : SILValue(), Inst->getElement(), getOpType(Inst->getType()))); } template void SILCloner::visitInitEnumDataAddrInst(InitEnumDataAddrInst *Inst) { doPostProcess(Inst, Builder.createInitEnumDataAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getElement(), getOpType(Inst->getType()))); } template void SILCloner::visitTakeEnumDataAddrInst(TakeEnumDataAddrInst *Inst) { doPostProcess(Inst, Builder.createTakeEnumDataAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getElement(), getOpType(Inst->getType()))); } template void SILCloner::visitInjectEnumAddrInst(InjectEnumAddrInst *Inst) { doPostProcess(Inst, Builder.createInjectEnumAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getElement())); } template void SILCloner::visitMetatypeInst(MetatypeInst *Inst) { doPostProcess(Inst, Builder.createMetatype(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()))); } template void SILCloner::visitValueMetatypeInst(ValueMetatypeInst *Inst) { doPostProcess(Inst, Builder.createValueMetatype(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitExistentialMetatypeInst(ExistentialMetatypeInst *Inst) { doPostProcess(Inst, Builder.createExistentialMetatype(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitTupleExtractInst(TupleExtractInst *Inst) { doPostProcess(Inst, Builder.createTupleExtract(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getFieldNo(), getOpType(Inst->getType()))); } template void SILCloner::visitTupleElementAddrInst(TupleElementAddrInst *Inst) { doPostProcess(Inst, Builder.createTupleElementAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getFieldNo(), getOpType(Inst->getType()))); } template void SILCloner::visitStructExtractInst(StructExtractInst *Inst) { doPostProcess(Inst, Builder.createStructExtract(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getField(), getOpType(Inst->getType()))); } template void SILCloner::visitStructElementAddrInst(StructElementAddrInst *Inst) { doPostProcess(Inst, Builder.createStructElementAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getField(), getOpType(Inst->getType()))); } template void SILCloner::visitRefElementAddrInst(RefElementAddrInst *Inst) { doPostProcess(Inst, Builder.createRefElementAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getField(), getOpType(Inst->getType()))); } template void SILCloner::visitClassMethodInst(ClassMethodInst *Inst) { doPostProcess(Inst, Builder.createClassMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template void SILCloner::visitSuperMethodInst(SuperMethodInst *Inst) { doPostProcess(Inst, Builder.createSuperMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template void SILCloner::visitWitnessMethodInst(WitnessMethodInst *Inst) { doPostProcess(Inst, Builder.createWitnessMethod(getOpLocation(Inst->getLoc()), getOpType(Inst->getLookupType()), getOpConformance(Inst->getLookupType(), Inst->getConformance()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template void SILCloner::visitProtocolMethodInst(ProtocolMethodInst *Inst) { doPostProcess(Inst, Builder.createProtocolMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template void SILCloner::visitDynamicMethodInst(DynamicMethodInst *Inst) { doPostProcess(Inst, Builder.createDynamicMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template void SILCloner::visitProjectExistentialInst(ProjectExistentialInst *Inst) { doPostProcess(Inst, Builder.createProjectExistential(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitProjectExistentialRefInst(ProjectExistentialRefInst *Inst) { doPostProcess(Inst, Builder.createProjectExistentialRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitOpenExistentialInst(OpenExistentialInst *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?"); OpenedExistentialSubs[archetypeTy] = ArchetypeType::getOpened(archetypeTy->getOpenedExistentialType()); doPostProcess(Inst, Builder.createOpenExistential(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(); OpenedExistentialSubs[archetypeTy] = ArchetypeType::getOpened(archetypeTy->getOpenedExistentialType()); doPostProcess(Inst, Builder.createOpenExistentialRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitInitExistentialInst(InitExistentialInst *Inst) { doPostProcess(Inst, Builder.createInitExistential(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getConcreteType()), Inst->getConformances())); } template void SILCloner::visitInitExistentialRefInst(InitExistentialRefInst *Inst) { doPostProcess(Inst, Builder.createInitExistentialRef(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), getOpValue(Inst->getOperand()), Inst->getConformances())); } template void SILCloner::visitDeinitExistentialInst(DeinitExistentialInst *Inst) { doPostProcess(Inst, Builder.createDeinitExistential(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitUpcastExistentialInst(UpcastExistentialInst *Inst) { doPostProcess(Inst, Builder.createUpcastExistential(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrcExistential()), getOpValue(Inst->getDestExistential()), (IsTake_t)Inst->isTakeOfSrc())); } template void SILCloner::visitUpcastExistentialRefInst(UpcastExistentialRefInst *Inst) { doPostProcess(Inst, Builder.createUpcastExistentialRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template void SILCloner::visitStrongRetainInst(StrongRetainInst *Inst) { doPostProcess(Inst, Builder.createStrongRetain(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner:: visitStrongRetainAutoreleasedInst(StrongRetainAutoreleasedInst *Inst) { doPostProcess(Inst, Builder.createStrongRetainAutoreleased(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitFixLifetimeInst(FixLifetimeInst *Inst) { doPostProcess(Inst, Builder.createFixLifetime(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitStrongReleaseInst(StrongReleaseInst *Inst) { doPostProcess(Inst, Builder.createStrongRelease(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner:: visitStrongRetainUnownedInst(StrongRetainUnownedInst *Inst) { doPostProcess(Inst, Builder.createStrongRetainUnowned(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitUnownedRetainInst(UnownedRetainInst *Inst) { doPostProcess(Inst, Builder.createUnownedRetain(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitUnownedReleaseInst(UnownedReleaseInst *Inst) { doPostProcess(Inst, Builder.createUnownedRelease(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitDeallocStackInst(DeallocStackInst *Inst) { doPostProcess(Inst, Builder.createDeallocStack(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitDeallocRefInst(DeallocRefInst *Inst) { doPostProcess(Inst, Builder.createDeallocRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitDeallocBoxInst(DeallocBoxInst *Inst) { doPostProcess(Inst, Builder.createDeallocBox(getOpLocation(Inst->getLoc()), getOpType(Inst->getElementType()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitDestroyAddrInst(DestroyAddrInst *Inst) { doPostProcess(Inst, Builder.createDestroyAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitCondFailInst(CondFailInst *Inst) { doPostProcess(Inst, Builder.createCondFail(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitIndexAddrInst(IndexAddrInst *Inst) { doPostProcess(Inst, Builder.createIndexAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getBase()), getOpValue(Inst->getIndex()))); } template void SILCloner::visitIndexRawPointerInst(IndexRawPointerInst *Inst) { doPostProcess(Inst, Builder.createIndexRawPointer(getOpLocation(Inst->getLoc()), getOpValue(Inst->getBase()), getOpValue(Inst->getIndex()))); } template void SILCloner::visitUnreachableInst(UnreachableInst *Inst) { doPostProcess(Inst, Builder.createUnreachable(getOpLocation(Inst->getLoc()))); } template void SILCloner::visitReturnInst(ReturnInst *Inst) { doPostProcess(Inst, Builder.createReturn(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitAutoreleaseReturnInst(AutoreleaseReturnInst *Inst) { doPostProcess(Inst, Builder.createAutoreleaseReturn(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template void SILCloner::visitBranchInst(BranchInst *Inst) { auto Args = getOpValueArray<8>(Inst->getArgs()); doPostProcess(Inst, Builder.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()); doPostProcess(Inst, Builder.createCondBranch(getOpLocation(Inst->getLoc()), getOpValue(Inst->getCondition()), getOpBasicBlock(Inst->getTrueBB()), TrueArgs, getOpBasicBlock(Inst->getFalseBB()), FalseArgs)); } template void SILCloner::visitCheckedCastBranchInst(CheckedCastBranchInst *Inst) { doPostProcess(Inst, Builder.createCheckedCastBranch(getOpLocation(Inst->getLoc()), Inst->getCastKind(), getOpValue(Inst->getOperand()), getOpType(Inst->getCastType()), getOpBasicBlock(Inst->getSuccessBB()), getOpBasicBlock(Inst->getFailureBB()))); } template void SILCloner::visitSwitchIntInst(SwitchIntInst *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(Inst->getCase(i).first, getOpBasicBlock(Inst->getCase(i).second))); doPostProcess(Inst, Builder.createSwitchInt(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(int i = 0, e = Inst->getNumCases(); i != e; ++i) CaseBBs.push_back(std::make_pair(Inst->getCase(i).first, getOpBasicBlock(Inst->getCase(i).second))); doPostProcess(Inst, Builder.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(int i = 0, e = Inst->getNumCases(); i != e; ++i) CaseBBs.push_back(std::make_pair(Inst->getCase(i).first, getOpBasicBlock(Inst->getCase(i).second))); doPostProcess(Inst, Builder.createSwitchEnumAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), DefaultBB, CaseBBs)); } template void SILCloner::visitDynamicMethodBranchInst( DynamicMethodBranchInst *Inst) { doPostProcess(Inst, Builder.createDynamicMethodBranch(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpBasicBlock(Inst->getHasMethodBB()), getOpBasicBlock(Inst->getNoMethodBB()))); } } // end namespace swift #endif