Skip to content
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
17 changes: 10 additions & 7 deletions include/swift/SIL/SILFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -587,15 +587,18 @@ class SILFunction
return getLoweredFunctionType()->hasIndirectFormalResults();
}

/// Returns true if this function either has a self metadata argument or
/// object that Self metadata may be derived from.
/// Returns true if this function ie either a class method, or a
/// closure that captures the 'self' value or its metatype.
///
/// If this returns true, DynamicSelfType can be used in the body
/// of the function.
///
/// Note that this is not the same as hasSelfParam().
///
/// For closures that capture DynamicSelfType, hasSelfMetadataParam()
/// For closures that capture DynamicSelfType, hasDynamicSelfMetadata()
/// is true and hasSelfParam() is false. For methods on value types,
/// hasSelfParam() is true and hasSelfMetadataParam() is false.
bool hasSelfMetadataParam() const;
/// hasSelfParam() is true and hasDynamicSelfMetadata() is false.
bool hasDynamicSelfMetadata() const;

/// Return the mangled name of this SILFunction.
StringRef getName() const { return Name; }
Expand Down Expand Up @@ -1084,8 +1087,8 @@ class SILFunction
return getArguments().back();
}

const SILArgument *getSelfMetadataArgument() const {
assert(hasSelfMetadataParam() && "This method can only be called if the "
const SILArgument *getDynamicSelfMetadata() const {
assert(hasDynamicSelfMetadata() && "This method can only be called if the "
"SILFunction has a self-metadata parameter");
return getArguments().back();
}
Expand Down
18 changes: 9 additions & 9 deletions lib/IRGen/GenHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1733,12 +1733,12 @@ void IRGenFunction::emit##ID(llvm::Value *value, Address src) { \
#undef DEFINE_STORE_WEAK_OP
#undef NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE_HELPER

llvm::Value *IRGenFunction::getLocalSelfMetadata() {
assert(LocalSelf && "no local self metadata");
llvm::Value *IRGenFunction::getDynamicSelfMetadata() {
assert(SelfValue && "no local self metadata");

// If we already have a metatype, just return it.
if (SelfKind == SwiftMetatype)
return LocalSelf;
return SelfValue;

// We need to materialize a metatype. Emit the code for that once at the
// top of the function and cache the result.
Expand All @@ -1754,29 +1754,29 @@ llvm::Value *IRGenFunction::getLocalSelfMetadata() {
// with the correct value.

llvm::IRBuilderBase::InsertPointGuard guard(Builder);
auto insertPt = isa<llvm::Instruction>(LocalSelf)
auto insertPt = isa<llvm::Instruction>(SelfValue)
? std::next(llvm::BasicBlock::iterator(
cast<llvm::Instruction>(LocalSelf)))
cast<llvm::Instruction>(SelfValue)))
: CurFn->getEntryBlock().begin();
Builder.SetInsertPoint(&CurFn->getEntryBlock(), insertPt);

switch (SelfKind) {
case SwiftMetatype:
llvm_unreachable("Already handled");
case ObjCMetatype:
LocalSelf = emitObjCMetadataRefForMetadata(*this, LocalSelf);
SelfValue = emitObjCMetadataRefForMetadata(*this, SelfValue);
SelfKind = SwiftMetatype;
break;
case ObjectReference:
LocalSelf = emitDynamicTypeOfHeapObject(*this, LocalSelf,
SelfValue = emitDynamicTypeOfHeapObject(*this, SelfValue,
MetatypeRepresentation::Thick,
SILType::getPrimitiveObjectType(LocalSelfType),
SILType::getPrimitiveObjectType(SelfType),
/*allow artificial*/ false);
SelfKind = SwiftMetatype;
break;
}

return LocalSelf;
return SelfValue;
}

/// Given a non-tagged object pointer, load a pointer to its class object.
Expand Down
16 changes: 8 additions & 8 deletions lib/IRGen/GenType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2381,16 +2381,16 @@ unsigned IRGenModule::getBuiltinIntegerWidth(BuiltinIntegerWidth w) {
llvm_unreachable("impossible width value");
}

void IRGenFunction::setLocalSelfMetadata(CanType selfClass,
bool isExactSelfClass,
llvm::Value *value,
IRGenFunction::LocalSelfKind kind) {
assert(!LocalSelf && "already have local self metadata");
LocalSelf = value;
void IRGenFunction::setDynamicSelfMetadata(CanType selfClass,
bool isExactSelfClass,
llvm::Value *value,
IRGenFunction::DynamicSelfKind kind) {
assert(!SelfValue && "already have local self metadata");
SelfValue = value;
assert(selfClass->getClassOrBoundGenericClass()
&& "self type not a class?");
LocalSelfIsExact = isExactSelfClass;
LocalSelfType = selfClass;
SelfTypeIsExact = isExactSelfClass;
SelfType = selfClass;
SelfKind = kind;
}

Expand Down
20 changes: 10 additions & 10 deletions lib/IRGen/IRGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -643,8 +643,8 @@ class IRGenFunction {
~ConditionalDominanceScope();
};

/// The kind of value LocalSelf is.
enum LocalSelfKind {
/// The kind of value DynamicSelf is.
enum DynamicSelfKind {
/// An object reference.
ObjectReference,
/// A Swift metatype.
Expand All @@ -653,9 +653,9 @@ class IRGenFunction {
ObjCMetatype,
};

llvm::Value *getLocalSelfMetadata();
void setLocalSelfMetadata(CanType selfBaseTy, bool selfIsExact,
llvm::Value *value, LocalSelfKind kind);
llvm::Value *getDynamicSelfMetadata();
void setDynamicSelfMetadata(CanType selfBaseTy, bool selfIsExact,
llvm::Value *value, DynamicSelfKind kind);

private:
LocalTypeDataCache &getOrCreateLocalTypeData();
Expand All @@ -669,12 +669,12 @@ class IRGenFunction {
DominancePoint ActiveDominancePoint = DominancePoint::universal();
ConditionalDominanceScope *ConditionalDominance = nullptr;

/// The value that satisfies metadata lookups for dynamic Self.
llvm::Value *LocalSelf = nullptr;
/// The value that satisfies metadata lookups for DynamicSelfType.
llvm::Value *SelfValue = nullptr;
/// If set, the dynamic Self type is assumed to be equivalent to this exact class.
CanType LocalSelfType;
bool LocalSelfIsExact = false;
LocalSelfKind SelfKind;
CanType SelfType;
bool SelfTypeIsExact = false;
DynamicSelfKind SelfKind;
};

using ConditionalDominanceScope = IRGenFunction::ConditionalDominanceScope;
Expand Down
12 changes: 6 additions & 6 deletions lib/IRGen/IRGenSIL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1855,15 +1855,15 @@ static void emitEntryPointArgumentsCOrObjC(IRGenSILFunction &IGF,
}

/// Get metadata for the dynamic Self type if we have it.
static void emitLocalSelfMetadata(IRGenSILFunction &IGF) {
if (!IGF.CurSILFn->hasSelfMetadataParam())
static void emitDynamicSelfMetadata(IRGenSILFunction &IGF) {
if (!IGF.CurSILFn->hasDynamicSelfMetadata())
return;

const SILArgument *selfArg = IGF.CurSILFn->getSelfMetadataArgument();
const SILArgument *selfArg = IGF.CurSILFn->getDynamicSelfMetadata();
auto selfTy = selfArg->getType().getASTType();
CanMetatypeType metaTy =
dyn_cast<MetatypeType>(selfTy);
IRGenFunction::LocalSelfKind selfKind;
IRGenFunction::DynamicSelfKind selfKind;
if (!metaTy)
selfKind = IRGenFunction::ObjectReference;
else {
Expand All @@ -1889,7 +1889,7 @@ static void emitLocalSelfMetadata(IRGenSILFunction &IGF) {
bool isExact = selfTy->getClassOrBoundGenericClass()->isFinal()
|| IGF.CurSILFn->isExactSelfClass();

IGF.setLocalSelfMetadata(selfTy, isExact, value, selfKind);
IGF.setDynamicSelfMetadata(selfTy, isExact, value, selfKind);
}

/// Emit the definition for the given SIL constant.
Expand Down Expand Up @@ -1960,7 +1960,7 @@ void IRGenSILFunction::emitSILFunction() {
emitEntryPointArgumentsCOrObjC(*this, entry->first, params, funcTy);
break;
}
emitLocalSelfMetadata(*this);
emitDynamicSelfMetadata(*this);

assert(params.empty() && "did not map all llvm params to SIL params?!");

Expand Down
6 changes: 3 additions & 3 deletions lib/IRGen/MetadataRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1574,7 +1574,7 @@ namespace {

MetadataResponse visitDynamicSelfType(CanDynamicSelfType type,
DynamicMetadataRequest request) {
return MetadataResponse::forComplete(IGF.getLocalSelfMetadata());
return MetadataResponse::forComplete(IGF.getDynamicSelfMetadata());
}

MetadataResponse emitExistentialTypeMetadata(CanType type,
Expand Down Expand Up @@ -2751,8 +2751,8 @@ IRGenFunction::emitTypeMetadataRef(CanType type,

// If we're asking for the metadata of the type that dynamic Self is known
// to be equal to, we can just use the self metadata.
if (LocalSelfIsExact && LocalSelfType == type) {
return MetadataResponse::forComplete(getLocalSelfMetadata());
if (SelfTypeIsExact && SelfType == type) {
return MetadataResponse::forComplete(getDynamicSelfMetadata());
}

if (type->hasArchetype() ||
Expand Down
2 changes: 1 addition & 1 deletion lib/SIL/IR/SILFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -571,7 +571,7 @@ void SILFunction::viewCFGOnly() const {
}


bool SILFunction::hasSelfMetadataParam() const {
bool SILFunction::hasDynamicSelfMetadata() const {
auto paramTypes =
getConventions().getParameterSILTypes(TypeExpansionContext::minimal());
if (paramTypes.empty())
Expand Down
2 changes: 1 addition & 1 deletion lib/SIL/IR/SILInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static void buildTypeDependentOperands(
TypeDependentOperands.push_back(Def);
}
if (hasDynamicSelf)
TypeDependentOperands.push_back(F.getSelfMetadataArgument());
TypeDependentOperands.push_back(F.getDynamicSelfMetadata());
}

// Collects all opened archetypes from a type and a substitutions list and form
Expand Down
10 changes: 5 additions & 5 deletions lib/SIL/Verifier/SILVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1391,9 +1391,9 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
if (isa<SILArgument>(V)) {
require(hasDynamicSelf,
"dynamic self operand without dynamic self type");
require(AI->getFunction()->hasSelfMetadataParam(),
require(AI->getFunction()->hasDynamicSelfMetadata(),
"self metadata operand in function without self metadata param");
require((ValueBase *)V == AI->getFunction()->getSelfMetadataArgument(),
require((ValueBase *)V == AI->getFunction()->getDynamicSelfMetadata(),
"wrong self metadata operand");
} else {
require(isa<SingleValueInstruction>(V),
Expand Down Expand Up @@ -3615,10 +3615,10 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
require(Def, "Opened archetype should be registered in SILFunction");
} else if (t->hasDynamicSelfType()) {
require(I->getFunction()->hasSelfParam() ||
I->getFunction()->hasSelfMetadataParam(),
I->getFunction()->hasDynamicSelfMetadata(),
"Function containing dynamic self type must have self parameter");
if (I->getFunction()->hasSelfMetadataParam())
Def = I->getFunction()->getArguments().back();
if (I->getFunction()->hasDynamicSelfMetadata())
Def = I->getFunction()->getDynamicSelfMetadata();
else
Def = I->getFunction()->getSelfArgument();
} else {
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenPoly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3204,7 +3204,7 @@ CanSILFunctionType SILGenFunction::buildThunkType(
// If this thunk involves DynamicSelfType in any way, add a capture for it
// in case we need to recover metadata.
if (hasDynamicSelf) {
dynamicSelfType = F.getSelfMetadataArgument()->getType().getASTType();
dynamicSelfType = F.getDynamicSelfMetadata()->getType().getASTType();
if (!isa<MetatypeType>(dynamicSelfType)) {
dynamicSelfType = CanMetatypeType::get(dynamicSelfType,
MetatypeRepresentation::Thick);
Expand Down
4 changes: 4 additions & 0 deletions lib/SILOptimizer/Mandatory/DIMemoryUseCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1409,6 +1409,10 @@ collectDelegatingInitUses(const DIMemoryObjectInfo &TheMemory,
Kind = DIUseKind::LoadForTypeOfSelf;
}
}
// value_metatype may also use the 'self' value directly, if it has an
// address-only type.
if (isa<ValueMetatypeInst>(User))
Kind = DIUseKind::TypeOfSelf;

// We can safely handle anything else as an escape. They should all happen
// after self.init is invoked.
Expand Down
3 changes: 3 additions & 0 deletions lib/SILOptimizer/Mandatory/DIMemoryUseCollector.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,9 @@ enum DIUseKind {
/// This instruction is a load that's only used to answer a `type(of: self)`
/// question.
LoadForTypeOfSelf,

/// This instruction is a value_metatype on the address of 'self'.
TypeOfSelf
};

/// This struct represents a single classified access to the memory object
Expand Down
Loading