Skip to content

Revert "Generic metadata prespecialization, part 1" #29145

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

Closed
Closed
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
32 changes: 1 addition & 31 deletions include/swift/ABI/Metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -697,8 +697,6 @@ struct TargetMetadata {

bool satisfiesClassConstraint() const;

bool isCanonicalStaticallySpecializedGenericMetadata() const;

#if SWIFT_OBJC_INTEROP
/// Get the ObjC class object for this type if it has one, or return null if
/// the type is not a class (or not a class with a class object).
Expand Down Expand Up @@ -1350,34 +1348,6 @@ struct TargetStructMetadata : public TargetValueMetadata<Runtime> {
return reinterpret_cast<const uint32_t *>(asWords + offset);
}

bool isCanonicalStaticallySpecializedGenericMetadata() const {
auto *description = getDescription();
if (!description->isGeneric())
return false;

auto *trailingFlags = getTrailingFlags();
if (trailingFlags == nullptr)
return false;

return trailingFlags->isCanonicalStaticSpecialization();
}

const MetadataTrailingFlags *getTrailingFlags() const {
auto description = getDescription();
auto flags = description->getFullGenericContextHeader()
.DefaultInstantiationPattern->PatternFlags;
if (!flags.hasTrailingFlags())
return nullptr;
auto fieldOffset = description->FieldOffsetVectorOffset;
auto offset =
fieldOffset +
// Pad to the nearest pointer.
((description->NumFields * sizeof(uint32_t) + sizeof(void *) - 1) /
sizeof(void *));
auto asWords = reinterpret_cast<const void *const *>(this);
return reinterpret_cast<const MetadataTrailingFlags *>(asWords + offset);
}

static constexpr int32_t getGenericArgumentOffset() {
return sizeof(TargetStructMetadata<Runtime>) / sizeof(StoredPointer);
}
Expand Down Expand Up @@ -3605,7 +3575,7 @@ struct TargetSingletonMetadataInitialization {
}

/// This method can only be called from the runtime itself. It is defined
/// in Metadata.cpp.
/// in MetadataCache.h.
TargetMetadata<Runtime> *allocate(
const TargetTypeContextDescriptor<Runtime> *description) const;
};
Expand Down
32 changes: 0 additions & 32 deletions include/swift/ABI/MetadataValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -1511,10 +1511,6 @@ class GenericMetadataPatternFlags : public FlagSet<uint32_t> {
/// Does this pattern have an extra-data pattern?
HasExtraDataPattern = 0,

/// Do instances of this pattern have a bitset of flags that occur at the
/// end of the metadata, after the extra data if there is any?
HasTrailingFlags = 1,

// Class-specific flags.

/// Does this pattern have an immediate-members pattern?
Expand All @@ -1539,10 +1535,6 @@ class GenericMetadataPatternFlags : public FlagSet<uint32_t> {
hasExtraDataPattern,
setHasExtraDataPattern)

FLAGSET_DEFINE_FLAG_ACCESSORS(HasTrailingFlags,
hasTrailingFlags,
setHasTrailingFlags)

FLAGSET_DEFINE_FIELD_ACCESSORS(Value_MetadataKind,
Value_MetadataKind_width,
MetadataKind,
Expand Down Expand Up @@ -1675,30 +1667,6 @@ class MetadataRequest : public FlagSet<size_t> {
}
};

struct MetadataTrailingFlags : public FlagSet<uint64_t> {
enum {
/// Whether this metadata is a specialization of a generic metadata pattern
/// which was created during compilation.
IsStaticSpecialization = 0,

/// Whether this metadata is a specialization of a generic metadata pattern
/// which was created during compilation and made to be canonical by
/// modifying the metadata accessor.
IsCanonicalStaticSpecialization = 1,
};

explicit MetadataTrailingFlags(uint64_t bits) : FlagSet(bits) {}
constexpr MetadataTrailingFlags() {}

FLAGSET_DEFINE_FLAG_ACCESSORS(IsStaticSpecialization,
isStaticSpecialization,
setIsStaticSpecialization)

FLAGSET_DEFINE_FLAG_ACCESSORS(IsCanonicalStaticSpecialization,
isCanonicalStaticSpecialization,
setIsCanonicalStaticSpecialization)
};

/// Flags for Builtin.IntegerLiteral values.
class IntegerLiteralFlags {
public:
Expand Down
8 changes: 0 additions & 8 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -614,14 +614,6 @@ class ASTContext final {
/// swift_getTypeByMangledNameInContextInMetadataState.
AvailabilityContext getTypesInAbstractMetadataStateAvailability();

/// Get the runtime availability of support for prespecialized generic
/// metadata.
AvailabilityContext getPrespecializedGenericMetadataAvailability();

/// Get the runtime availability of features introduced in the Swift 5.2
/// compiler for the target platform.
AvailabilityContext getSwift52Availability();


//===--------------------------------------------------------------------===//
// Diagnostics Helper functions
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2864,7 +2864,7 @@ class GenericTypeDecl : public GenericContext, public TypeDecl {
/// code. One is formed implicitly when a declaration is written with an opaque
/// result type, as in:
///
/// func foo() -> some SignedInteger { return 1 }
/// func foo() -> opaque SignedInteger { return 1 }
///
/// The declared type is a special kind of ArchetypeType representing the
/// abstracted underlying type.
Expand Down
9 changes: 2 additions & 7 deletions include/swift/AST/IRGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,6 @@ class IRGenOptions {
/// Passing this flag completely disables this behavior.
unsigned DisableLegacyTypeInfo : 1;

/// Create metadata specializations for generic types at statically known type
/// arguments.
unsigned PrespecializeGenericMetadata : 1;

/// The path to load legacy type layouts from.
StringRef ReadLegacyTypeInfoPath;

Expand Down Expand Up @@ -259,9 +255,8 @@ class IRGenOptions {
EnableAnonymousContextMangledNames(false), ForcePublicLinkage(false),
LazyInitializeClassMetadata(false),
LazyInitializeProtocolConformances(false), DisableLegacyTypeInfo(false),
PrespecializeGenericMetadata(false), UseIncrementalLLVMCodeGen(true),
UseSwiftCall(false), GenerateProfile(false),
EnableDynamicReplacementChaining(false),
UseIncrementalLLVMCodeGen(true), UseSwiftCall(false),
GenerateProfile(false), EnableDynamicReplacementChaining(false),
DisableRoundTripDebugTypes(false), DisableDebuggerShadowCopies(false),
CmdArgs(), SanitizeCoverage(llvm::SanitizerCoverageOptions()),
TypeInfoFilter(TypeInfoDumpFilter::All) {}
Expand Down
2 changes: 1 addition & 1 deletion include/swift/IRGen/Linking.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class UniversalLinkageInfo {
bool shouldAllPrivateDeclsBeVisibleFromOtherFiles() const {
return HasMultipleIGMs;
}
/// In case of multiple llvm modules, private lazy protocol
/// In case of multipe llvm modules, private lazy protocol
/// witness table accessors could be emitted by two different IGMs during
/// IRGen into different object files and the linker would complain about
/// duplicate symbols.
Expand Down
4 changes: 0 additions & 4 deletions include/swift/Option/FrontendOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -644,10 +644,6 @@ def disable_verify_exclusivity : Flag<["-"], "disable-verify-exclusivity">,
def disable_legacy_type_info : Flag<["-"], "disable-legacy-type-info">,
HelpText<"Completely disable legacy type layout">;

def prespecialize_generic_metadata : Flag<["-"], "prespecialize-generic-metadata">,
HelpText<"Statically specialize metadata for generic types at types that "
"are known to be used in source.">;

def read_legacy_type_info_path_EQ : Joined<["-"], "read-legacy-type-info-path=">,
HelpText<"Read legacy type layout from the given path instead of default path">;

Expand Down
15 changes: 2 additions & 13 deletions lib/AST/Availability.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,25 +239,14 @@ AvailabilityContext ASTContext::getSwift51Availability() {
}

AvailabilityContext ASTContext::getTypesInAbstractMetadataStateAvailability() {
return getSwift52Availability();
}

AvailabilityContext ASTContext::getPrespecializedGenericMetadataAvailability() {
return getSwift52Availability();
}

AvailabilityContext ASTContext::getSwift52Availability() {
auto target = LangOpts.Target;

if (target.isMacOSX() ) {
return AvailabilityContext(
VersionRange::allGTE(llvm::VersionTuple(10, 99, 0)));
} else if (target.isiOS()) {
return AvailabilityContext(
VersionRange::allGTE(llvm::VersionTuple(99, 0, 0)));
} else if (target.isWatchOS()) {
} else if (target.isiOS() || target.isWatchOS()) {
return AvailabilityContext(
VersionRange::allGTE(llvm::VersionTuple(9, 99, 0)));
VersionRange::allGTE(llvm::VersionTuple(9999, 0, 0)));
} else {
return AvailabilityContext::alwaysAvailable();
}
Expand Down
4 changes: 0 additions & 4 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1245,10 +1245,6 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
Opts.DisableLegacyTypeInfo = true;
}

if (Args.hasArg(OPT_prespecialize_generic_metadata)) {
Opts.PrespecializeGenericMetadata = true;
}

if (const Arg *A = Args.getLastArg(OPT_read_legacy_type_info_path_EQ)) {
Opts.ReadLegacyTypeInfoPath = A->getValue();
}
Expand Down
9 changes: 2 additions & 7 deletions lib/IRGen/ClassMetadataVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,13 +204,8 @@ class ClassMetadataScanner : public ClassMetadataVisitor<Impl> {
addPointer();
}
}
void addGenericArgument(GenericRequirement requirement, ClassDecl *forClass) {
addPointer();
}
void addGenericWitnessTable(GenericRequirement requirement,
ClassDecl *forClass) {
addPointer();
}
void addGenericArgument(ClassDecl *forClass) { addPointer(); }
void addGenericWitnessTable(ClassDecl *forClass) { addPointer(); }
void addPlaceholder(MissingMemberDecl *MMD) {
for (auto i : range(MMD->getNumberOfVTableEntries())) {
(void)i;
Expand Down
4 changes: 2 additions & 2 deletions lib/IRGen/EnumMetadataVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ class EnumMetadataScanner : public EnumMetadataVisitor<Impl> {
void addMetadataFlags() { addPointer(); }
void addValueWitnessTable() { addPointer(); }
void addNominalTypeDescriptor() { addPointer(); }
void addGenericArgument(GenericRequirement requirement) { addPointer(); }
void addGenericWitnessTable(GenericRequirement requirement) { addPointer(); }
void addGenericArgument() { addPointer(); }
void addGenericWitnessTable() { addPointer(); }
void addPayloadSize() { addPointer(); }
void noteStartOfTypeSpecificMembers() {}

Expand Down
54 changes: 9 additions & 45 deletions lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1129,7 +1129,6 @@ void IRGenerator::emitTypeMetadataRecords() {
/// else) that we require.
void IRGenerator::emitLazyDefinitions() {
while (!LazyTypeMetadata.empty() ||
!LazySpecializedTypeMetadataRecords.empty() ||
!LazyTypeContextDescriptors.empty() ||
!LazyOpaqueTypeDescriptors.empty() ||
!LazyFieldDescriptors.empty() ||
Expand All @@ -1146,12 +1145,6 @@ void IRGenerator::emitLazyDefinitions() {
CurrentIGMPtr IGM = getGenModule(type->getDeclContext());
emitLazyTypeMetadata(*IGM.get(), type);
}
while (!LazySpecializedTypeMetadataRecords.empty()) {
CanType type = LazySpecializedTypeMetadataRecords.pop_back_val();
auto *nominal = type->getNominalOrBoundGenericNominal();
CurrentIGMPtr IGM = getGenModule(nominal->getDeclContext());
emitLazySpecializedGenericTypeMetadata(*IGM.get(), type);
}
while (!LazyTypeContextDescriptors.empty()) {
NominalTypeDecl *type = LazyTypeContextDescriptors.pop_back_val();
auto &entry = LazyTypeGlobals.find(type)->second;
Expand Down Expand Up @@ -1192,12 +1185,6 @@ void IRGenerator::emitLazyDefinitions() {
}
}

while (!LazyMetadataAccessors.empty()) {
NominalTypeDecl *nominal = LazyMetadataAccessors.pop_back_val();
CurrentIGMPtr IGM = getGenModule(nominal->getDeclContext());
emitLazyMetadataAccessor(*IGM.get(), nominal);
}

FinishedEmittingLazyDefinitions = true;
}

Expand Down Expand Up @@ -1375,18 +1362,6 @@ void IRGenerator::noteUseOfFieldDescriptor(NominalTypeDecl *type) {
LazyFieldDescriptors.push_back(type);
}

void IRGenerator::noteUseOfSpecializedGenericTypeMetadata(CanType type) {
auto key = type->getAnyNominal();
assert(key);
auto &enqueuedSpecializedTypes = this->SpecializationsForGenericTypes[key];
if (llvm::all_of(enqueuedSpecializedTypes,
[&](CanType enqueued) { return enqueued != type; })) {
assert(!FinishedEmittingLazyDefinitions);
this->LazySpecializedTypeMetadataRecords.push_back(type);
enqueuedSpecializedTypes.push_back(type);
}
}

void IRGenerator::noteUseOfOpaqueTypeDescriptor(OpaqueTypeDecl *opaque) {
if (!opaque)
return;
Expand Down Expand Up @@ -3671,11 +3646,8 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(CanType concreteType,
if (nominal)
addRuntimeResolvableType(nominal);

// Don't define the alias for foreign type metadata or prespecialized generic
// metadata, since neither is ABI.
if ((nominal && requiresForeignTypeMetadata(nominal)) ||
(concreteType->getAnyGeneric() &&
concreteType->getAnyGeneric()->isGenericContext()))
// Don't define the alias for foreign type metadata, since it's not ABI.
if (nominal && requiresForeignTypeMetadata(nominal))
return var;

// For concrete metadata, declare the alias to its address point.
Expand Down Expand Up @@ -3710,13 +3682,9 @@ ConstantReference IRGenModule::getAddrOfTypeMetadata(CanType concreteType,

llvm::Type *defaultVarTy;
unsigned adjustmentIndex;

bool fullMetadata = (nominal && requiresForeignTypeMetadata(nominal)) ||
(concreteType->getAnyGeneric() &&
concreteType->getAnyGeneric()->isGenericContext());


// Foreign classes reference the full metadata with a GEP.
if (fullMetadata) {
if (nominal && requiresForeignTypeMetadata(nominal)) {
defaultVarTy = FullTypeMetadataStructTy;
adjustmentIndex = MetadataAdjustmentIndex::ValueType;
// The symbol for other nominal type metadata is generated at the address
Expand All @@ -3741,18 +3709,10 @@ ConstantReference IRGenModule::getAddrOfTypeMetadata(CanType concreteType,
IRGen.noteUseOfTypeMetadata(nominal);
}

if (shouldPrespecializeGenericMetadata()) {
if (auto nominal = concreteType->getAnyNominal()) {
if (nominal->isGenericContext()) {
IRGen.noteUseOfSpecializedGenericTypeMetadata(concreteType);
}
}
}

Optional<LinkEntity> entity;
DebugTypeInfo DbgTy;

if (fullMetadata) {
if (nominal && requiresForeignTypeMetadata(nominal)) {
entity = LinkEntity::forTypeMetadata(concreteType,
TypeMetadataAddress::FullMetadata);
DbgTy = DebugTypeInfo::getMetadata(MetatypeType::get(concreteType),
Expand Down Expand Up @@ -4069,6 +4029,10 @@ Optional<llvm::Function*> IRGenModule::getAddrOfIVarInitDestroy(
llvm::Function *IRGenModule::getAddrOfValueWitness(CanType abstractType,
ValueWitness index,
ForDefinition_t forDefinition) {
// We shouldn't emit value witness symbols for generic type instances.
assert(!isa<BoundGenericType>(abstractType) &&
"emitting value witness for generic type instance?!");

LinkEntity entity = LinkEntity::forValueWitness(abstractType, index);

llvm::Function *&entry = GlobalFuncs[entity];
Expand Down
Loading