Skip to content

Track dependencies of SIL instructions on opened archetypes which they use. #2928

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 68 additions & 30 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "swift/SIL/SILDebugScope.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILModule.h"
#include "swift/SIL/SILOpenedArchetypesTracker.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/StringExtras.h"

Expand All @@ -40,6 +41,16 @@ class SILBuilder {
/// recorded in this list.
SmallVectorImpl<SILInstruction *> *InsertedInstrs = nullptr;

/// An immutable view on the set of available opened archetypes.
/// It is passed down to SILInstruction constructors and create
/// methods.
SILOpenedArchetypesState OpenedArchetypes;

/// Maps opened archetypes to their definitions. If provided,
/// can be used by the builder. It is supposed to be used
/// only by SILGen or SIL deserializers.
SILOpenedArchetypesTracker *OpenedArchetypesTracker = nullptr;

public:
SILBuilder(SILFunction &F) : F(F), BB(0) {}

Expand Down Expand Up @@ -75,6 +86,19 @@ class SILBuilder {
return F.getModule().getTypeLowering(T);
}

void setOpenedArchetypesTracker(SILOpenedArchetypesTracker *Tracker) {
this->OpenedArchetypesTracker = Tracker;
this->OpenedArchetypes.setOpenedArchetypesTracker(OpenedArchetypesTracker);
}

SILOpenedArchetypesTracker *getOpenedArchetypesTracker() const {
return OpenedArchetypesTracker;
}

SILOpenedArchetypesState &getOpenedArchetypes() {
return OpenedArchetypes;
}

void setCurrentDebugScope(const SILDebugScope *DS) { CurDebugScope = DS; }
const SILDebugScope *getCurrentDebugScope() const { return CurDebugScope; }

Expand Down Expand Up @@ -261,7 +285,8 @@ class SILBuilder {
SILType Result, ArrayRef<Substitution> Subs,
ArrayRef<SILValue> Args, bool isNonThrowing) {
return insert(ApplyInst::create(getSILDebugLocation(Loc), Fn, SubstFnTy,
Result, Subs, Args, isNonThrowing, F));
Result, Subs, Args, isNonThrowing, F,
OpenedArchetypes));
}

ApplyInst *createApply(SILLocation Loc, SILValue Fn, ArrayRef<SILValue> Args,
Expand All @@ -278,16 +303,18 @@ class SILBuilder {
SILBasicBlock *errorBB) {
return insertTerminator(TryApplyInst::create(getSILDebugLocation(Loc),
fn, substFnTy, subs, args,
normalBB, errorBB, F));
normalBB, errorBB, F,
OpenedArchetypes));
}

PartialApplyInst *createPartialApply(SILLocation Loc, SILValue Fn,
SILType SubstFnTy,
ArrayRef<Substitution> Subs,
ArrayRef<SILValue> Args,
SILType ClosureTy) {
return insert(PartialApplyInst::create(
getSILDebugLocation(Loc), Fn, SubstFnTy, Subs, Args, ClosureTy, F));
return insert(PartialApplyInst::create(getSILDebugLocation(Loc), Fn,
SubstFnTy, Subs, Args, ClosureTy, F,
OpenedArchetypes));
}

