Skip to content

Commit 8c57691

Browse files
committed
IRGen: adjust the linkage for VWT emission on Windows
When building the standard library, we would previously mark the well known metadata for a number of types as having external storage (DLLImport). The well known builtin VWT are defined in the runtime rather than the module, which would prevent us from properly annotating the symbol. This change is an improvement but not completely sufficient as we currently mark the VWT for `() -> ()` as having external storage.
1 parent e252cbb commit 8c57691

File tree

4 files changed

+47
-37
lines changed

4 files changed

+47
-37
lines changed

lib/IRGen/GenDecl.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5656,7 +5656,14 @@ llvm::Constant *
56565656
IRGenModule::getAddrOfValueWitnessTable(CanType concreteType,
56575657
ConstantInit definition) {
56585658
LinkEntity entity = LinkEntity::forValueWitnessTable(concreteType);
5659-
return getAddrOfLLVMVariable(entity, definition, DebugTypeInfo());
5659+
llvm::Constant *C = getAddrOfLLVMVariable(entity, definition, DebugTypeInfo());
5660+
if (getSwiftModule()->isStdlibModule() && useDllStorage(Triple))
5661+
if (IsWellKnownBuiltinOrStructralType(concreteType))
5662+
ApplyIRLinkage({llvm::GlobalValue::ExternalLinkage,
5663+
llvm::GlobalValue::DefaultVisibility,
5664+
llvm::GlobalValue::DefaultStorageClass})
5665+
.to(cast<llvm::GlobalValue>(C));
5666+
return C;
56605667
}
56615668

56625669
static Address getAddrOfSimpleVariable(IRGenModule &IGM,

lib/IRGen/IRGenModule.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1375,6 +1375,39 @@ llvm::Module *IRGenModule::getModule() const {
13751375
return ClangCodeGen->GetModule();
13761376
}
13771377

1378+
bool IRGenModule::IsWellKnownBuiltinOrStructralType(CanType T) const {
1379+
static const CanType kStructural[] = {
1380+
Context.TheEmptyTupleType, Context.TheNativeObjectType,
1381+
Context.TheBridgeObjectType, Context.TheRawPointerType,
1382+
Context.getAnyObjectType()
1383+
};
1384+
1385+
if (std::any_of(std::begin(kStructural), std::end(kStructural),
1386+
[T](const CanType &ST) { return T == ST; }))
1387+
return true;
1388+
1389+
if (auto IntTy = dyn_cast<BuiltinIntegerType>(T)) {
1390+
auto Width = IntTy->getWidth();
1391+
if (Width.isPointerWidth())
1392+
return true;
1393+
if (!Width.isFixedWidth())
1394+
return false;
1395+
switch (Width.getFixedWidth()) {
1396+
case 8:
1397+
case 16:
1398+
case 32:
1399+
case 64:
1400+
case 128:
1401+
case 256:
1402+
return true;
1403+
default:
1404+
break;
1405+
}
1406+
}
1407+
1408+
return false;
1409+
}
1410+
13781411
GeneratedModule IRGenModule::intoGeneratedModule() && {
13791412
return GeneratedModule{
13801413
std::move(LLVMContext),

lib/IRGen/IRGenModule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,8 @@ class IRGenModule {
11371137

11381138
ClassMetadataStrategy getClassMetadataStrategy(const ClassDecl *theClass);
11391139

1140+
bool IsWellKnownBuiltinOrStructralType(CanType type) const;
1141+
11401142
private:
11411143
TypeConverter &Types;
11421144
friend TypeConverter;

lib/IRGen/MetadataRequest.cpp

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3694,41 +3694,6 @@ namespace {
36943694
return nullptr;
36953695
}
36963696

3697-
bool hasVisibleValueWitnessTable(CanType t) const {
3698-
// Some builtin and structural types have value witnesses exported from
3699-
// the runtime.
3700-
auto &C = IGF.IGM.Context;
3701-
if (t == C.TheEmptyTupleType
3702-
|| t == C.TheNativeObjectType
3703-
|| t == C.TheBridgeObjectType
3704-
|| t == C.TheRawPointerType
3705-
|| t == C.getAnyObjectType())
3706-
return true;
3707-
if (auto intTy = dyn_cast<BuiltinIntegerType>(t)) {
3708-
auto width = intTy->getWidth();
3709-
if (width.isPointerWidth())
3710-
return true;
3711-
if (width.isFixedWidth()) {
3712-
switch (width.getFixedWidth()) {
3713-
case 8:
3714-
case 16:
3715-
case 32:
3716-
case 64:
3717-
case 128:
3718-
case 256:
3719-
return true;
3720-
default:
3721-
return false;
3722-
}
3723-
}
3724-
return false;
3725-
}
3726-
3727-
// TODO: If a nominal type is in the same source file as we're currently
3728-
// emitting, we would be able to see its value witness table.
3729-
return false;
3730-
}
3731-
37323697
/// Fallback default implementation.
37333698
llvm::Value *visitType(CanType t, DynamicMetadataRequest request) {
37343699
auto silTy = IGF.IGM.getLoweredType(t);
@@ -3737,7 +3702,10 @@ namespace {
37373702
// If the type is in the same source file, or has a common value
37383703
// witness table exported from the runtime, we can project from the
37393704
// value witness table instead of emitting a new record.
3740-
if (hasVisibleValueWitnessTable(t))
3705+
//
3706+
// TODO: If a nominal type is in the same source file as we're currently
3707+
// emitting, we would be able to see its value witness table.
3708+
if (IGF.IGM.IsWellKnownBuiltinOrStructralType(t))
37413709
return emitFromValueWitnessTable(t);
37423710

37433711
// If the type is a singleton aggregate, the field's layout is equivalent

0 commit comments

Comments
 (0)