mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This instruction creates a "virtual" address to represent a property with a behavior that supports definite initialization. The instruction holds references to functions that perform the initialization and 'set' logic for the property. It will be DI's job to rewrite assignments into this virtual address into calls to the initializer or setter based on the initialization state of the property at the time of assignment.
1894 lines
74 KiB
C++
1894 lines
74 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())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitReleaseValueInst(ReleaseValueInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createReleaseValue(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitAutoreleaseValueInst(AutoreleaseValueInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createAutoreleaseValue(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
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())));
|
|
}
|
|
|
|
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())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitStrongUnpinInst(StrongUnpinInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStrongUnpin(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitStrongReleaseInst(StrongReleaseInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStrongRelease(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::
|
|
visitStrongRetainUnownedInst(StrongRetainUnownedInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createStrongRetainUnowned(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitUnownedRetainInst(UnownedRetainInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUnownedRetain(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
|
|
template<typename ImplClass>
|
|
void
|
|
SILCloner<ImplClass>::visitUnownedReleaseInst(UnownedReleaseInst *Inst) {
|
|
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
|
|
doPostProcess(Inst,
|
|
getBuilder().createUnownedRelease(getOpLocation(Inst->getLoc()),
|
|
getOpValue(Inst->getOperand())));
|
|
}
|
|
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
|