@@ -933,9 +933,12 @@ void IRGenModule::emitVTableStubs() {
933
933
llvm::CallInst::Create (errorFunc, ArrayRef<llvm::Value *>(), " " , entry);
934
934
new llvm::UnreachableInst (getLLVMContext (), entry);
935
935
}
936
+
936
937
// For each eliminated method symbol create an alias to the stub.
937
- llvm::GlobalAlias::create (llvm::GlobalValue::ExternalLinkage, F.getName (),
938
- stub);
938
+ auto *alias = llvm::GlobalAlias::create (llvm::GlobalValue::ExternalLinkage,
939
+ F.getName (), stub);
940
+ if (Triple.isOSBinFormatCOFF ())
941
+ alias->setDLLStorageClass (llvm::GlobalValue::DLLExportStorageClass);
939
942
}
940
943
}
941
944
@@ -1223,32 +1226,34 @@ bool LinkEntity::isFragile(IRGenModule &IGM) const {
1223
1226
return false ;
1224
1227
}
1225
1228
1226
-
1227
- static std::pair<llvm::GlobalValue::LinkageTypes,
1228
- llvm::GlobalValue::VisibilityTypes>
1229
- getIRLinkage (IRGenModule &IGM,
1230
- SILLinkage linkage, bool isFragile, bool isSILOnly,
1231
- ForDefinition_t isDefinition,
1229
+ static std::tuple<llvm::GlobalValue::LinkageTypes,
1230
+ llvm::GlobalValue::VisibilityTypes,
1231
+ llvm::GlobalValue::DLLStorageClassTypes>
1232
+ getIRLinkage (IRGenModule &IGM, SILLinkage linkage, bool isFragile,
1233
+ bool isSILOnly, ForDefinition_t isDefinition,
1232
1234
bool isWeakImported) {
1233
-
1234
- #define RESULT (LINKAGE, VISIBILITY ) \
1235
- { llvm::GlobalValue::LINKAGE##Linkage, \
1236
- llvm::GlobalValue::VISIBILITY##Visibility }
1237
- // Public visibility depends on the target object format.
1238
-
1239
- llvm::GlobalValue::VisibilityTypes PublicDefinitionVisibility;
1240
- switch (IGM.TargetInfo .OutputObjectFormat ) {
1241
- case llvm::Triple::ELF:
1242
- // Use protected visibility for public symbols we define.
1243
- // ld.so doesn't support relative relocations at load time, which interferes
1244
- // with our metadata formats.
1245
- PublicDefinitionVisibility = llvm::GlobalValue::ProtectedVisibility;
1246
- break ;
1247
- default :
1248
- // Default visibility should suffice for other object formats.
1249
- PublicDefinitionVisibility = llvm::GlobalValue::DefaultVisibility;
1250
- break ;
1251
- }
1235
+ #define RESULT (LINKAGE, VISIBILITY, DLL_STORAGE ) \
1236
+ std::make_tuple (llvm::GlobalValue::LINKAGE##Linkage, \
1237
+ llvm::GlobalValue::VISIBILITY##Visibility, \
1238
+ llvm::GlobalValue::DLL_STORAGE##StorageClass)
1239
+
1240
+ const auto ObjFormat = IGM.TargetInfo .OutputObjectFormat ;
1241
+ bool IsELFObject = ObjFormat == llvm::Triple::ELF;
1242
+ bool IsCOFFObject = ObjFormat == llvm::Triple::COFF;
1243
+
1244
+ // Use protected visibility for public symbols we define on ELF. ld.so
1245
+ // doesn't support relative relocations at load time, which interferes with
1246
+ // our metadata formats. Default visibility should suffice for other object
1247
+ // formats.
1248
+ llvm::GlobalValue::VisibilityTypes PublicDefinitionVisibility =
1249
+ IsELFObject ? llvm::GlobalValue::ProtectedVisibility
1250
+ : llvm::GlobalValue::DefaultVisibility;
1251
+ llvm::GlobalValue::DLLStorageClassTypes ExportedStorage =
1252
+ IsCOFFObject ? llvm::GlobalValue::DLLExportStorageClass
1253
+ : llvm::GlobalValue::DefaultStorageClass;
1254
+ llvm::GlobalValue::DLLStorageClassTypes ImportedStorage =
1255
+ IsCOFFObject ? llvm::GlobalValue::DLLImportStorageClass
1256
+ : llvm::GlobalValue::DefaultStorageClass;
1252
1257
1253
1258
if (isFragile) {
1254
1259
// Fragile functions/globals must be visible from outside, regardless of
@@ -1269,58 +1274,67 @@ llvm::GlobalValue::VISIBILITY##Visibility }
1269
1274
break ;
1270
1275
}
1271
1276
}
1272
-
1277
+
1273
1278
switch (linkage) {
1274
1279
case SILLinkage::Public:
1275
- // Don't code-gen transparent functions. Internal linkage
1276
- // will enable llvm to delete transparent functions except
1277
- // they are referenced from somewhere (i.e. the function pointer
1278
- // is taken).
1279
- if (isSILOnly &&
1280
- // In case we are generating multiple LLVM modules, we still have to
1281
- // use ExternalLinkage so that modules can cross-reference transparent
1282
- // functions.
1283
- !IGM. IRGen . hasMultipleIGMs () &&
1284
-
1285
- // TODO: In non-whole-module-opt the generated swiftmodules are "linked"
1286
- // and this strips all serialized transparent functions. So we have to
1287
- // code-gen transparent functions in non-whole-module-opt.
1288
- IGM. getSILModule (). isWholeModule ()) {
1289
- return RESULT (Internal, Default);
1290
- }
1291
- return {llvm::GlobalValue::ExternalLinkage, PublicDefinitionVisibility};
1280
+ // Don't code-gen transparent functions. Internal linkage will enable llvm
1281
+ // to delete transparent functions except they are referenced from somewhere
1282
+ // (i.e. the function pointer is taken).
1283
+ //
1284
+ // In case we are generating multiple LLVM modules, we still have to use
1285
+ // ExternalLinkage so that modules can cross-reference transparent
1286
+ // functions.
1287
+ //
1288
+ // TODO: In non-whole-module-opt the generated swiftmodules are "linked" and
1289
+ // this strips all serialized transparent functions. So we have to code-gen
1290
+ // transparent functions in non-whole-module-opt.
1291
+ if (isSILOnly && !IGM. IRGen . hasMultipleIGMs () &&
1292
+ IGM. getSILModule (). isWholeModule ())
1293
+ return RESULT (Internal, Default, Default);
1294
+ return std::make_tuple (llvm::GlobalValue::ExternalLinkage,
1295
+ PublicDefinitionVisibility, ExportedStorage);
1296
+
1292
1297
case SILLinkage::Shared:
1293
- case SILLinkage::SharedExternal: return RESULT (LinkOnceODR, Hidden);
1294
- case SILLinkage::Hidden: return RESULT (External, Hidden);
1298
+ case SILLinkage::SharedExternal:
1299
+ return RESULT (LinkOnceODR, Hidden, Default);
1300
+
1301
+ case SILLinkage::Hidden:
1302
+ return RESULT (External, Hidden, Default);
1303
+
1295
1304
case SILLinkage::Private:
1296
- if (IGM.IRGen .hasMultipleIGMs ()) {
1297
- // In case of multiple llvm modules (in multi-threaded compilation) all
1298
- // private decls must be visible from other files.
1299
- return RESULT (External, Hidden);
1300
- }
1301
- return RESULT (Internal, Default);
1302
- case SILLinkage::PublicExternal:
1303
- if (isDefinition) {
1304
- if (isSILOnly) {
1305
- // Transparent function are not available externally.
1306
- return RESULT (LinkOnceODR, Hidden);
1307
- }
1308
- return RESULT (AvailableExternally, Default);
1309
- }
1305
+ // In case of multiple llvm modules (in multi-threaded compilation) all
1306
+ // private decls must be visible from other files.
1307
+ if (IGM.IRGen .hasMultipleIGMs ())
1308
+ return RESULT (External, Hidden, Default);
1309
+ return RESULT (Internal, Default, Default);
1310
1310
1311
- if (isWeakImported)
1312
- return RESULT (ExternalWeak, Default);
1313
- return RESULT (External, Default);
1314
- case SILLinkage::HiddenExternal:
1315
- case SILLinkage::PrivateExternal: {
1316
- auto visibility = isFragile ? llvm::GlobalValue::DefaultVisibility
1317
- : llvm::GlobalValue::HiddenVisibility;
1311
+ case SILLinkage::PublicExternal: {
1318
1312
if (isDefinition) {
1319
- return {llvm::GlobalValue::AvailableExternallyLinkage, visibility};
1313
+ // Transparent function are not available externally.
1314
+ if (isSILOnly)
1315
+ return RESULT (LinkOnceODR, Hidden, Default);
1316
+ return std::make_tuple (llvm::GlobalValue::AvailableExternallyLinkage,
1317
+ llvm::GlobalValue::DefaultVisibility,
1318
+ ExportedStorage);
1320
1319
}
1321
- return {llvm::GlobalValue::ExternalLinkage, visibility};
1320
+
1321
+ auto linkage = isWeakImported ? llvm::GlobalValue::ExternalWeakLinkage
1322
+ : llvm::GlobalValue::ExternalLinkage;
1323
+ return std::make_tuple (linkage, llvm::GlobalValue::DefaultVisibility,
1324
+ ImportedStorage);
1322
1325
}
1326
+
1327
+ case SILLinkage::HiddenExternal:
1328
+ case SILLinkage::PrivateExternal:
1329
+ return std::make_tuple (isDefinition
1330
+ ? llvm::GlobalValue::AvailableExternallyLinkage
1331
+ : llvm::GlobalValue::ExternalLinkage,
1332
+ isFragile ? llvm::GlobalValue::DefaultVisibility
1333
+ : llvm::GlobalValue::HiddenVisibility,
1334
+ ImportedStorage);
1335
+
1323
1336
}
1337
+
1324
1338
llvm_unreachable (" bad SIL linkage" );
1325
1339
}
1326
1340
@@ -1331,26 +1345,24 @@ static void updateLinkageForDefinition(IRGenModule &IGM,
1331
1345
const LinkEntity &entity) {
1332
1346
// TODO: there are probably cases where we can avoid redoing the
1333
1347
// entire linkage computation.
1334
- auto linkage = getIRLinkage (
1335
- IGM,
1336
- entity.getLinkage (IGM, ForDefinition),
1337
- entity.isFragile (IGM),
1338
- entity.isSILOnly (),
1339
- ForDefinition,
1348
+ auto linkage =
1349
+ getIRLinkage (IGM, entity.getLinkage (IGM, ForDefinition),
1350
+ entity.isFragile (IGM), entity.isSILOnly (), ForDefinition,
1340
1351
entity.isWeakImported (IGM.getSwiftModule ()));
1341
- global->setLinkage (linkage.first );
1342
- global->setVisibility (linkage.second );
1352
+ global->setLinkage (std::get<0 >(linkage));
1353
+ global->setVisibility (std::get<1 >(linkage));
1354
+ global->setDLLStorageClass (std::get<2 >(linkage));
1343
1355
1344
1356
// Everything externally visible is considered used in Swift.
1345
1357
// That mostly means we need to be good at not marking things external.
1346
1358
//
1347
1359
// Exclude "main", because it should naturally be used, and because adding it
1348
1360
// to llvm.used leaves a dangling use when the REPL attempts to discard
1349
1361
// intermediate mains.
1350
- if (LinkInfo::isUsed (linkage.first , linkage.second ) &&
1351
- global->getName () != SWIFT_ENTRY_POINT_FUNCTION) {
1362
+ if (LinkInfo::isUsed (std::get<0 >(linkage), std::get<1 >(linkage),
1363
+ std::get<2 >(linkage)) &&
1364
+ global->getName () != SWIFT_ENTRY_POINT_FUNCTION)
1352
1365
IGM.addUsedGlobal (global);
1353
- }
1354
1366
}
1355
1367
1356
1368
LinkInfo LinkInfo::get (IRGenModule &IGM, const LinkEntity &entity,
@@ -1359,12 +1371,10 @@ LinkInfo LinkInfo::get(IRGenModule &IGM, const LinkEntity &entity,
1359
1371
1360
1372
entity.mangle (result.Name );
1361
1373
1362
- std::tie (result.Linkage , result.Visibility ) =
1363
- getIRLinkage (IGM, entity.getLinkage (IGM, isDefinition),
1364
- entity.isFragile (IGM),
1365
- entity.isSILOnly (),
1366
- isDefinition,
1367
- entity.isWeakImported (IGM.getSwiftModule ()));
1374
+ std::tie (result.Linkage , result.Visibility , result.DLLStorageClass ) =
1375
+ getIRLinkage (IGM, entity.getLinkage (IGM, isDefinition),
1376
+ entity.isFragile (IGM), entity.isSILOnly (), isDefinition,
1377
+ entity.isWeakImported (IGM.getSwiftModule ()));
1368
1378
1369
1379
result.ForDefinition = isDefinition;
1370
1380
@@ -1394,15 +1404,16 @@ llvm::Function *LinkInfo::createFunction(IRGenModule &IGM,
1394
1404
existing->setName (getName () + " .unique" );
1395
1405
}
1396
1406
1397
- llvm::Function *fn
1398
- = llvm::Function::Create (fnType, getLinkage (), getName ());
1407
+ llvm::Function *fn = llvm::Function::Create (fnType, getLinkage (), getName ());
1408
+ fn->setVisibility (getVisibility ());
1409
+ fn->setDLLStorageClass (getDLLStorage ());
1410
+ fn->setCallingConv (cc);
1411
+
1399
1412
if (insertBefore) {
1400
1413
IGM.Module .getFunctionList ().insert (insertBefore->getIterator (), fn);
1401
1414
} else {
1402
1415
IGM.Module .getFunctionList ().push_back (fn);
1403
- }
1404
- fn->setVisibility (getVisibility ());
1405
- fn->setCallingConv (cc);
1416
+ }
1406
1417
1407
1418
auto initialAttrs = IGM.constructInitialAttributes ();
1408
1419
// Merge initialAttrs with attrs.
@@ -1426,12 +1437,15 @@ llvm::Function *LinkInfo::createFunction(IRGenModule &IGM,
1426
1437
}
1427
1438
1428
1439
bool LinkInfo::isUsed (llvm::GlobalValue::LinkageTypes Linkage,
1429
- llvm::GlobalValue::VisibilityTypes Visibility) {
1440
+ llvm::GlobalValue::VisibilityTypes Visibility,
1441
+ llvm::GlobalValue::DLLStorageClassTypes DLLStorage) {
1430
1442
// Everything externally visible is considered used in Swift.
1431
1443
// That mostly means we need to be good at not marking things external.
1432
1444
return Linkage == llvm::GlobalValue::ExternalLinkage &&
1433
- (Visibility == llvm::GlobalValue::DefaultVisibility ||
1434
- Visibility == llvm::GlobalValue::ProtectedVisibility);
1445
+ (Visibility == llvm::GlobalValue::DefaultVisibility ||
1446
+ Visibility == llvm::GlobalValue::ProtectedVisibility) &&
1447
+ (DLLStorage == llvm::GlobalValue::DefaultStorageClass ||
1448
+ DLLStorage == llvm::GlobalValue::DLLExportStorageClass);
1435
1449
}
1436
1450
1437
1451
// / Get or create an LLVM global variable with these linkage rules.
@@ -1456,10 +1470,10 @@ llvm::GlobalVariable *LinkInfo::createVariable(IRGenModule &IGM,
1456
1470
}
1457
1471
1458
1472
auto var = new llvm::GlobalVariable (IGM.Module , storageType,
1459
- /* constant*/ false ,
1460
- getLinkage (), /* initializer*/ nullptr ,
1461
- getName ());
1473
+ /* constant*/ false , getLinkage (),
1474
+ /* initializer*/ nullptr , getName ());
1462
1475
var->setVisibility (getVisibility ());
1476
+ var->setDLLStorageClass (getDLLStorage ());
1463
1477
var->setAlignment (alignment.getValue ());
1464
1478
1465
1479
// Everything externally visible is considered used in Swift.
@@ -2477,6 +2491,7 @@ llvm::GlobalValue *IRGenModule::defineTypeMetadata(CanType concreteType,
2477
2491
ptrTy->getElementType (), ptrTy->getAddressSpace (), link.getLinkage (),
2478
2492
link.getName (), addr, &Module);
2479
2493
alias->setVisibility (link.getVisibility ());
2494
+ alias->setDLLStorageClass (link.getDLLStorage ());
2480
2495
2481
2496
// The full metadata is used based on the visibility of the address point,
2482
2497
// not the metadata itself.
@@ -3166,6 +3181,7 @@ static llvm::Function *shouldDefineHelper(IRGenModule &IGM,
3166
3181
3167
3182
def->setLinkage (llvm::Function::LinkOnceODRLinkage);
3168
3183
def->setVisibility (llvm::Function::HiddenVisibility);
3184
+ def->setDLLStorageClass (llvm::GlobalVariable::DefaultStorageClass);
3169
3185
def->setDoesNotThrow ();
3170
3186
def->setCallingConv (IGM.DefaultCC );
3171
3187
return def;
0 commit comments