Skip to content

Commit 2cdbfa7

Browse files
committed
[DefaultOverrides] IRGen.
1 parent 4951e9d commit 2cdbfa7

File tree

7 files changed

+159
-0
lines changed

7 files changed

+159
-0
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1955,8 +1955,12 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
19551955
/// Set if the metadata contains a pointer to a layout string
19561956
HasLayoutString = 4,
19571957

1958+
/// WARNING: 5 is the last bit!
1959+
19581960
// Type-specific flags:
19591961

1962+
Class_HasDefaultOverrideTable = 6,
1963+
19601964
/// Set if the class is an actor.
19611965
///
19621966
/// Only meaningful for class descriptors.
@@ -2062,6 +2066,9 @@ class TypeContextDescriptorFlags : public FlagSet<uint16_t> {
20622066
FLAGSET_DEFINE_FLAG_ACCESSORS(Class_IsActor,
20632067
class_isActor,
20642068
class_setIsActor)
2069+
FLAGSET_DEFINE_FLAG_ACCESSORS(Class_HasDefaultOverrideTable,
2070+
class_hasDefaultOverrideTable,
2071+
class_setHasDefaultOverrideTable)
20652072

20662073
FLAGSET_DEFINE_FIELD_ACCESSORS(Class_ResilientSuperclassReferenceKind,
20672074
Class_ResilientSuperclassReferenceKind_width,

lib/IRGen/GenClass.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "swift/Basic/Defer.h"
3333
#include "swift/ClangImporter/ClangModule.h"
3434
#include "swift/IRGen/Linking.h"
35+
#include "swift/SIL/SILDefaultOverrideTable.h"
3536
#include "swift/SIL/SILModule.h"
3637
#include "swift/SIL/SILType.h"
3738
#include "swift/SIL/SILVTableVisitor.h"
@@ -3157,3 +3158,12 @@ irgen::emitVirtualMethodValue(IRGenFunction &IGF,
31573158

31583159
return emitVirtualMethodValue(IGF, metadata, method, methodType);
31593160
}
3161+
3162+
void IRGenerator::ensureRelativeSymbolCollocation(SILDefaultOverrideTable &ot) {
3163+
if (!CurrentIGM)
3164+
return;
3165+
3166+
for (auto &entry : ot.getEntries()) {
3167+
forceLocalEmitOfLazyFunction(entry.impl);
3168+
}
3169+
}

lib/IRGen/GenDecl.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1193,6 +1193,9 @@ void IRGenerator::emitGlobalTopLevel(
11931193
CurrentIGMPtr IGM = getGenModule(wt.getProtocol()->getDeclContext());
11941194
ensureRelativeSymbolCollocation(wt);
11951195
}
1196+
for (auto &ot : PrimaryIGM->getSILModule().getDefaultOverrideTableList()) {
1197+
ensureRelativeSymbolCollocation(ot);
1198+
}
11961199
for (auto &directive: linkerDirectives) {
11971200
createLinkerDirectiveVariable(*PrimaryIGM, directive);
11981201
}

lib/IRGen/GenMeta.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2036,6 +2036,7 @@ namespace {
20362036
maybeAddCanonicalMetadataPrespecializations();
20372037
addInvertedProtocols();
20382038
maybeAddSingletonMetadataPointer();
2039+
maybeAddDefaultOverrideTable();
20392040
}
20402041

20412042
void addIncompleteMetadataOrRelocationFunction() {
@@ -2077,6 +2078,9 @@ namespace {
20772078
if (getType()->isDefaultActor(IGM.getSwiftModule(),
20782079
ResilienceExpansion::Maximal))
20792080
flags.class_setIsDefaultActor(true);
2081+
2082+
if (getDefaultOverrideTable())
2083+
flags.class_setHasDefaultOverrideTable(true);
20802084
}
20812085

20822086
if (ResilientSuperClassRef) {
@@ -2286,6 +2290,71 @@ namespace {
22862290
descriptor.finishAndAddTo(B);
22872291
}
22882292

2293+
SILDefaultOverrideTable *getDefaultOverrideTable() {
2294+
auto *table = IGM.getSILModule().lookUpDefaultOverrideTable(getType());
2295+
if (!table)
2296+
return nullptr;
2297+
2298+
if (table->getEntries().size() == 0)
2299+
return nullptr;
2300+
2301+
return table;
2302+
}
2303+
2304+
void maybeAddDefaultOverrideTable() {
2305+
auto *table = getDefaultOverrideTable();
2306+
if (!table)
2307+
return;
2308+
2309+
LLVM_DEBUG(llvm::dbgs() << "Default Override Table entries for "
2310+
<< getType()->getName() << ":\n";
2311+
for (auto entry
2312+
: table->getEntries()) {
2313+
llvm::dbgs() << " ";
2314+
llvm::dbgs() << "original(" << entry.original << ")";
2315+
llvm::dbgs() << " -> ";
2316+
llvm::dbgs() << "replacement(" << entry.method << ")";
2317+
llvm::dbgs() << " -> ";
2318+
llvm::dbgs() << "impl(" << entry.impl->getName() << ")";
2319+
llvm::dbgs() << '\n';
2320+
});
2321+
2322+
B.addInt32(table->getEntries().size());
2323+
2324+
for (auto entry : table->getEntries())
2325+
emitDefaultOverrideDescriptor(entry.method, entry.original, entry.impl);
2326+
}
2327+
2328+
void emitDefaultOverrideDescriptor(SILDeclRef replacement,
2329+
SILDeclRef original, SILFunction *impl) {
2330+
auto descriptor =
2331+
B.beginStruct(IGM.MethodDefaultOverrideDescriptorStructTy);
2332+
2333+
auto replacementEntity = LinkEntity::forMethodDescriptor(replacement);
2334+
auto replacementDescriptor =
2335+
IGM.getAddrOfLLVMVariableOrGOTEquivalent(replacementEntity);
2336+
descriptor.addRelativeAddress(replacementDescriptor);
2337+
2338+
auto originalEntity = LinkEntity::forMethodDescriptor(original);
2339+
auto originalDescriptor =
2340+
IGM.getAddrOfLLVMVariableOrGOTEquivalent(originalEntity);
2341+
descriptor.addRelativeAddress(originalDescriptor);
2342+
2343+
if (impl->isAsync()) {
2344+
llvm::Constant *implFn = IGM.getAddrOfAsyncFunctionPointer(impl);
2345+
descriptor.addRelativeAddress(implFn);
2346+
} else if (impl->getLoweredFunctionType()->isCalleeAllocatedCoroutine()) {
2347+
llvm::Constant *implFn = IGM.getAddrOfCoroFunctionPointer(impl);
2348+
descriptor.addRelativeAddress(implFn);
2349+
} else {
2350+
llvm::Function *implFn =
2351+
IGM.getAddrOfSILFunction(impl, NotForDefinition);
2352+
descriptor.addCompactFunctionReference(implFn);
2353+
}
2354+
2355+
descriptor.finishAndAddTo(B);
2356+
}
2357+
22892358
void addPlaceholder(MissingMemberDecl *MMD) {
22902359
llvm_unreachable("cannot generate metadata with placeholders in it");
22912360
}

lib/IRGen/IRGenModule.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,10 @@ IRGenModule::IRGenModule(IRGenerator &irgen,
502502
RelativeAddressTy
503503
});
504504

505+
MethodDefaultOverrideDescriptorStructTy = createStructType(
506+
*this, "swift.method_default_override_descriptor",
507+
{RelativeAddressTy, RelativeAddressTy, RelativeAddressTy});
508+
505509
TypeMetadataRecordTy
506510
= createStructType(*this, "swift.type_metadata_record", {
507511
RelativeAddressTy

lib/IRGen/IRGenModule.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ namespace swift {
112112
class SILDifferentiabilityWitness;
113113
class SILGlobalVariable;
114114
class SILModule;
115+
class SILDefaultOverrideTable;
115116
class SILProperty;
116117
class SILType;
117118
class SILVTable;
@@ -464,6 +465,8 @@ class IRGenerator {
464465

465466
void ensureRelativeSymbolCollocation(SILDefaultWitnessTable &wt);
466467

468+
void ensureRelativeSymbolCollocation(SILDefaultOverrideTable &ot);
469+
467470
llvm::SmallVector<std::pair<CanType, TypeMetadataCanonicality>, 4>
468471
metadataPrespecializationsForType(NominalTypeDecl *type) {
469472
return MetadataPrespecializationsForGenericTypes.lookup(type);
@@ -789,6 +792,7 @@ class IRGenModule {
789792
llvm::StructType *ClassContextDescriptorTy;
790793
llvm::StructType *MethodDescriptorStructTy; /// %swift.method_descriptor
791794
llvm::StructType *MethodOverrideDescriptorStructTy; /// %swift.method_override_descriptor
795+
llvm::StructType *MethodDefaultOverrideDescriptorStructTy; /// %swift.method_default_override_descriptor
792796
llvm::StructType *TypeMetadataRecordTy;
793797
llvm::PointerType *TypeMetadataRecordPtrTy;
794798
llvm::StructType *FieldDescriptorTy;

test/IRGen/default_override.sil

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// RUN: %target-swift-frontend \
2+
// RUN: %s \
3+
// RUN: -module-name Library \
4+
// RUN: -emit-ir \
5+
// RUN: -enable-experimental-feature CoroutineAccessors \
6+
// RUN: -enable-library-evolution \
7+
// RUN: | %IRGenFileCheck %s
8+
9+
// REQUIRES: swift_feature_CoroutineAccessors
10+
11+
sil_stage canonical
12+
13+
import Builtin
14+
15+
struct Int {
16+
var _value: Builtin.Int64
17+
}
18+
19+
open class B {
20+
open var i: Int { read set }
21+
}
22+
23+
sil @B_i_read : $@yield_once @convention(method) (@guaranteed B) -> @yields Int
24+
sil @B_i_read2 : $@yield_once_2 @convention(method) (@guaranteed B) -> @yields Int
25+
sil @B_i_set : $@convention(method) (Int, @guaranteed B) -> ()
26+
sil @B_i_modify : $@yield_once @convention(method) (@guaranteed B) -> @yields @inout Int
27+
sil @B_i_modify2 : $@yield_once_2 @convention(method) (@guaranteed B) -> @yields @inout Int
28+
29+
sil_vtable B {
30+
#B.i!read: (B) -> () -> () : @B_i_read
31+
#B.i!read2: (B) -> () -> () : @B_i_read2
32+
#B.i!setter: (B) -> (Int) -> () : @B_i_set
33+
#B.i!modify: (B) -> () -> () : @B_i_modify
34+
#B.i!modify2: (B) -> () -> () : @B_i_modify2
35+
}
36+
37+
sil @B_i_read2_default_override : $@yield_once_2 @convention(method) (@guaranteed B) -> @yields Int
38+
sil @B_i_modify2_default_override : $@yield_once_2 @convention(method) (@guaranteed B) -> @yields @inout Int
39+
40+
sil_default_override_table B {
41+
#B.i!read2: #B.i!read: (B) -> () -> () : @B_i_read2_default_override
42+
#B.i!modify2: #B.i!modify: (B) -> () -> () : @B_i_modify2_default_override
43+
}
44+
45+
// CHECK: %swift.method_default_override_descriptor = type { i32, i32, i32 }
46+
47+
// CHECK-LABEL: @"$s7Library1BCMn" = {{.*}}constant <{
48+
// Other stuff.
49+
// CHECK-SAME: i32
50+
// CHECK-SAME: %swift.method_default_override_descriptor
51+
// CHECK-SAME: %swift.method_default_override_descriptor
52+
// CHECK-SAME:}>
53+
// CHECK-SAME:<{
54+
// Eventually...
55+
// CHECK-SAME: i32 2
56+
// CHECK-SAME: %swift.method_default_override_descriptor {
57+
// CHECK-SAME: B_i_read2_default_overrideTwc
58+
// CHECK-SAME: }
59+
// CHECK-SAME: %swift.method_default_override_descriptor {
60+
// CHECK-SAME: B_i_modify2_default_overrideTwc
61+
// CHECK-SAME: }
62+
// CHECK-SAME:}>

0 commit comments

Comments
 (0)