@@ -1991,8 +1991,9 @@ void irgen::updateLinkageForDefinition(IRGenModule &IGM,
1991
1991
1992
1992
// Everything externally visible is considered used in Swift.
1993
1993
// That mostly means we need to be good at not marking things external.
1994
- if (LinkInfo::isUsed (IRL))
1995
- IGM.addUsedGlobal (global);
1994
+ if (LinkInfo::isUsed (IRL) && !IGM.IRGen .Opts .EmitDeadStrippableSymbols ) {
1995
+ IGM.addUsedGlobal (global);
1996
+ }
1996
1997
}
1997
1998
1998
1999
LinkInfo LinkInfo::get (IRGenModule &IGM, const LinkEntity &entity,
@@ -2085,7 +2086,11 @@ llvm::Function *irgen::createFunction(IRGenModule &IGM,
2085
2086
// Everything externally visible is considered used in Swift.
2086
2087
// That mostly means we need to be good at not marking things external.
2087
2088
if (linkInfo.isUsed ()) {
2088
- IGM.addUsedGlobal (fn);
2089
+ // Don't allow dead_strip'ing for "main".
2090
+ if (name == SWIFT_ENTRY_POINT_FUNCTION ||
2091
+ !IGM.IRGen .Opts .EmitDeadStrippableSymbols ) {
2092
+ IGM.addUsedGlobal (fn);
2093
+ }
2089
2094
}
2090
2095
2091
2096
return fn;
@@ -2132,7 +2137,7 @@ llvm::GlobalVariable *swift::irgen::createVariable(
2132
2137
2133
2138
// Everything externally visible is considered used in Swift.
2134
2139
// That mostly means we need to be good at not marking things external.
2135
- if (linkInfo.isUsed ()) {
2140
+ if (linkInfo.isUsed () && !IGM. IRGen . Opts . EmitDeadStrippableSymbols ) {
2136
2141
IGM.addUsedGlobal (var);
2137
2142
}
2138
2143
@@ -3350,6 +3355,47 @@ llvm::Constant *IRGenModule::emitSwiftProtocols() {
3350
3355
if (SwiftProtocols.empty ())
3351
3356
return nullptr ;
3352
3357
3358
+ StringRef sectionName;
3359
+ switch (TargetInfo.OutputObjectFormat ) {
3360
+ case llvm::Triple::UnknownObjectFormat:
3361
+ llvm_unreachable (" Don't know how to emit protocols for "
3362
+ " the selected object format." );
3363
+ case llvm::Triple::MachO:
3364
+ sectionName = IRGen.Opts .EmitDeadStrippableSymbols
3365
+ ? " __TEXT, __swift5_protos, regular, live_support"
3366
+ : " __TEXT, __swift5_protos, regular, no_dead_strip" ;
3367
+ break ;
3368
+ case llvm::Triple::ELF:
3369
+ case llvm::Triple::Wasm:
3370
+ sectionName = " swift5_protocols" ;
3371
+ break ;
3372
+ case llvm::Triple::XCOFF:
3373
+ case llvm::Triple::COFF:
3374
+ sectionName = " .sw5prt$B" ;
3375
+ break ;
3376
+ }
3377
+
3378
+ if (IRGen.Opts .EmitDeadStrippableSymbols ) {
3379
+ for (auto *protocol : SwiftProtocols) {
3380
+ auto ref = getTypeEntityReference (protocol);
3381
+ auto name = " \x01 l_protocol_" + std::string (ref.getValue ()->getName ());
3382
+ auto var = new llvm::GlobalVariable (
3383
+ Module, ProtocolRecordTy, /* isConstant*/ true ,
3384
+ llvm::GlobalValue::PrivateLinkage, /* initializer*/ nullptr , name);
3385
+
3386
+ llvm::Constant *relativeAddr =
3387
+ emitDirectRelativeReference (ref.getValue (), var, {0 });
3388
+ llvm::Constant *recordFields[] = {relativeAddr};
3389
+ auto record = llvm::ConstantStruct::get (ProtocolRecordTy, recordFields);
3390
+ var->setInitializer (record);
3391
+ var->setSection (sectionName);
3392
+ var->setAlignment (llvm::MaybeAlign (4 ));
3393
+
3394
+ disableAddressSanitizer (*this , var);
3395
+ }
3396
+ return nullptr ;
3397
+ }
3398
+
3353
3399
// Define the global variable for the protocol list.
3354
3400
ConstantInitBuilder builder (*this );
3355
3401
auto recordsArray = builder.beginArray (ProtocolRecordTy);
@@ -3374,24 +3420,6 @@ llvm::Constant *IRGenModule::emitSwiftProtocols() {
3374
3420
/* isConstant*/ true ,
3375
3421
llvm::GlobalValue::PrivateLinkage);
3376
3422
3377
- StringRef sectionName;
3378
- switch (TargetInfo.OutputObjectFormat ) {
3379
- case llvm::Triple::UnknownObjectFormat:
3380
- llvm_unreachable (" Don't know how to emit protocols for "
3381
- " the selected object format." );
3382
- case llvm::Triple::MachO:
3383
- sectionName = " __TEXT, __swift5_protos, regular, no_dead_strip" ;
3384
- break ;
3385
- case llvm::Triple::ELF:
3386
- case llvm::Triple::Wasm:
3387
- sectionName = " swift5_protocols" ;
3388
- break ;
3389
- case llvm::Triple::XCOFF:
3390
- case llvm::Triple::COFF:
3391
- sectionName = " .sw5prt$B" ;
3392
- break ;
3393
- }
3394
-
3395
3423
var->setSection (sectionName);
3396
3424
3397
3425
disableAddressSanitizer (*this , var);
@@ -3413,6 +3441,49 @@ llvm::Constant *IRGenModule::emitProtocolConformances() {
3413
3441
if (ProtocolConformances.empty ())
3414
3442
return nullptr ;
3415
3443
3444
+ StringRef sectionName;
3445
+ switch (TargetInfo.OutputObjectFormat ) {
3446
+ case llvm::Triple::UnknownObjectFormat:
3447
+ llvm_unreachable (" Don't know how to emit protocol conformances for "
3448
+ " the selected object format." );
3449
+ case llvm::Triple::MachO:
3450
+ sectionName = IRGen.Opts .EmitDeadStrippableSymbols
3451
+ ? " __TEXT, __swift5_proto, regular, live_support"
3452
+ : " __TEXT, __swift5_proto, regular, no_dead_strip" ;
3453
+ break ;
3454
+ case llvm::Triple::ELF:
3455
+ case llvm::Triple::Wasm:
3456
+ sectionName = " swift5_protocol_conformances" ;
3457
+ break ;
3458
+ case llvm::Triple::XCOFF:
3459
+ case llvm::Triple::COFF:
3460
+ sectionName = " .sw5prtc$B" ;
3461
+ break ;
3462
+ }
3463
+
3464
+ if (IRGen.Opts .EmitDeadStrippableSymbols ) {
3465
+ for (const auto &record : ProtocolConformances) {
3466
+ auto conformance = record.conformance ;
3467
+ auto entity = LinkEntity::forProtocolConformanceDescriptor (conformance);
3468
+ auto name =
3469
+ " \x01 l_protocol_conformance_" + std::string (entity.mangleAsString ());
3470
+ auto var = new llvm::GlobalVariable (
3471
+ Module, RelativeAddressTy, /* isConstant*/ true ,
3472
+ llvm::GlobalValue::PrivateLinkage, /* initializer*/ nullptr , name);
3473
+
3474
+ auto descriptor =
3475
+ getAddrOfLLVMVariable (entity, ConstantInit (), DebugTypeInfo ());
3476
+ llvm::Constant *relativeAddr =
3477
+ emitDirectRelativeReference (descriptor, var, {});
3478
+ var->setInitializer (relativeAddr);
3479
+ var->setSection (sectionName);
3480
+ var->setAlignment (llvm::MaybeAlign (4 ));
3481
+
3482
+ disableAddressSanitizer (*this , var);
3483
+ }
3484
+ return nullptr ;
3485
+ }
3486
+
3416
3487
// Define the global variable for the conformance list.
3417
3488
ConstantInitBuilder builder (*this );
3418
3489
auto descriptorArray = builder.beginArray (RelativeAddressTy);
@@ -3434,24 +3505,6 @@ llvm::Constant *IRGenModule::emitProtocolConformances() {
3434
3505
/* isConstant*/ true ,
3435
3506
llvm::GlobalValue::PrivateLinkage);
3436
3507
3437
- StringRef sectionName;
3438
- switch (TargetInfo.OutputObjectFormat ) {
3439
- case llvm::Triple::UnknownObjectFormat:
3440
- llvm_unreachable (" Don't know how to emit protocol conformances for "
3441
- " the selected object format." );
3442
- case llvm::Triple::MachO:
3443
- sectionName = " __TEXT, __swift5_proto, regular, no_dead_strip" ;
3444
- break ;
3445
- case llvm::Triple::ELF:
3446
- case llvm::Triple::Wasm:
3447
- sectionName = " swift5_protocol_conformances" ;
3448
- break ;
3449
- case llvm::Triple::XCOFF:
3450
- case llvm::Triple::COFF:
3451
- sectionName = " .sw5prtc$B" ;
3452
- break ;
3453
- }
3454
-
3455
3508
var->setSection (sectionName);
3456
3509
3457
3510
disableAddressSanitizer (*this , var);
@@ -3466,7 +3519,9 @@ llvm::Constant *IRGenModule::emitTypeMetadataRecords() {
3466
3519
std::string sectionName;
3467
3520
switch (TargetInfo.OutputObjectFormat ) {
3468
3521
case llvm::Triple::MachO:
3469
- sectionName = " __TEXT, __swift5_types, regular, no_dead_strip" ;
3522
+ sectionName = IRGen.Opts .EmitDeadStrippableSymbols
3523
+ ? " __TEXT, __swift5_types, regular, live_support"
3524
+ : " __TEXT, __swift5_types, regular, no_dead_strip" ;
3470
3525
break ;
3471
3526
case llvm::Triple::ELF:
3472
3527
case llvm::Triple::Wasm:
@@ -3485,6 +3540,45 @@ llvm::Constant *IRGenModule::emitTypeMetadataRecords() {
3485
3540
if (RuntimeResolvableTypes.empty ())
3486
3541
return nullptr ;
3487
3542
3543
+ auto generateRecord = [this ](TypeEntityReference ref,
3544
+ llvm::GlobalVariable *var,
3545
+ ArrayRef<unsigned > baseIndices) {
3546
+ // Form the relative address, with the type reference kind in the low bits.
3547
+ llvm::Constant *relativeAddr =
3548
+ emitDirectRelativeReference (ref.getValue (), var, baseIndices);
3549
+ unsigned lowBits = static_cast <unsigned >(ref.getKind ());
3550
+ if (lowBits != 0 ) {
3551
+ relativeAddr = llvm::ConstantExpr::getAdd (
3552
+ relativeAddr, llvm::ConstantInt::get (RelativeAddressTy, lowBits));
3553
+ }
3554
+
3555
+ llvm::Constant *recordFields[] = {relativeAddr};
3556
+ auto record = llvm::ConstantStruct::get (TypeMetadataRecordTy, recordFields);
3557
+ return record;
3558
+ };
3559
+
3560
+ if (IRGen.Opts .EmitDeadStrippableSymbols ) {
3561
+ for (auto type : RuntimeResolvableTypes) {
3562
+ auto ref = getTypeEntityReference (type);
3563
+ auto name =
3564
+ " \x01 l_type_metadata_" + std::string (ref.getValue ()->getName ());
3565
+ auto var = new llvm::GlobalVariable (
3566
+ Module, TypeMetadataRecordTy, /* isConstant*/ true ,
3567
+ llvm::GlobalValue::PrivateLinkage, /* initializer*/ nullptr , name);
3568
+
3569
+ auto record = generateRecord (ref, var, {0 });
3570
+ var->setInitializer (record);
3571
+ var->setSection (sectionName);
3572
+ var->setAlignment (llvm::MaybeAlign (4 ));
3573
+
3574
+ disableAddressSanitizer (*this , var);
3575
+
3576
+ addCompilerUsedGlobal (var);
3577
+ }
3578
+
3579
+ return nullptr ;
3580
+ }
3581
+
3488
3582
// Define the global variable for the conformance list.
3489
3583
// We have to do this before defining the initializer since the entries will
3490
3584
// contain offsets relative to themselves.
@@ -3502,20 +3596,8 @@ llvm::Constant *IRGenModule::emitTypeMetadataRecords() {
3502
3596
SmallVector<llvm::Constant *, 8 > elts;
3503
3597
for (auto type : RuntimeResolvableTypes) {
3504
3598
auto ref = getTypeEntityReference (type);
3505
-
3506
- // Form the relative address, with the type reference kind in the low bits.
3507
3599
unsigned arrayIdx = elts.size ();
3508
- llvm::Constant *relativeAddr =
3509
- emitDirectRelativeReference (ref.getValue (), var, { arrayIdx, 0 });
3510
- unsigned lowBits = static_cast <unsigned >(ref.getKind ());
3511
- if (lowBits != 0 ) {
3512
- relativeAddr = llvm::ConstantExpr::getAdd (relativeAddr,
3513
- llvm::ConstantInt::get (RelativeAddressTy, lowBits));
3514
- }
3515
-
3516
- llvm::Constant *recordFields[] = { relativeAddr };
3517
- auto record = llvm::ConstantStruct::get (TypeMetadataRecordTy,
3518
- recordFields);
3600
+ auto record = generateRecord (ref, var, { arrayIdx, 0 });
3519
3601
elts.push_back (record);
3520
3602
}
3521
3603
@@ -3890,7 +3972,9 @@ llvm::GlobalValue *IRGenModule::defineAlias(LinkEntity entity,
3890
3972
ApplyIRLinkage ({link.getLinkage (), link.getVisibility (), link.getDLLStorage ()})
3891
3973
.to (alias);
3892
3974
3893
- if (link.isUsed ()) {
3975
+ // Everything externally visible is considered used in Swift.
3976
+ // That mostly means we need to be good at not marking things external.
3977
+ if (link.isUsed () && !IRGen.Opts .EmitDeadStrippableSymbols ) {
3894
3978
addUsedGlobal (alias);
3895
3979
}
3896
3980
0 commit comments