mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
1914 lines
76 KiB
C++
1914 lines
76 KiB
C++
//===--- 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 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/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<typename ImplClass>
|
|
class SILCloner : protected SILVisitor<ImplClass> {
|
|
friend class SILVisitor<ImplClass, SILValue>;
|
|
|
|
public:
|
|
using SILVisitor<ImplClass>::asImpl;
|
|
|
|
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<SILInstruction*> *II) {
|
|
getBuilder().setTrackingList(II);
|
|
}
|
|
|
|
SmallVectorImpl<SILInstruction*> *getTrackingList() {
|
|
return getBuilder().getTrackingList();
|
|
}
|
|
|
|
SILBuilder &getBuilder() { return Builder; }
|
|
|
|
protected:
|
|
#define VALUE(CLASS, PARENT) \
|
|
void visit##CLASS(CLASS *I) { \
|
|
llvm_unreachable("SILCloner visiting non-instruction?"); \
|
|
}
|
|
#define INST(CLASS, PARENT, 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<Substitution> getOpSubstitutions(ArrayRef<Substitution> Subs) {
|
|
MutableArrayRef<Substitution> newSubsBuf;
|
|
|
|
auto copySubs = [&]{
|
|
if (!newSubsBuf.empty())
|
|
return;
|
|
newSubsBuf = getBuilder().getASTContext()
|
|
.template Allocate<Substitution>(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<ProtocolConformanceRef> getOpConformances(CanType type,
|
|
ArrayRef<ProtocolConformanceRef> oldConformances) {
|
|
Substitution sub(type, oldConformances);
|
|
Substitution mappedSub = asImpl().remapSubstitution(sub);
|
|
ArrayRef<ProtocolConformanceRef> 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 <size_t N, typename ArrayRefType>
|
|
SmallVector<SILValue, N> getOpValueArray(ArrayRefType Values) {
|
|
SmallVector<SILValue, N> 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 doPostProcess(SILInstruction *Orig, SILInstruction *Cloned) {
|
|
asImpl().postProcess(Orig, Cloned);
|
|
assert((Orig->getDebugScope() ? Cloned->getDebugScope()!=nullptr : true) &&
|
|
"cloned instruction dropped debug scope");
|
|
}
|
|
|
|
protected:
|
|
|
|
SILBuilder Builder;
|
|
SILBasicBlock *InsertBeforeBB;
|
|
llvm::DenseMap<SILValue, SILValue> ValueMap;
|
|
llvm::DenseMap<SILInstruction*, SILInstruction*> InstructionMap;
|
|
|
|
// Use MapVector to ensure that the order of block predecessors is
|
|
// deterministic.
|
|
llvm::MapVector<SILBasicBlock*, SILBasicBlock*> BBMap;
|
|
|
|
TypeSubstitutionMap OpenedExistentialSubs;
|
|
/// Set of basic blocks where unreachable was inserted.
|
|
SmallPtrSet<SILBasicBlock *, 32> BlocksWithUnreachables;
|
|
};
|
|
|
|
/// \brief A SILBuilder that automatically invokes postprocess on each
|
|
/// inserted instruction.
|
|
template<class SomeSILCloner, unsigned N = 4>
|
|
class SILBuilderWithPostProcess : public SILBuilder {
|
|
SomeSILCloner &SC;
|
|
SILInstruction *Orig;
|
|
SmallVector<SILInstruction*, N> InsertedInstrs;
|
|
|
|
public:
|
|
SILBuilderWithPostProcess(SomeSILCloner *sc, SILInstruction *Orig)
|
|
: SILBuilder(sc->getBuilder().getInsertionBB(), &InsertedInstrs),
|
|
SC(*sc), Orig(Orig)
|
|
{
|
|
setInsertionPoint(SC.getBuilder().getInsertionBB(),
|
|
SC.getBuilder().getInsertionPoint());
|
|
}
|
|
|
|
~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<typename ImplClass>
|
|
class SILClonerWithScopes : public SILCloner<ImplClass> {
|
|
friend class SILCloner<ImplClass>;
|
|
public:
|
|
SILClonerWithScopes(SILFunction &To, bool Disable = false)
|
|
: SILCloner<ImplClass>(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> scopeCloner;
|
|
protected:
|
|
/// Clone the SILDebugScope for the cloned function.
|
|
void postProcess(SILInstruction *Orig, SILInstruction *Cloned) {
|
|
SILCloner<ImplClass>::postProcess(Orig, Cloned);
|
|
}
|
|
|
|
const SILDebugScope *remapScope(const SILDebugScope *DS) {
|
|
return scopeCloner ? scopeCloner->getOrCreateClonedScope(DS) : DS;
|
|
}
|
|
};
|
|
|
|
template<typename ImplClass>
|
|
SILValue
|
|
SILCloner<ImplClass>::remapValue(SILValue Value) {
|
|
auto VI = ValueMap.find(Value);
|
|
if (VI != ValueMap.end())
|
|
return VI->second;
|
|
|
|
if (SILInstruction* I = dyn_cast<SILInstruction>(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<SILUndef>(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<typename ImplClass>
|
|
SILBasicBlock*
|
|
SILCloner<ImplClass>::remapBasicBlock(SILBasicBlock *BB) {
|
|
SILBasicBlock *MappedBB = BBMap[BB];
|
|
assert(MappedBB && "Unmapped basic block while cloning?");
|
|
return MappedBB;
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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 = 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(MappedBB, 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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<UnreachableInst>(&I))
|
|
continue;
|
|
|
|
// Collect together all the instructions after this point
|
|
llvm::SmallVector<SILInstruction *, 32> 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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitSILFunction(SILFunction *F) {
|
|
for (auto &BB : *F)
|
|
asImpl().visitSILBasicBlock(&BB);
|
|
cleanUp(F);
|
|
}
|
|
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitAllocStackInst(AllocStackInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createAllocStack(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getElementType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitAllocRefInst(AllocRefInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createAllocRef(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getType()),
|
|
Inst->isObjC(), Inst->canAllocOnStack()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitAllocRefDynamicInst(AllocRefDynamicInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createAllocRefDynamic(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType()),
|
|
Inst->isObjC()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitAllocBoxInst(AllocBoxInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createAllocBox(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getElementType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitAllocValueBufferInst(AllocValueBufferInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createAllocValueBuffer(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getValueType()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitFunctionRefInst(FunctionRefInst *Inst) {
|
|
SILFunction *OpFunction = getOpFunction(Inst->getReferencedFunction());
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createFunctionRef(getOpLocation(Inst->getLoc()),
|
|
OpFunction));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitAllocGlobalInst(AllocGlobalInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createAllocGlobal(getOpLocation(Inst->getLoc()),
|
|
Inst->getReferencedGlobal()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitGlobalAddrInst(GlobalAddrInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createGlobalAddr(getOpLocation(Inst->getLoc()),
|
|
Inst->getReferencedGlobal()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitIntegerLiteralInst(IntegerLiteralInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createIntegerLiteral(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getType()),
|
|
Inst->getValue()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitFloatLiteralInst(FloatLiteralInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createFloatLiteral(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getType()),
|
|
Inst->getValue()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitStringLiteralInst(StringLiteralInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStringLiteral(getOpLocation(Inst->getLoc()),
|
|
Inst->getValue(),
|
|
Inst->getEncoding()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitLoadInst(LoadInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createLoad(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitStoreInst(StoreInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStore(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getSrc()),
|
|
getOpValue(Inst->getDest())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitAssignInst(AssignInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createAssign(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getSrc()),
|
|
getOpValue(Inst->getDest())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitMarkUninitializedInst(MarkUninitializedInst *Inst) {
|
|
SILValue OpValue = getOpValue(Inst->getOperand());
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createMarkUninitialized(getOpLocation(Inst->getLoc()),
|
|
OpValue,
|
|
Inst->getKind()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitLoadUnownedInst(LoadUnownedInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createLoadUnowned(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->isTake()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitStoreUnownedInst(StoreUnownedInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStoreUnowned(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getSrc()),
|
|
getOpValue(Inst->getDest()),
|
|
Inst->isInitializationOfDest()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitLoadWeakInst(LoadWeakInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createLoadWeak(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->isTake()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitStoreWeakInst(StoreWeakInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStoreWeak(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getSrc()),
|
|
getOpValue(Inst->getDest()),
|
|
Inst->isInitializationOfDest()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitConvertFunctionInst(ConvertFunctionInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createConvertFunction(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void SILCloner<ImplClass>::visitThinFunctionToPointerInst(
|
|
ThinFunctionToPointerInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createThinFunctionToPointer(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void SILCloner<ImplClass>::visitPointerToThinFunctionInst(
|
|
PointerToThinFunctionInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createPointerToThinFunction(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitUpcastInst(UpcastInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUpcast(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitAddressToPointerInst(AddressToPointerInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createAddressToPointer(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitPointerToAddressInst(PointerToAddressInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createPointerToAddress(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitUncheckedRefCastInst(UncheckedRefCastInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUncheckedRefCast(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitUncheckedAddrCastInst(UncheckedAddrCastInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUncheckedAddrCast(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitUncheckedTrivialBitCastInst(UncheckedTrivialBitCastInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUncheckedTrivialBitCast(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitUncheckedBitwiseCastInst(UncheckedBitwiseCastInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUncheckedBitwiseCast(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitRefToBridgeObjectInst(RefToBridgeObjectInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createRefToBridgeObject(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getConverted()),
|
|
getOpValue(Inst->getBitsOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitBridgeObjectToRefInst(BridgeObjectToRefInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createBridgeObjectToRef(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getConverted()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitBridgeObjectToWordInst(BridgeObjectToWordInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createBridgeObjectToWord(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getConverted()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitRefToRawPointerInst(RefToRawPointerInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createRefToRawPointer(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitRawPointerToRefInst(RawPointerToRefInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createRawPointerToRef(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitRefToUnownedInst(RefToUnownedInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createRefToUnowned(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitUnownedToRefInst(UnownedToRefInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUnownedToRef(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitRefToUnmanagedInst(RefToUnmanagedInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createRefToUnmanaged(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitUnmanagedToRefInst(UnmanagedToRefInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUnmanagedToRef(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitThinToThickFunctionInst(ThinToThickFunctionInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createThinToThickFunction(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitThickToObjCMetatypeInst(ThickToObjCMetatypeInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createThickToObjCMetatype(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitObjCToThickMetatypeInst(ObjCToThickMetatypeInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createObjCToThickMetatype(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitIsNonnullInst(IsNonnullInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createIsNonnull(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitRetainValueInst(RetainValueInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createRetainValue(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getAtomicity()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitReleaseValueInst(ReleaseValueInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createReleaseValue(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getAtomicity()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitAutoreleaseValueInst(AutoreleaseValueInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createAutoreleaseValue(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getAtomicity()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitSetDeallocatingInst(SetDeallocatingInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createSetDeallocating(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getAtomicity()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitInitEnumDataAddrInst(InitEnumDataAddrInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createInitEnumDataAddr(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getElement(),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitUncheckedEnumDataInst(UncheckedEnumDataInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUncheckedEnumData(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getElement(),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitUncheckedTakeEnumDataAddrInst(UncheckedTakeEnumDataAddrInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUncheckedTakeEnumDataAddr(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getElement(),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitInjectEnumAddrInst(InjectEnumAddrInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createInjectEnumAddr(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getElement()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitMetatypeInst(MetatypeInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createMetatype(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitValueMetatypeInst(ValueMetatypeInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createValueMetatype(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getType()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitExistentialMetatypeInst(ExistentialMetatypeInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createExistentialMetatype(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getType()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitTupleExtractInst(TupleExtractInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createTupleExtract(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getFieldNo(),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitTupleElementAddrInst(TupleElementAddrInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createTupleElementAddr(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getFieldNo(),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitStructExtractInst(StructExtractInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStructExtract(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getField(),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitStructElementAddrInst(StructElementAddrInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStructElementAddr(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getField(),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitRefElementAddrInst(RefElementAddrInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createRefElementAddr(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getField(),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitWitnessMethodInst(WitnessMethodInst *Inst) {
|
|
auto conformance =
|
|
getOpConformance(Inst->getLookupType(), Inst->getConformance());
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(
|
|
Inst,
|
|
getBuilder()
|
|
.createWitnessMethod(
|
|
getOpLocation(Inst->getLoc()),
|
|
getOpASTType(Inst->getLookupType()), conformance,
|
|
Inst->getMember(), getOpType(Inst->getType()),
|
|
Inst->hasOperand() ? getOpValue(Inst->getOperand()) : SILValue(),
|
|
Inst->isVolatile()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitOpenExistentialAddrInst(OpenExistentialAddrInst *Inst) {
|
|
// Create a new archetype for this opened existential type.
|
|
auto archetypeTy
|
|
= Inst->getType().getSwiftRValueType()->castTo<ArchetypeType>();
|
|
assert(OpenedExistentialSubs.count(archetypeTy) == 0 &&
|
|
"Already substituted opened existential archetype?");
|
|
OpenedExistentialSubs[archetypeTy]
|
|
= ArchetypeType::getOpened(archetypeTy->getOpenedExistentialType());
|
|
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createOpenExistentialAddr(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
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<ExistentialMetatypeType>(exType)) {
|
|
exType = exMetatype.getInstanceType();
|
|
openedType = cast<MetatypeType>(openedType).getInstanceType();
|
|
}
|
|
auto archetypeTy = cast<ArchetypeType>(openedType);
|
|
OpenedExistentialSubs[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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitOpenExistentialRefInst(OpenExistentialRefInst *Inst) {
|
|
// Create a new archetype for this opened existential type.
|
|
auto archetypeTy
|
|
= Inst->getType().getSwiftRValueType()->castTo<ArchetypeType>();
|
|
OpenedExistentialSubs[archetypeTy]
|
|
= ArchetypeType::getOpened(archetypeTy->getOpenedExistentialType());
|
|
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createOpenExistentialRef(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitOpenExistentialBoxInst(OpenExistentialBoxInst *Inst) {
|
|
// Create a new archetype for this opened existential type.
|
|
auto archetypeTy
|
|
= Inst->getType().getSwiftRValueType()->castTo<ArchetypeType>();
|
|
OpenedExistentialSubs[archetypeTy]
|
|
= ArchetypeType::getOpened(archetypeTy->getOpenedExistentialType());
|
|
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createOpenExistentialBox(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitDeinitExistentialAddrInst(DeinitExistentialAddrInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createDeinitExistentialAddr(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitCopyBlockInst(CopyBlockInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
Builder.createCopyBlock(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitStrongRetainInst(StrongRetainInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStrongRetain(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getAtomicity()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitFixLifetimeInst(FixLifetimeInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createFixLifetime(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitMarkDependenceInst(MarkDependenceInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createMarkDependence(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getValue()),
|
|
getOpValue(Inst->getBase())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitStrongPinInst(StrongPinInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStrongPin(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getAtomicity()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitStrongUnpinInst(StrongUnpinInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStrongUnpin(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getAtomicity()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitStrongReleaseInst(StrongReleaseInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStrongRelease(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getAtomicity()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitStrongRetainUnownedInst(StrongRetainUnownedInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStrongRetainUnowned(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getAtomicity()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitUnownedRetainInst(UnownedRetainInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUnownedRetain(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getAtomicity()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitUnownedReleaseInst(UnownedReleaseInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUnownedRelease(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->getAtomicity()));
|
|
}
|
|
template<typename ImplClass>
|
|
void SILCloner<ImplClass>::visitIsUniqueInst(IsUniqueInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createIsUnique(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitIsUniqueOrPinnedInst(IsUniqueOrPinnedInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createIsUniqueOrPinned(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitDeallocStackInst(DeallocStackInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createDeallocStack(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitDeallocRefInst(DeallocRefInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createDeallocRef(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
Inst->canAllocOnStack()));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitDeallocPartialRefInst(DeallocPartialRefInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createDeallocPartialRef(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getInstance()),
|
|
getOpValue(Inst->getMetatype())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void SILCloner<ImplClass>::visitDeallocValueBufferInst(
|
|
DeallocValueBufferInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createDeallocValueBuffer(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getValueType()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitDeallocBoxInst(DeallocBoxInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createDeallocBox(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getElementType()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitDeallocExistentialBoxInst(
|
|
DeallocExistentialBoxInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createDeallocExistentialBox(getOpLocation(Inst->getLoc()),
|
|
getOpASTType(Inst->getConcreteType()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitDestroyAddrInst(DestroyAddrInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createDestroyAddr(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void SILCloner<ImplClass>::visitProjectValueBufferInst(
|
|
ProjectValueBufferInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createProjectValueBuffer(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getValueType()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void SILCloner<ImplClass>::visitProjectBoxInst(ProjectBoxInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createProjectBox(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getValueType()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void SILCloner<ImplClass>::visitProjectExistentialBoxInst(
|
|
ProjectExistentialBoxInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createProjectExistentialBox(getOpLocation(Inst->getLoc()),
|
|
getOpType(Inst->getValueType()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitCondFailInst(CondFailInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createCondFail(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitIndexAddrInst(IndexAddrInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createIndexAddr(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getBase()),
|
|
getOpValue(Inst->getIndex())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitIndexRawPointerInst(IndexRawPointerInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createIndexRawPointer(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getBase()),
|
|
getOpValue(Inst->getIndex())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitUnreachableInst(UnreachableInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUnreachable(getOpLocation(Inst->getLoc())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitReturnInst(ReturnInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createReturn(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitThrowInst(ThrowInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createThrow(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::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<typename ImplClass>
|
|
void SILCloner<ImplClass>::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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitSwitchValueInst(SwitchValueInst *Inst) {
|
|
SILBasicBlock *DefaultBB = nullptr;
|
|
if (Inst->hasDefault())
|
|
DefaultBB = getOpBasicBlock(Inst->getDefaultBB());
|
|
SmallVector<std::pair<SILValue, SILBasicBlock*>, 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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitSwitchEnumInst(SwitchEnumInst *Inst) {
|
|
SILBasicBlock *DefaultBB = nullptr;
|
|
if (Inst->hasDefault())
|
|
DefaultBB = getOpBasicBlock(Inst->getDefaultBB());
|
|
SmallVector<std::pair<EnumElementDecl*, SILBasicBlock*>, 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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitSwitchEnumAddrInst(SwitchEnumAddrInst *Inst) {
|
|
SILBasicBlock *DefaultBB = nullptr;
|
|
if (Inst->hasDefault())
|
|
DefaultBB = getOpBasicBlock(Inst->getDefaultBB());
|
|
SmallVector<std::pair<EnumElementDecl*, SILBasicBlock*>, 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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitSelectEnumInst(SelectEnumInst *Inst) {
|
|
SILValue DefaultResult;
|
|
if (Inst->hasDefault())
|
|
DefaultResult = getOpValue(Inst->getDefaultResult());
|
|
SmallVector<std::pair<EnumElementDecl*, SILValue>, 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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitSelectEnumAddrInst(SelectEnumAddrInst *Inst) {
|
|
SILValue DefaultResult;
|
|
if (Inst->hasDefault())
|
|
DefaultResult = getOpValue(Inst->getDefaultResult());
|
|
SmallVector<std::pair<EnumElementDecl*, SILValue>, 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<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitSelectValueInst(SelectValueInst *Inst) {
|
|
SILValue DefaultResult;
|
|
if (Inst->hasDefault())
|
|
DefaultResult = getOpValue(Inst->getDefaultResult());
|
|
SmallVector<std::pair<SILValue, SILValue>, 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 <typename ImplClass>
|
|
void SILCloner<ImplClass>::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 <typename ImplClass>
|
|
void SILCloner<ImplClass>::visitProjectBlockStorageInst(
|
|
ProjectBlockStorageInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst, getBuilder().createProjectBlockStorage(
|
|
getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template <typename ImplClass>
|
|
void SILCloner<ImplClass>::visitInitBlockStorageHeaderInst(
|
|
InitBlockStorageHeaderInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst, getBuilder().createInitBlockStorageHeader(
|
|
getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getBlockStorage()),
|
|
getOpValue(Inst->getInvokeFunction()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template <typename ImplClass>
|
|
void SILCloner<ImplClass>::visitObjCMetatypeToObjectInst(
|
|
ObjCMetatypeToObjectInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst, getBuilder().createObjCMetatypeToObject(
|
|
getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template <typename ImplClass>
|
|
void SILCloner<ImplClass>::visitObjCExistentialMetatypeToObjectInst(
|
|
ObjCExistentialMetatypeToObjectInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst, getBuilder().createObjCExistentialMetatypeToObject(
|
|
getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand()),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
template <typename ImplClass>
|
|
void SILCloner<ImplClass>::visitObjCProtocolInst(ObjCProtocolInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst, getBuilder().createObjCProtocol(
|
|
getOpLocation(Inst->getLoc()), Inst->getProtocol(),
|
|
getOpType(Inst->getType())));
|
|
}
|
|
|
|
} // end namespace swift
|
|
|
|
#endif
|