Skip to content

Cherry pick some fixes to qualification branch #22819

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
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
10 changes: 7 additions & 3 deletions include/swift/Remote/MetadataReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ class MetadataReader {
StoredPointer TaggedPointerExtendedSlotShift;
StoredPointer TaggedPointerExtendedSlotMask;
StoredPointer TaggedPointerExtendedClasses;
StoredPointer TaggedPointerObfuscator;

Demangle::NodeFactory Factory;

Expand Down Expand Up @@ -744,7 +745,7 @@ class MetadataReader {
if (getTaggedPointerEncoding() != TaggedPointerEncodingKind::Extended)
return false;

return objectAddress & TaggedPointerMask;
return (objectAddress ^ TaggedPointerObfuscator) & TaggedPointerMask;
}

/// Read the isa pointer of an Object-C tagged pointer value.
Expand All @@ -761,8 +762,8 @@ class MetadataReader {

// Extended pointers have a tag of 0b111, using 8 additional bits
// to specify the class.
if (TaggedPointerExtendedMask != 0 &&
((objectAddress & TaggedPointerExtendedMask)
if (TaggedPointerExtendedMask != 0 &&
(((objectAddress ^ TaggedPointerObfuscator) & TaggedPointerExtendedMask)
== TaggedPointerExtendedMask)) {
auto tag = ((objectAddress >> TaggedPointerExtendedSlotShift) &
TaggedPointerExtendedSlotMask);
Expand Down Expand Up @@ -2469,6 +2470,9 @@ class MetadataReader {
TaggedPointerExtendedClasses =
TaggedPointerExtendedClassesAddr.getAddressData();

tryFindAndReadSymbol(TaggedPointerObfuscator,
"objc_debug_taggedpointer_obfuscator");

# undef tryFindSymbol
# undef tryReadSymbol
# undef tryFindAndReadSymbol
Expand Down
16 changes: 11 additions & 5 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -2125,12 +2125,18 @@ class SILBuilder {
}

bool isLoadableOrOpaque(SILType Ty) {
if (!F) {
// We are inserting into the static initializer of a SILGlobalVariable.
// All types used there are loadable by definition.
auto &M = C.Module;

if (!SILModuleConventions(M).useLoweredAddresses())
return true;
}
return Ty.isLoadableOrOpaque(F);

auto expansion = ResilienceExpansion::Maximal;
// If there's no current SILFunction, we're inserting into a global
// variable initializer.
if (F)
expansion = F->getResilienceExpansion();

return M.getTypeLowering(Ty, expansion).isLoadable();
}

void appendOperandTypeName(SILType OpdTy, llvm::SmallString<16> &Name) {
Expand Down
66 changes: 24 additions & 42 deletions include/swift/SIL/TypeLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,23 +306,6 @@ class TypeLowering {
return Properties.isResilient();
}

/// Return the semantic type.
///
/// The semantic type is what a type pretends to be during
/// type-checking: that is, the type that getTypeOfRValue would
/// return on a variable of this type.
SILType getSemanticType() const {
// If you change this, change getSemanticTypeLowering() too.
auto storageType = getLoweredType().getASTType();
if (auto refType = dyn_cast<ReferenceStorageType>(storageType))
return SILType::getPrimitiveType(refType.getReferentType(),
SILValueCategory::Object);
return getLoweredType();
}

/// Return the lowering for the semantic type.
inline const TypeLowering &getSemanticTypeLowering(TypeConverter &TC) const;

/// Produce an exact copy of the value in the given address as a
/// scalar. The caller is responsible for destroying this value,
/// e.g. by releasing it.
Expand Down Expand Up @@ -582,13 +565,6 @@ class TypeConverter {

llvm::BumpPtrAllocator IndependentBPA;

enum : unsigned {
/// There is a unique entry with this uncurry level in the
/// type-lowering map for every TLI we create. The map has the
/// responsibility to call the destructor for these entries.
UniqueLoweringEntry = ~0U
};

struct CachingTypeKey {
GenericSignature *Sig;
AbstractionPattern::CachingKey OrigType;
Expand Down Expand Up @@ -700,8 +676,16 @@ class TypeConverter {
#include "swift/SIL/BridgedTypes.def"

const TypeLowering &
getTypeLoweringForLoweredType(TypeKey key, ResilienceExpansion forExpansion);
const TypeLowering &getTypeLoweringForUncachedLoweredType(TypeKey key);
getTypeLoweringForLoweredType(TypeKey key,
ResilienceExpansion forExpansion);
const TypeLowering &
getTypeLoweringForUncachedLoweredType(TypeKey key,
ResilienceExpansion forExpansion);

const TypeLowering &
getTypeLoweringForExpansion(TypeKey key,
ResilienceExpansion forExpansion,
const TypeLowering *lowering);

public:
SILModule &M;
Expand Down Expand Up @@ -763,15 +747,19 @@ class TypeConverter {

/// Lowers a Swift type to a SILType, and returns the SIL TypeLowering
/// for that type.
const TypeLowering &getTypeLowering(Type t) {
const TypeLowering &
getTypeLowering(Type t, ResilienceExpansion forExpansion =
ResilienceExpansion::Minimal) {
AbstractionPattern pattern(getCurGenericContext(), t->getCanonicalType());
return getTypeLowering(pattern, t);
return getTypeLowering(pattern, t, forExpansion);
}

/// Lowers a Swift type to a SILType according to the abstraction
/// patterns of the given original type.
const TypeLowering &getTypeLowering(AbstractionPattern origType,
Type substType);
Type substType,
ResilienceExpansion forExpansion =
ResilienceExpansion::Minimal);

/// Returns the SIL TypeLowering for an already lowered SILType. If the
/// SILType is an address, returns the TypeLowering for the pointed-to
Expand All @@ -782,16 +770,19 @@ class TypeConverter {

// Returns the lowered SIL type for a Swift type.
SILType getLoweredType(Type t) {
return getTypeLowering(t).getLoweredType();
return getTypeLowering(t, ResilienceExpansion::Minimal).getLoweredType();
}

// Returns the lowered SIL type for a Swift type.
SILType getLoweredType(AbstractionPattern origType, Type substType) {
return getTypeLowering(origType, substType).getLoweredType();
return getTypeLowering(origType, substType, ResilienceExpansion::Minimal)
.getLoweredType();
}

SILType getLoweredLoadableType(Type t) {
const TypeLowering &ti = getTypeLowering(t);
SILType getLoweredLoadableType(Type t,
ResilienceExpansion forExpansion =
ResilienceExpansion::Minimal) {
const TypeLowering &ti = getTypeLowering(t, forExpansion);
assert(
(ti.isLoadable() || !SILModuleConventions(M).useLoweredAddresses()) &&
"unexpected address-only type");
Expand Down Expand Up @@ -1033,15 +1024,6 @@ class TypeConverter {
bool suppressOptional);
};

inline const TypeLowering &
TypeLowering::getSemanticTypeLowering(TypeConverter &TC) const {
// If you change this, change getSemanticType() too.
auto storageType = getLoweredType().getASTType();
if (auto refType = dyn_cast<ReferenceStorageType>(storageType))
return TC.getTypeLowering(refType.getReferentType());
return *this;
}

/// RAII interface to push a generic context.
class GenericContextScope {
TypeConverter &TC;
Expand Down
6 changes: 4 additions & 2 deletions include/swift/SILOptimizer/Utils/Local.h
Original file line number Diff line number Diff line change
Expand Up @@ -535,13 +535,15 @@ bool isSimpleType(SILType SILTy, SILModule& Module);
bool analyzeStaticInitializer(SILValue V,
SmallVectorImpl<SILInstruction *> &Insns);

/// Returns true if the below operation will succeed.
bool canReplaceLoadSequence(SILInstruction *I);

/// Replace load sequence which may contain
/// a chain of struct_element_addr followed by a load.
/// The sequence is traversed inside out, i.e.
/// starting with the innermost struct_element_addr
void replaceLoadSequence(SILInstruction *I,
SILValue Value,
SILBuilder &B);
SILValue Value);


/// Do we have enough information to determine all callees that could
Expand Down
42 changes: 29 additions & 13 deletions lib/IRGen/GenProto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -948,23 +948,35 @@ namespace {

/// Return true if the witness table requires runtime instantiation to
/// handle resiliently-added requirements with default implementations.
static bool isResilientConformance(const NormalProtocolConformance *conformance) {
bool IRGenModule::isResilientConformance(
const NormalProtocolConformance *conformance) {
// If the protocol is not resilient, the conformance is not resilient
// either.
if (!conformance->getProtocol()->isResilient())
return false;

// If the protocol is in the same module as the conformance, we're
// not resilient.
if (conformance->getDeclContext()->getParentModule()
== conformance->getProtocol()->getParentModule())
auto *conformanceModule = conformance->getDeclContext()->getParentModule();

// If the protocol and the conformance are both in the current module,
// they're not resilient.
if (conformanceModule == getSwiftModule() &&
conformanceModule == conformance->getProtocol()->getParentModule())
return false;

// If the protocol and the conformance are in the same module and the
// conforming type is not generic, they're not resilient.
//
// This is an optimization -- a conformance of a non-generic type cannot
// resiliently become dependent.
if (!conformance->getDeclContext()->isGenericContext() &&
conformanceModule == conformance->getProtocol()->getParentModule())
return false;

// We have a resilient conformance.
return true;
}

static bool isResilientConformance(const RootProtocolConformance *root) {
bool IRGenModule::isResilientConformance(const RootProtocolConformance *root) {
if (auto normal = dyn_cast<NormalProtocolConformance>(root))
return isResilientConformance(normal);
// Self-conformances never require this.
Expand Down Expand Up @@ -997,6 +1009,7 @@ static bool hasDependentTypeWitness(
}

static bool isDependentConformance(
IRGenModule &IGM,
const RootProtocolConformance *rootConformance,
bool considerResilience,
llvm::SmallPtrSet<const NormalProtocolConformance *, 4> &visited){
Expand All @@ -1011,7 +1024,7 @@ static bool isDependentConformance(
return false;

// If the conformance is resilient, this is always true.
if (considerResilience && isResilientConformance(conformance))
if (considerResilience && IGM.isResilientConformance(conformance))
return true;

// Check whether any of the conformances are dependent.
Expand All @@ -1027,7 +1040,8 @@ static bool isDependentConformance(
auto assocConformance =
conformance->getAssociatedConformance(req.getFirstType(), assocProtocol);
if (assocConformance.isAbstract() ||
isDependentConformance(assocConformance.getConcrete()
isDependentConformance(IGM,
assocConformance.getConcrete()
->getRootConformance(),
considerResilience,
visited))
Expand All @@ -1045,10 +1059,12 @@ static bool isDependentConformance(

/// Is there anything about the given conformance that requires witness
/// tables to be dependently-generated?
static bool isDependentConformance(const RootProtocolConformance *conformance,
bool considerResilience) {
bool IRGenModule::isDependentConformance(
const RootProtocolConformance *conformance,
bool considerResilience) {
llvm::SmallPtrSet<const NormalProtocolConformance *, 4> visited;
return ::isDependentConformance(conformance, considerResilience, visited);
return ::isDependentConformance(*this, conformance, considerResilience,
visited);
}

static bool isSynthesizedNonUnique(const RootProtocolConformance *conformance) {
Expand Down Expand Up @@ -1286,7 +1302,7 @@ class AccessorConformanceInfo : public ConformanceInfo {
Conformance.getDeclContext())),
SILEntries(SILWT->getEntries()),
SILConditionalConformances(SILWT->getConditionalConformances()),
ResilientConformance(isResilientConformance(&Conformance)),
ResilientConformance(IGM.isResilientConformance(&Conformance)),
PI(IGM.getProtocolInfo(SILWT->getConformance()->getProtocol(),
(ResilientConformance
? ProtocolInfoKind::RequirementSignature
Expand Down Expand Up @@ -2086,7 +2102,7 @@ void IRGenerator::ensureRelativeSymbolCollocation(SILWitnessTable &wt) {

// Only resilient conformances use relative pointers for witness methods.
if (wt.isDeclaration() || isAvailableExternally(wt.getLinkage()) ||
!isResilientConformance(wt.getConformance()))
!CurrentIGM->isResilientConformance(wt.getConformance()))
return;

for (auto &entry : wt.getEntries()) {
Expand Down
5 changes: 5 additions & 0 deletions lib/IRGen/IRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,11 @@ class IRGenModule {
ResilienceExpansion getResilienceExpansionForLayout(NominalTypeDecl *decl);
ResilienceExpansion getResilienceExpansionForLayout(SILGlobalVariable *var);

bool isResilientConformance(const NormalProtocolConformance *conformance);
bool isResilientConformance(const RootProtocolConformance *root);
bool isDependentConformance(const RootProtocolConformance *conformance,
bool considerResilience);

Alignment getCappedAlignment(Alignment alignment);

SpareBitVector getSpareBitsForType(llvm::Type *scalarTy, Size size);
Expand Down
13 changes: 4 additions & 9 deletions lib/SIL/SILWitnessTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@
//
// This file defines the SILWitnessTable class, which is used to map a protocol
// conformance for a type to its implementing SILFunctions. This information is
// (FIXME will be) used by IRGen to create witness tables for protocol dispatch.
// used by IRGen to create witness tables for protocol dispatch.
//
// It can also be used by generic specialization and existential
// devirtualization passes to promote witness_method and protocol_method
// instructions to static function_refs.
// devirtualization passes to promote witness_method instructions to static
// function_refs.
//
//===----------------------------------------------------------------------===//

Expand All @@ -24,7 +25,6 @@
#include "swift/AST/ASTMangler.h"
#include "swift/AST/Module.h"
#include "swift/AST/ProtocolConformance.h"
#include "swift/ClangImporter/ClangModule.h"
#include "swift/SIL/SILModule.h"
#include "llvm/ADT/SmallString.h"

Expand Down Expand Up @@ -172,11 +172,6 @@ bool SILWitnessTable::conformanceIsSerialized(
if (normalConformance && normalConformance->isResilient())
return false;

// Serialize witness tables for conformances synthesized by
// the ClangImporter.
if (isa<ClangModuleUnit>(conformance->getDeclContext()->getModuleScopeContext()))
return true;

if (conformance->getProtocol()->getEffectiveAccess() < AccessLevel::Public)
return false;

Expand Down
Loading