BuiltinInst *createBuiltin(SILLocation Loc, Identifier Name, SILType ResultTy,
Expand Down Expand Up @@ -526,8 +553,8 @@ class SILBuilder {

UncheckedRefCastInst *createUncheckedRefCast(SILLocation Loc, SILValue Op,
SILType Ty) {
return insert(new (F.getModule()) UncheckedRefCastInst(
getSILDebugLocation(Loc), Op, Ty));
return insert(UncheckedRefCastInst::create(getSILDebugLocation(Loc), Op, Ty,
F, OpenedArchetypes));
}

UncheckedRefCastAddrInst *
Expand All @@ -539,20 +566,20 @@ class SILBuilder {

UncheckedAddrCastInst *createUncheckedAddrCast(SILLocation Loc, SILValue Op,
SILType Ty) {
return insert(new (F.getModule()) UncheckedAddrCastInst(
getSILDebugLocation(Loc), Op, Ty));
return insert(UncheckedAddrCastInst::create(getSILDebugLocation(Loc), Op,
Ty, F, OpenedArchetypes));
}

UncheckedTrivialBitCastInst *
createUncheckedTrivialBitCast(SILLocation Loc, SILValue Op, SILType Ty) {
return insert(new (F.getModule()) UncheckedTrivialBitCastInst(
getSILDebugLocation(Loc), Op, Ty));
return insert(UncheckedTrivialBitCastInst::create(
getSILDebugLocation(Loc), Op, Ty, F, OpenedArchetypes));
}

UncheckedBitwiseCastInst *
createUncheckedBitwiseCast(SILLocation Loc, SILValue Op, SILType Ty) {
return insert(new (F.getModule()) UncheckedBitwiseCastInst(
getSILDebugLocation(Loc), Op, Ty));
return insert(UncheckedBitwiseCastInst::create(getSILDebugLocation(Loc), Op,
Ty, F, OpenedArchetypes));
}

RefToBridgeObjectInst *createRefToBridgeObject(SILLocation Loc, SILValue Ref,
Expand Down Expand Up @@ -648,8 +675,8 @@ class SILBuilder {

UnconditionalCheckedCastInst *
createUnconditionalCheckedCast(SILLocation Loc, SILValue op, SILType destTy) {
return insert(new (F.getModule()) UnconditionalCheckedCastInst(
getSILDebugLocation(Loc), op, destTy));
return insert(UnconditionalCheckedCastInst::create(
getSILDebugLocation(Loc), op, destTy, F, OpenedArchetypes));
}

UnconditionalCheckedCastAddrInst *createUnconditionalCheckedCastAddr(
Expand Down Expand Up @@ -896,11 +923,10 @@ class SILBuilder {
WitnessMethodInst *createWitnessMethod(SILLocation Loc, CanType LookupTy,
ProtocolConformanceRef Conformance,
SILDeclRef Member, SILType MethodTy,
SILValue OptionalOpenedExistential,
bool Volatile = false) {
return insert(WitnessMethodInst::create(
getSILDebugLocation(Loc), LookupTy, Conformance, Member, MethodTy,
&F, OptionalOpenedExistential, Volatile));
&F, OpenedArchetypes, Volatile));
}

DynamicMethodInst *createDynamicMethod(SILLocation Loc, SILValue Operand,
Expand All @@ -912,27 +938,39 @@ class SILBuilder {

OpenExistentialAddrInst *
createOpenExistentialAddr(SILLocation Loc, SILValue Operand, SILType SelfTy) {
return insert(new (F.getModule()) OpenExistentialAddrInst(
auto *I = insert(new (F.getModule()) OpenExistentialAddrInst(
getSILDebugLocation(Loc), Operand, SelfTy));
if (OpenedArchetypesTracker)
OpenedArchetypesTracker->registerOpenedArchetypes(I);
return I;
}

OpenExistentialMetatypeInst *createOpenExistentialMetatype(SILLocation Loc,
SILValue operand,
SILType selfTy) {
return insert(new (F.getModule()) OpenExistentialMetatypeInst(
auto *I = insert(new (F.getModule()) OpenExistentialMetatypeInst(
getSILDebugLocation(Loc), operand, selfTy));
if (OpenedArchetypesTracker)
OpenedArchetypesTracker->registerOpenedArchetypes(I);
return I;
}

OpenExistentialRefInst *
createOpenExistentialRef(SILLocation Loc, SILValue Operand, SILType Ty) {
return insert(new (F.getModule()) OpenExistentialRefInst(
auto *I = insert(new (F.getModule()) OpenExistentialRefInst(
getSILDebugLocation(Loc), Operand, Ty));
if (OpenedArchetypesTracker)
OpenedArchetypesTracker->registerOpenedArchetypes(I);
return I;
}

OpenExistentialBoxInst *
createOpenExistentialBox(SILLocation Loc, SILValue Operand, SILType Ty) {
return insert(new (F.getModule()) OpenExistentialBoxInst(
auto *I = insert(new (F.getModule()) OpenExistentialBoxInst(
getSILDebugLocation(Loc), Operand, Ty));
if (OpenedArchetypesTracker)
OpenedArchetypesTracker->registerOpenedArchetypes(I);
return I;
}

InitExistentialAddrInst *
Expand All @@ -942,25 +980,25 @@ class SILBuilder {
ArrayRef<ProtocolConformanceRef> Conformances) {
return insert(InitExistentialAddrInst::create(
getSILDebugLocation(Loc), Existential, FormalConcreteType,
LoweredConcreteType, Conformances, &F));
LoweredConcreteType, Conformances, &F, OpenedArchetypes));
}

InitExistentialMetatypeInst *
createInitExistentialMetatype(SILLocation Loc, SILValue metatype,
SILType existentialType,
ArrayRef<ProtocolConformanceRef> conformances) {
return insert(InitExistentialMetatypeInst::create(
getSILDebugLocation(Loc), existentialType, metatype, conformances,
&F));
getSILDebugLocation(Loc), existentialType, metatype, conformances, &F,
OpenedArchetypes));
}

InitExistentialRefInst *
createInitExistentialRef(SILLocation Loc, SILType ExistentialType,
CanType FormalConcreteType, SILValue Concrete,
ArrayRef<ProtocolConformanceRef> Conformances) {
return insert(InitExistentialRefInst::create(
getSILDebugLocation(Loc), ExistentialType, FormalConcreteType,
Concrete, Conformances, &F));
getSILDebugLocation(Loc), ExistentialType, FormalConcreteType, Concrete,
Conformances, &F, OpenedArchetypes));
}

DeinitExistentialAddrInst *createDeinitExistentialAddr(SILLocation Loc,
Expand Down Expand Up @@ -992,8 +1030,8 @@ class SILBuilder {
}

MetatypeInst *createMetatype(SILLocation Loc, SILType Metatype) {
return insert(new (F.getModule())
MetatypeInst(getSILDebugLocation(Loc), Metatype));
return insert(MetatypeInst::create(getSILDebugLocation(Loc), Metatype,
&F, OpenedArchetypes));
}

ObjCMetatypeToObjectInst *
Expand Down Expand Up @@ -1306,9 +1344,9 @@ class SILBuilder {
SILValue op, SILType destTy,
SILBasicBlock *successBB,
SILBasicBlock *failureBB) {
return insertTerminator(new (F.getModule()) CheckedCastBranchInst(
getSILDebugLocation(Loc), isExact, op, destTy, successBB,
failureBB));
return insertTerminator(CheckedCastBranchInst::create(
getSILDebugLocation(Loc), isExact, op, destTy, successBB, failureBB, F,
OpenedArchetypes));
}

CheckedCastAddrBranchInst *
Expand Down
62 changes: 54 additions & 8 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifndef SWIFT_SIL_SILCLONER_H
#define SWIFT_SIL_SILCLONER_H

#include "swift/SIL/SILOpenedArchetypesTracker.h"
#include "swift/SIL/SILBuilder.h"
#include "swift/SIL/SILDebugScope.h"
#include "swift/SIL/SILVisitor.h"
Expand All @@ -39,9 +40,19 @@ class SILCloner : protected SILVisitor<ImplClass> {
public:
using SILVisitor<ImplClass>::asImpl;

explicit SILCloner(SILFunction &F,
SILOpenedArchetypesTracker &OpenedArchetypesTracker)
: Builder(F), InsertBeforeBB(nullptr),
OpenedArchetypesTracker(OpenedArchetypesTracker) {
Builder.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
}

explicit SILCloner(SILFunction &F)
: Builder(F), InsertBeforeBB(nullptr) { }

: Builder(F), InsertBeforeBB(nullptr),
OpenedArchetypesTracker(F) {
Builder.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
}

/// Clients of SILCloner who want to know about any newly created
/// instructions can install a SmallVector into the builder to collect them.
void setTrackingList(SmallVectorImpl<SILInstruction*> *II) {
Expand Down Expand Up @@ -199,6 +210,14 @@ class SILCloner : protected SILVisitor<ImplClass> {
void cleanUp(SILFunction *F);

public:
void doPreProcess(SILInstruction *Orig) {
// Extend the set of available opened archetypes by the opened archetypes
// used by the instruction being cloned.
auto OpenedArchetypeOperands = Orig->getOpenedArchetypeOperands();
Builder.getOpenedArchetypes().addOpenedArchetypeOperands(
OpenedArchetypeOperands);
}

void doPostProcess(SILInstruction *Orig, SILInstruction *Cloned) {
asImpl().postProcess(Orig, Cloned);
assert((Orig->getDebugScope() ? Cloned->getDebugScope()!=nullptr : true) &&
Expand All @@ -217,6 +236,8 @@ class SILCloner : protected SILVisitor<ImplClass> {
llvm::MapVector<SILBasicBlock*, SILBasicBlock*> BBMap;

TypeSubstitutionMap OpenedExistentialSubs;
SILOpenedArchetypesTracker OpenedArchetypesTracker;

/// Set of basic blocks where unreachable was inserted.
SmallPtrSet<SILBasicBlock *, 32> BlocksWithUnreachables;
};
Expand Down Expand Up @@ -253,8 +274,27 @@ template<typename ImplClass>
class SILClonerWithScopes : public SILCloner<ImplClass> {
friend class SILCloner<ImplClass>;
public:
SILClonerWithScopes(SILFunction &To, bool Disable = false)
: SILCloner<ImplClass>(To) {
SILClonerWithScopes(SILFunction &To,
SILOpenedArchetypesTracker &OpenedArchetypesTracker,
bool Disable = false)
: SILCloner<ImplClass>(To, OpenedArchetypesTracker) {

// We only want to do this when we generate cloned functions, not
// when we inline.

// FIXME: This is due to having TypeSubstCloner inherit from
// SILClonerWithScopes, and having TypeSubstCloner be used
// both by passes that clone whole functions and ones that
// inline functions.
if (Disable)
return;

scopeCloner.reset(new ScopeCloner(To));
}

SILClonerWithScopes(SILFunction &To,
bool Disable = false)
: SILCloner<ImplClass>(To) {

// We only want to do this when we generate cloned functions, not
// when we inline.
Expand All @@ -269,6 +309,7 @@ class SILClonerWithScopes : public SILCloner<ImplClass> {
scopeCloner.reset(new ScopeCloner(To));
}


private:
std::unique_ptr<ScopeCloner> scopeCloner;
protected:
Expand Down Expand Up @@ -333,8 +374,12 @@ 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)
for (auto I = BB->begin(), E = --BB->end(); I != E; ++I) {
// Update the set of available opened archetypes with the opned archetypes
// used by the current instruction.
doPreProcess(&*I);
asImpl().visit(&*I);
}
// Iterate over successors to do the depth-first search.
for (auto &Succ : BB->getSuccessors()) {
auto BBI = BBMap.find(Succ);
Expand Down Expand Up @@ -1251,16 +1296,17 @@ template<typename ImplClass>
void
SILCloner<ImplClass>::visitWitnessMethodInst(WitnessMethodInst *Inst) {
auto conformance =
getOpConformance(Inst->getLookupType(), Inst->getConformance());
getOpConformance(Inst->getLookupType(), Inst->getConformance());
auto lookupType = Inst->getLookupType();
auto newLookupType = getOpASTType(lookupType);
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
doPostProcess(
Inst,
getBuilder()
.createWitnessMethod(
getOpLocation(Inst->getLoc()),
getOpASTType(Inst->getLookupType()), conformance,
newLookupType, conformance,
Inst->getMember(), getOpType(Inst->getType()),
Inst->hasOperand() ? getOpValue(Inst->getOperand()) : SILValue(),
Inst->isVolatile()));
}

Expand Down
Loading