Skip to content

Commit e9e93c1

Browse files
committed
[Opaque Values] Address-lower TypeLowerings.
When opaque values are enabled, TypeConverter associates to an address-only type an OpaqueValueTypeLowering. That lowering stores a single lowered SIL type, and its value category is "object". So long as the module has not yet been address-lowered, that type has the appropriate value category. After the module has been address-lowered, however, that type has the wrong value category: the type is address-only, and in an address-lowered module, its lowered type's value category must be "address". Code that obtains a lowered type expects the value category to reflect the state of the module. So somewhere, it's necessary to fixup that single lowered type's value category. One option would be to update all code that uses lowered types. That would require many changes across the codebase and all new code that used lowered types would need to account for this. Another option would be to update some popular conveniences that call through to TypeConverter, for example those on SILFunction, and ensure that all code used those conveniences. Even if this were done completely, it would be easy enough for new code to be added which didn't use the conveniences. A third option would be to update TypeLowering::getLoweredType to take in the context necessary to determine whether the stored SILType should be fixed up. That would require each callsite to be changed and potentially to carry around more context than it already had in order to be able to pass it along. A fourth option would be to make TypeConverter aware of the address-loweredness, and to update its state at the end of AddressLowering. Updating TypeConverter's state would entail updating all cached OpaqueValueTypeLowering instances at the end of the AddressLowering pass. Additionally, when TypeConverter produces new OpaqueValueTypeLowerings, they would need to have the "address" value category from creation. Of all the options, the last is least invasive and least error-prone, so it is taken here.
1 parent 1dcc53d commit e9e93c1

File tree

7 files changed

+103
-17
lines changed

7 files changed

+103
-17
lines changed

include/swift/SIL/SILModule.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,12 @@ class SILModule {
874874
/// True if SIL conventions force address-only to be passed by address.
875875
bool useLoweredAddresses() const { return loweredAddresses; }
876876

877-
void setLoweredAddresses(bool val) { loweredAddresses = val; }
877+
void setLoweredAddresses(bool val) {
878+
loweredAddresses = val;
879+
if (val) {
880+
Types.setLoweredAddresses();
881+
}
882+
}
878883

879884
llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); }
880885

