//===--- 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) { } protected: #define VALUE(CLASS, PARENT) \ SILValue visit##CLASS(CLASS *I) { \ return getOpValue(I); \ } #define INST(CLASS, PARENT, MEMBEHAVIOR) \ SILValue visit##CLASS(CLASS *I); #include "swift/SIL/SILNodes.def" 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; } SILValue remapValue(SILValue Value) { return Value; } SILFunction *remapFunction(SILFunction *Func) { return Func; } SILBasicBlock *remapBasicBlock(SILBasicBlock *BB) { return BB; } SILValue postProcess(SILInstruction *Orig, SILInstruction *Cloned) { return Cloned; } SILLocation getOpLocation(SILLocation Loc) { return static_cast(this)->remapLocation(Loc); } SILType getOpType(SILType Ty) { return static_cast(this)->remapType(Ty); } 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); } SILValue doPostProcess(SILInstruction *Orig, SILInstruction *Cloned) { return static_cast(this)->postProcess(Orig, Cloned); } SILBuilder Builder; }; /// SILInstructionCloner - Concrete SILCloner subclass which can only be called /// directly on instructions and clones them without any remapping of locations, /// types, values, etc. class SILInstructionCloner : public SILCloner { public: SILInstructionCloner(SILFunction &F) : SILCloner(F) { } #define INST(CLASS, PARENT, MEMBEHAVIOR) \ CLASS *clone(CLASS *I) { \ SILValue clone = SILCloner::visit##CLASS(I);\ assert(clone->getKind() == I->getKind() && \ clone.getResultNumber() == 0); \ return static_cast(clone.getDef()); \ } #include "swift/SIL/SILNodes.def" SILInstruction *clone(SILInstruction *I) { SILValue clone = SILCloner::visit(I); assert(clone->getKind() == I->getKind() && clone.getResultNumber() == 0); return static_cast(clone.getDef()); } }; template SILValue SILCloner::visitAllocStackInst(AllocStackInst* Inst) { return doPostProcess(Inst, Builder.createAllocStack(getOpLocation(Inst->getLoc()), getOpType(Inst->getElementType()))); } template SILValue SILCloner::visitAllocRefInst(AllocRefInst* Inst) { return doPostProcess(Inst, Builder.createAllocRef(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitAllocBoxInst(AllocBoxInst* Inst) { return doPostProcess(Inst, Builder.createAllocBox(getOpLocation(Inst->getLoc()), getOpType(Inst->getElementType()))); } template SILValue SILCloner::visitAllocArrayInst(AllocArrayInst* Inst) { return doPostProcess(Inst, Builder.createAllocArray(getOpLocation(Inst->getLoc()), getOpType(Inst->getElementType()), getOpValue(Inst->getNumElements()))); } template SILValue SILCloner::visitApplyInst(ApplyInst* Inst) { auto Args = getOpValueArray<8>(Inst->getArguments()); return doPostProcess(Inst, Builder.createApply(getOpLocation(Inst->getLoc()), getOpValue(Inst->getCallee()), getOpType(Inst->getType()), Args, Inst->isTransparent())); } template SILValue SILCloner::visitPartialApplyInst(PartialApplyInst* Inst) { auto Args = getOpValueArray<8>(Inst->getArguments()); return doPostProcess(Inst, Builder.createPartialApply(getOpLocation(Inst->getLoc()), getOpValue(Inst->getCallee()), Args, getOpType(Inst->getType()))); } template SILValue SILCloner::visitBuiltinFunctionRefInst(BuiltinFunctionRefInst* Inst) { return doPostProcess(Inst, Builder.createBuiltinFunctionRef(getOpLocation(Inst->getLoc()), Inst->getFunction(), getOpType(Inst->getType()))); } template SILValue SILCloner::visitFunctionRefInst(FunctionRefInst* Inst) { return doPostProcess(Inst, Builder.createFunctionRef(getOpLocation(Inst->getLoc()), getOpFunction(Inst->getFunction()))); } template SILValue SILCloner::visitGlobalAddrInst(GlobalAddrInst* Inst) { return doPostProcess(Inst, Builder.createGlobalAddr(getOpLocation(Inst->getLoc()), Inst->getGlobal(), getOpType(Inst->getType()))); } template SILValue SILCloner::visitIntegerLiteralInst(IntegerLiteralInst* Inst) { return doPostProcess(Inst, Builder.createIntegerLiteral(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Inst->getValue())); } template SILValue SILCloner::visitFloatLiteralInst(FloatLiteralInst* Inst) { return doPostProcess(Inst, Builder.createFloatLiteral(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Inst->getValue())); } template SILValue SILCloner::visitStringLiteralInst(StringLiteralInst* Inst) { return doPostProcess(Inst, Builder.createStringLiteral(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Inst->getValue())); } template SILValue SILCloner::visitLoadInst(LoadInst* Inst) { return doPostProcess(Inst, Builder.createLoad(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitStoreInst(StoreInst* Inst) { return doPostProcess(Inst, Builder.createStore(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()))); } template SILValue SILCloner::visitAssignInst(AssignInst* Inst) { return doPostProcess(Inst, Builder.createAssign(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()))); } template SILValue SILCloner::visitMarkUninitializedInst(MarkUninitializedInst* Inst) { return doPostProcess(Inst, Builder.createMarkUninitialized(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitMarkFunctionEscapeInst(MarkFunctionEscapeInst* Inst){ auto Elements = getOpValueArray<8>(Inst->getElements()); return doPostProcess(Inst, Builder.createMarkFunctionEscape(getOpLocation(Inst->getLoc()), Elements)); } template SILValue SILCloner::visitLoadWeakInst(LoadWeakInst* Inst) { return doPostProcess(Inst, Builder.createLoadWeak(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->isTake())); } template SILValue SILCloner::visitStoreWeakInst(StoreWeakInst* Inst) { return doPostProcess(Inst, Builder.createStoreWeak(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()), Inst->isInitializationOfDest())); } template SILValue SILCloner::visitInitializeVarInst(InitializeVarInst* Inst) { return doPostProcess(Inst, Builder.createInitializeVar(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->canDefaultConstruct())); } template SILValue SILCloner::visitCopyAddrInst(CopyAddrInst* Inst) { return doPostProcess(Inst, Builder.createCopyAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrc()), getOpValue(Inst->getDest()), Inst->isTakeOfSrc(), Inst->isInitializationOfDest())); } template SILValue SILCloner::visitSpecializeInst(SpecializeInst* Inst) { return doPostProcess(Inst, Builder.createSpecialize(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getSubstitutions(), Inst->getType())); } template SILValue SILCloner::visitConvertFunctionInst(ConvertFunctionInst* Inst) { return doPostProcess(Inst, Builder.createConvertFunction(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitCoerceInst(CoerceInst* Inst) { return doPostProcess(Inst, Builder.createCoerce(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitUpcastInst(UpcastInst* Inst) { return doPostProcess(Inst, Builder.createUpcast(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitAddressToPointerInst(AddressToPointerInst* Inst) { return doPostProcess(Inst, Builder.createAddressToPointer(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitPointerToAddressInst(PointerToAddressInst* Inst) { return doPostProcess(Inst, Builder.createPointerToAddress(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitRefToObjectPointerInst(RefToObjectPointerInst* Inst) { return doPostProcess(Inst, Builder.createRefToObjectPointer(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitObjectPointerToRefInst(ObjectPointerToRefInst* Inst) { return doPostProcess(Inst, Builder.createObjectPointerToRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitRefToRawPointerInst(RefToRawPointerInst* Inst) { return doPostProcess(Inst, Builder.createRefToRawPointer(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitRawPointerToRefInst(RawPointerToRefInst* Inst) { return doPostProcess(Inst, Builder.createRawPointerToRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitRefToUnownedInst(RefToUnownedInst* Inst) { return doPostProcess(Inst, Builder.createRefToUnowned(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitUnownedToRefInst(UnownedToRefInst* Inst) { return doPostProcess(Inst, Builder.createUnownedToRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitThinToThickFunctionInst(ThinToThickFunctionInst* Inst) { return doPostProcess(Inst, Builder.createThinToThickFunction(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitConvertCCInst(ConvertCCInst* Inst) { return doPostProcess(Inst, Builder.createConvertCC(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitBridgeToBlockInst(BridgeToBlockInst* Inst) { return doPostProcess(Inst, Builder.createBridgeToBlock(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitArchetypeRefToSuperInst(ArchetypeRefToSuperInst* Inst) { return doPostProcess(Inst, Builder.createArchetypeRefToSuper(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitIsNonnullInst(IsNonnullInst* Inst) { return doPostProcess(Inst, Builder.createIsNonnull(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitDowncastInst(DowncastInst* Inst) { return doPostProcess(Inst, Builder.createDowncast(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()), Inst->getMode())); } template SILValue SILCloner::visitSuperToArchetypeRefInst(SuperToArchetypeRefInst* Inst) { return doPostProcess(Inst, Builder.createSuperToArchetypeRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()), Inst->getMode())); } template SILValue SILCloner::visitDowncastArchetypeAddrInst(DowncastArchetypeAddrInst* Inst) { return doPostProcess(Inst, Builder.createDowncastArchetypeAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()), Inst->getMode())); } template SILValue SILCloner::visitDowncastArchetypeRefInst(DowncastArchetypeRefInst* Inst) { return doPostProcess(Inst, Builder.createDowncastArchetypeRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()), Inst->getMode())); } template SILValue SILCloner::visitProjectDowncastExistentialAddrInst(ProjectDowncastExistentialAddrInst* Inst) { return doPostProcess(Inst, Builder.createProjectDowncastExistentialAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()), Inst->getMode())); } template SILValue SILCloner::visitDowncastExistentialRefInst(DowncastExistentialRefInst* Inst) { return doPostProcess(Inst, Builder.createDowncastExistentialRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()), Inst->getMode())); } template SILValue SILCloner::visitCopyValueInst(CopyValueInst* Inst) { return doPostProcess(Inst, Builder.createCopyValue(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitDestroyValueInst(DestroyValueInst* Inst) { return doPostProcess(Inst, Builder.createDestroyValue(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitStructInst(StructInst* Inst) { auto Elements = getOpValueArray<8>(Inst->getElements()); return doPostProcess(Inst, Builder.createStruct(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Elements)); } template SILValue SILCloner::visitTupleInst(TupleInst* Inst) { auto Elements = getOpValueArray<8>(Inst->getElements()); return doPostProcess(Inst, Builder.createTuple(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), Elements)); } template SILValue SILCloner::visitEnumInst(EnumInst* Inst) { return doPostProcess(Inst, Builder.createEnum(getOpLocation(Inst->getLoc()), Inst->hasOperand() ? getOpValue(Inst->getOperand()) : SILValue(), Inst->getElement(), getOpType(Inst->getType()))); } template SILValue SILCloner::visitEnumDataAddrInst(EnumDataAddrInst* Inst) { return doPostProcess(Inst, Builder.createEnumDataAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getElement(), getOpType(Inst->getType()))); } template SILValue SILCloner::visitInjectEnumAddrInst(InjectEnumAddrInst* Inst) { return doPostProcess(Inst, Builder.createInjectEnumAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getElement())); } template SILValue SILCloner::visitBuiltinZeroInst(BuiltinZeroInst* Inst) { return doPostProcess(Inst, Builder.createBuiltinZero(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitMetatypeInst(MetatypeInst* Inst) { return doPostProcess(Inst, Builder.createMetatype(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitClassMetatypeInst(ClassMetatypeInst* Inst) { return doPostProcess(Inst, Builder.createClassMetatype(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitArchetypeMetatypeInst(ArchetypeMetatypeInst* Inst) { return doPostProcess(Inst, Builder.createArchetypeMetatype(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitProtocolMetatypeInst(ProtocolMetatypeInst* Inst) { return doPostProcess(Inst, Builder.createProtocolMetatype(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitModuleInst(ModuleInst* Inst) { return doPostProcess(Inst, Builder.createModule(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitTupleExtractInst(TupleExtractInst* Inst) { return doPostProcess(Inst, Builder.createTupleExtractInst(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getFieldNo(), getOpType(Inst->getType()))); } template SILValue SILCloner::visitTupleElementAddrInst(TupleElementAddrInst* Inst) { return doPostProcess(Inst, Builder.createTupleElementAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getFieldNo(), getOpType(Inst->getType()))); } template SILValue SILCloner::visitStructExtractInst(StructExtractInst* Inst) { return doPostProcess(Inst, Builder.createStructExtract(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getField(), getOpType(Inst->getType()))); } template SILValue SILCloner::visitStructElementAddrInst(StructElementAddrInst* Inst) { return doPostProcess(Inst, Builder.createStructElementAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getField(), getOpType(Inst->getType()))); } template SILValue SILCloner::visitRefElementAddrInst(RefElementAddrInst* Inst) { return doPostProcess(Inst, Builder.createRefElementAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getField(), getOpType(Inst->getType()))); } template SILValue SILCloner::visitClassMethodInst(ClassMethodInst* Inst) { return doPostProcess(Inst, Builder.createClassMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template SILValue SILCloner::visitSuperMethodInst(SuperMethodInst* Inst) { return doPostProcess(Inst, Builder.createSuperMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template SILValue SILCloner::visitArchetypeMethodInst(ArchetypeMethodInst* Inst) { return doPostProcess(Inst, Builder.createArchetypeMethod(getOpLocation(Inst->getLoc()), getOpType(Inst->getLookupArchetype()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template SILValue SILCloner::visitProtocolMethodInst(ProtocolMethodInst* Inst) { return doPostProcess(Inst, Builder.createProtocolMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template SILValue SILCloner::visitDynamicMethodInst(DynamicMethodInst* Inst) { return doPostProcess(Inst, Builder.createDynamicMethod(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpType(Inst->getType()), Inst->isVolatile())); } template SILValue SILCloner::visitProjectExistentialInst(ProjectExistentialInst* Inst) { return doPostProcess(Inst, Builder.createProjectExistential(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitProjectExistentialRefInst(ProjectExistentialRefInst* Inst) { return doPostProcess(Inst, Builder.createProjectExistentialRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitInitExistentialInst(InitExistentialInst* Inst) { return doPostProcess(Inst, Builder.createInitExistential(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getConcreteType()), Inst->getConformances())); } template SILValue SILCloner::visitInitExistentialRefInst(InitExistentialRefInst* Inst) { return doPostProcess(Inst, Builder.createInitExistentialRef(getOpLocation(Inst->getLoc()), getOpType(Inst->getType()), getOpValue(Inst->getOperand()), Inst->getConformances())); } template SILValue SILCloner::visitDeinitExistentialInst(DeinitExistentialInst* Inst) { return doPostProcess(Inst, Builder.createDeinitExistential(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitUpcastExistentialInst(UpcastExistentialInst* Inst) { return doPostProcess(Inst, Builder.createUpcastExistential(getOpLocation(Inst->getLoc()), getOpValue(Inst->getSrcExistential()), getOpValue(Inst->getDestExistential()), (IsTake_t)Inst->isTakeOfSrc())); } template SILValue SILCloner::visitUpcastExistentialRefInst(UpcastExistentialRefInst* Inst) { return doPostProcess(Inst, Builder.createUpcastExistentialRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), getOpType(Inst->getType()))); } template SILValue SILCloner::visitStrongRetainInst(StrongRetainInst* Inst) { return doPostProcess(Inst, Builder.createStrongRetainInst(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner:: visitStrongRetainAutoreleasedInst(StrongRetainAutoreleasedInst* Inst) { return doPostProcess(Inst, Builder.createStrongRetainAutoreleased(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitStrongReleaseInst(StrongReleaseInst* Inst) { return doPostProcess(Inst, Builder.createStrongReleaseInst(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner:: visitStrongRetainUnownedInst(StrongRetainUnownedInst* Inst) { return doPostProcess(Inst, Builder.createStrongRetainUnowned(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitUnownedRetainInst(UnownedRetainInst* Inst) { return doPostProcess(Inst, Builder.createUnownedRetain(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitUnownedReleaseInst(UnownedReleaseInst* Inst) { return doPostProcess(Inst, Builder.createUnownedRelease(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitDeallocStackInst(DeallocStackInst* Inst) { return doPostProcess(Inst, Builder.createDeallocStack(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitDeallocRefInst(DeallocRefInst* Inst) { return doPostProcess(Inst, Builder.createDeallocRef(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitDeallocBoxInst(DeallocBoxInst* Inst) { return doPostProcess(Inst, Builder.createDeallocBox(getOpLocation(Inst->getLoc()), getOpType(Inst->getElementType()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitDestroyAddrInst(DestroyAddrInst* Inst) { return doPostProcess(Inst, Builder.createDestroyAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitIndexAddrInst(IndexAddrInst* Inst) { return doPostProcess(Inst, Builder.createIndexAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getBase()), getOpValue(Inst->getIndex()))); } template SILValue SILCloner::visitIndexRawPointerInst(IndexRawPointerInst* Inst) { return doPostProcess(Inst, Builder.createIndexRawPointer(getOpLocation(Inst->getLoc()), getOpValue(Inst->getBase()), getOpValue(Inst->getIndex()))); } template SILValue SILCloner::visitUnreachableInst(UnreachableInst* Inst) { return doPostProcess(Inst, Builder.createUnreachable(getOpLocation(Inst->getLoc()))); } template SILValue SILCloner::visitReturnInst(ReturnInst* Inst) { return doPostProcess(Inst, Builder.createReturn(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitAutoreleaseReturnInst(AutoreleaseReturnInst* Inst) { return doPostProcess(Inst, Builder.createAutoreleaseReturn(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()))); } template SILValue SILCloner::visitBranchInst(BranchInst* Inst) { auto Args = getOpValueArray<8>(Inst->getArgs()); return doPostProcess(Inst, Builder.createBranch(getOpLocation(Inst->getLoc()), getOpBasicBlock(Inst->getDestBB()), Args)); } template SILValue SILCloner::visitCondBranchInst(CondBranchInst* Inst) { auto TrueArgs = getOpValueArray<8>(Inst->getTrueArgs()); auto FalseArgs = getOpValueArray<8>(Inst->getFalseArgs()); return doPostProcess(Inst, Builder.createCondBranch(getOpLocation(Inst->getLoc()), getOpValue(Inst->getCondition()), getOpBasicBlock(Inst->getTrueBB()), TrueArgs, getOpBasicBlock(Inst->getFalseBB()), FalseArgs)); } template SILValue 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))); return doPostProcess(Inst, Builder.createSwitchInt(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), DefaultBB, CaseBBs)); } template SILValue 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))); return doPostProcess(Inst, Builder.createSwitchEnum(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), DefaultBB, CaseBBs)); } template SILValue SILCloner::visitDestructiveSwitchEnumAddrInst( DestructiveSwitchEnumAddrInst* 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))); return doPostProcess(Inst, Builder.createDestructiveSwitchEnumAddr(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), DefaultBB, CaseBBs)); } template SILValue SILCloner::visitDynamicMethodBranchInst( DynamicMethodBranchInst* Inst) { return doPostProcess(Inst, Builder.createDynamicMethodBranch(getOpLocation(Inst->getLoc()), getOpValue(Inst->getOperand()), Inst->getMember(), getOpBasicBlock(Inst->getHasMethodBB()), getOpBasicBlock(Inst->getNoMethodBB()))); } } // end namespace swift #endif