include/swift/SIL/TypeLowering.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,13 @@ class TypeLowering {
289289
private:
290290
friend class TypeConverter;
291291

292+
virtual void setLoweredAddresses() const {}
293+
294+
protected:
292295
/// The SIL type of values with this Swift type.
293-
SILType LoweredType;
296+
mutable SILType LoweredType;
294297

298+
private:
295299
RecursiveProperties Properties;
296300

297301
/// The resilience expansion for this type lowering.
@@ -778,6 +782,9 @@ class TypeConverter {
778782
void removeNullEntry(const TypeKey &k);
779783
#endif
780784

785+
/// True if SIL conventions force address-only to be passed by address.
786+
bool LoweredAddresses;
787+
781788
CanGenericSignature CurGenericSignature;
782789

783790
/// Stack of types currently being lowered as part of an aggregate.
@@ -824,7 +831,7 @@ class TypeConverter {
824831
ModuleDecl &M;
825832
ASTContext &Context;
826833

827-
TypeConverter(ModuleDecl &m);
834+
TypeConverter(ModuleDecl &m, bool loweredAddresses = true);
828835
~TypeConverter();
829836
TypeConverter(TypeConverter const &) = delete;
830837
TypeConverter &operator=(TypeConverter const &) = delete;
@@ -1218,6 +1225,9 @@ class TypeConverter {
12181225

12191226
void setCaptureTypeExpansionContext(SILDeclRef constant,
12201227
SILModule &M);
1228+
1229+
void setLoweredAddresses();
1230+
12211231
private:
12221232
CanType computeLoweredRValueType(TypeExpansionContext context,
12231233
AbstractionPattern origType,

lib/DriverTool/modulewrap_main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ int modulewrap_main(ArrayRef<const char *> Args, const char *Argv0,
189189

190190
ASTCtx.addModuleLoader(ClangImporter::create(ASTCtx, ""), true);
191191
ModuleDecl *M = ModuleDecl::create(ASTCtx.getIdentifier("swiftmodule"), ASTCtx);
192-
std::unique_ptr<Lowering::TypeConverter> TC(new Lowering::TypeConverter(*M));
192+
std::unique_ptr<Lowering::TypeConverter> TC(
193+
new Lowering::TypeConverter(*M, ASTCtx.SILOpts.EnableSILOpaqueValues));
193194
std::unique_ptr<SILModule> SM = SILModule::createEmptyModule(M, *TC, SILOpts);
194195
createSwiftModuleObjectFile(*SM, (*ErrOrBuf)->getBuffer(),
195196
Invocation.getOutputFilename());

lib/Frontend/Frontend.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,10 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
202202
Lowering::TypeConverter &CompilerInstance::getSILTypes() {
203203
if (auto *tc = TheSILTypes.get())
204204
return *tc;
205-
206-
auto *tc = new Lowering::TypeConverter(*getMainModule());
205+
206+
auto *tc = new Lowering::TypeConverter(
207+
*getMainModule(),
208+
/*loweredAddresses=*/!Context->SILOpts.EnableSILOpaqueValues);
207209
TheSILTypes.reset(tc);
208210
return *tc;
209211
}

lib/IRGen/IRABIDetailsProvider.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ namespace swift {
7171
class IRABIDetailsProviderImpl {
7272
public:
7373
IRABIDetailsProviderImpl(ModuleDecl &mod, const IRGenOptions &opts)
74-
: typeConverter(mod),
74+
: typeConverter(mod, /*addressLowered=*/true),
7575
silMod(SILModule::createEmptyModule(&mod, typeConverter, silOpts)),
7676
IRGen(opts, *silMod), IGM(IRGen, IRGen.createTargetMachine()) {}
7777

lib/SIL/IR/TypeLowering.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,6 +1942,10 @@ namespace {
19421942
/// Lower address only types as opaque values.
19431943
class OpaqueValueTypeLowering : public LeafLoadableTypeLowering {
19441944
public:
1945+
void setLoweredAddresses() const override {
1946+
LoweredType = LoweredType.getAddressType();
1947+
}
1948+
19451949
OpaqueValueTypeLowering(SILType type, RecursiveProperties properties,
19461950
TypeExpansionContext forExpansion)
19471951
: LeafLoadableTypeLowering(type, properties, IsNotReferenceCounted,
@@ -2004,6 +2008,10 @@ namespace {
20042008
: LeafLoadableTypeLowering(type, properties, IsNotReferenceCounted,
20052009
forExpansion) {}
20062010

2011+
void setLoweredAddresses() const override {
2012+
LoweredType = LoweredType.getAddressType();
2013+
}
2014+
20072015
void emitCopyInto(SILBuilder &B, SILLocation loc, SILValue src,
20082016
SILValue dest, IsTake_t isTake,
20092017
IsInitialization_t isInit) const override {
@@ -2041,9 +2049,13 @@ namespace {
20412049
class LowerType
20422050
: public TypeClassifierBase<LowerType, TypeLowering *>
20432051
{
2052+
bool loweredAddresses;
2053+
20442054
public:
2045-
LowerType(TypeConverter &TC, TypeExpansionContext Expansion)
2046-
: TypeClassifierBase(TC, Expansion) {}
2055+
LowerType(TypeConverter &TC, TypeExpansionContext Expansion,
2056+
bool loweredAddresses)
2057+
: TypeClassifierBase(TC, Expansion),
2058+
loweredAddresses(loweredAddresses) {}
20472059

20482060
TypeLowering *handleTrivial(CanType type) {
20492061
return handleTrivial(type, RecursiveProperties::forTrivial());
@@ -2100,7 +2112,9 @@ namespace {
21002112
return new (TC) AddressOnlyTypeLowering(silType, properties,
21012113
Expansion);
21022114
}
2103-
auto silType = SILType::getPrimitiveObjectType(type);
2115+
auto silType = SILType::getPrimitiveType(
2116+
type, loweredAddresses ? SILValueCategory::Address
2117+
: SILValueCategory::Object);
21042118
return new (TC) OpaqueValueTypeLowering(silType, properties, Expansion);
21052119
}
21062120

@@ -2394,9 +2408,8 @@ namespace {
23942408
};
23952409
} // end anonymous namespace
23962410

2397-
TypeConverter::TypeConverter(ModuleDecl &m)
2398-
: M(m), Context(m.getASTContext()) {
2399-
}
2411+
TypeConverter::TypeConverter(ModuleDecl &m, bool loweredAddresses)
2412+
: LoweredAddresses(loweredAddresses), M(m), Context(m.getASTContext()) {}
24002413

24012414
TypeConverter::~TypeConverter() {
24022415
// The bump pointer allocator destructor will deallocate but not destroy all
@@ -2597,7 +2610,7 @@ TypeConverter::getTypeLowering(AbstractionPattern origType,
25972610
// and cache it.
25982611
if (loweredSubstType == substType && key.isCacheable()) {
25992612
lowering =
2600-
LowerType(*this, forExpansion)
2613+
LowerType(*this, forExpansion, LoweredAddresses)
26012614
.visit(key.SubstType, key.OrigType, isTypeExpansionSensitive);
26022615

26032616
// Otherwise, check the table at a key that would be used by the
@@ -3059,9 +3072,8 @@ const TypeLowering &TypeConverter::getTypeLoweringForLoweredType(
30593072
forExpansion, origType, loweredType);
30603073
}
30613074

3062-
lowering =
3063-
LowerType(*this, forExpansion)
3064-
.visit(loweredType, origType, isTypeExpansionSensitive);
3075+
lowering = LowerType(*this, forExpansion, LoweredAddresses)
3076+
.visit(loweredType, origType, isTypeExpansionSensitive);
30653077

30663078
if (!lowering->isResilient() && !lowering->isTypeExpansionSensitive())
30673079
insert(key.getKeyForMinimalExpansion(), lowering);
@@ -4358,6 +4370,14 @@ void TypeConverter::setCaptureTypeExpansionContext(SILDeclRef constant,
43584370
}
43594371
}
43604372

4373+
void TypeConverter::setLoweredAddresses() {
4374+
assert(!LoweredAddresses);
4375+
for (auto &pair : this->LoweredTypes) {
4376+
pair.getSecond()->setLoweredAddresses();
4377+
}
4378+
LoweredAddresses = true;
4379+
}
4380+
43614381
static void countNumberOfInnerFields(unsigned &fieldsCount, TypeConverter &TC,
43624382
SILType Ty,
43634383
TypeExpansionContext expansion) {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// RUN: %target-sil-opt -wmo -enable-sil-verify-all -emit-sorted-sil %s -enable-existential-specializer -existential-specializer -type-lowering-force-opaque-value-lowering 2>&1 | %FileCheck %s
2+
3+
// Test ExistentialSpecializer with OpaqueValueTypeLowerings.
4+
5+
import Builtin
6+
import Swift
7+
import SwiftShims
8+
9+
public protocol P {}
10+
11+
public struct S : P {
12+
init()
13+
14+
var o: AnyObject // nontrivial to check ownership conventions
15+
}
16+
17+
// Verify that the opened existential type used in thunk building is properly
18+
// address lowered even though it has an OpaqueValueTypeLowering.
19+
// CHECK-LABEL: sil hidden [signature_optimized_thunk] [always_inline] @$s6test2_6storePyyAA1P_p_AaC_pztF : {{.*}} {
20+
// CHECK: {{bb[0-9]+}}([[IN_ADDR:%[^,]+]] : $*any P, [[OUT_ADDR:%[^,]+]] : $*any P):
21+
// CHECK: [[OPENED_IN_ADDR:%[^,]+]] = open_existential_addr mutable_access [[IN_ADDR]] : $*any P to $*@opened([[UUID:".*"]], any P) Self
22+
// CHECK: [[OPENED_OUT_ADDR:%[^,]+]] = alloc_stack $@opened([[UUID]], any P) Self
23+
// CHECK: copy_addr [[OPENED_IN_ADDR]] to [init] [[OPENED_OUT_ADDR]] : $*@opened([[UUID]], any P) Self
24+
// CHECK: apply {{%[^,]+}}<@opened([[UUID]], any P) Self>([[OPENED_OUT_ADDR]], [[OUT_ADDR]])
25+
// CHECK: destroy_addr [[IN_ADDR]]
26+
// CHECK: dealloc_stack [[OPENED_OUT_ADDR]]
27+
// CHECK-LABEL: } // end sil function '$s6test2_6storePyyAA1P_p_AaC_pztF'
28+
sil hidden [noinline] @$s6test2_6storePyyAA1P_p_AaC_pztF : $@convention(thin) (@in P, @inout P) -> () {
29+
bb0(%0 : $*P, %1 : $*P):
30+
copy_addr %0 to [init] %1 : $*P
31+
destroy_addr %0 : $*P
32+
%5 = tuple ()
33+
return %5 : $()
34+
}
35+
36+
sil @$s6test2_6storeS1s1qyAA1SV_AA1P_pztF : $@convention(thin) (S, @inout P) -> () {
37+
bb0(%0 : $S, %1 : $*P):
38+
%4 = alloc_stack $P
39+
%5 = init_existential_addr %4 : $*P, $S
40+
store %0 to %5 : $*S
41+
%7 = function_ref @$s6test2_6storePyyAA1P_p_AaC_pztF : $@convention(thin) (@in P, @inout P) -> ()
42+
%8 = apply %7(%4, %1) : $@convention(thin) (@in P, @inout P) -> ()
43+
dealloc_stack %4 : $*P
44+
%10 = tuple ()
45+
return %10 : $()
46+
}
47+
48+
sil_witness_table S: P module test {}

0 commit comments

Comments
 (0)