@@ -1300,18 +1300,6 @@ static bool replaceModuleFlagsEntry(llvm::LLVMContext &Ctx,
1300
1300
llvm_unreachable (" Could not replace old linker options entry?" );
1301
1301
}
1302
1302
1303
- // / Returns true if the object file generated by \p IGM will be the "first"
1304
- // / object file in the module. This lets us determine where to put a symbol
1305
- // / that must be unique.
1306
- static bool isFirstObjectFileInModule (IRGenModule &IGM) {
1307
- if (IGM.getSILModule ().isWholeModule ())
1308
- return IGM.IRGen .getPrimaryIGM () == &IGM;
1309
-
1310
- auto *file = cast<FileUnit>(IGM.getSILModule ().getAssociatedContext ());
1311
- auto *containingModule = file->getParentModule ();
1312
- return containingModule->getFiles ().front () == file;
1313
- }
1314
-
1315
1303
static bool
1316
1304
doesTargetAutolinkUsingAutolinkExtract (const SwiftTargetInfo &TargetInfo,
1317
1305
const llvm::Triple &Triple) {
@@ -1486,6 +1474,47 @@ AutolinkKind AutolinkKind::create(const SwiftTargetInfo &TargetInfo,
1486
1474
return AutolinkKind::LLVMLinkerOptions;
1487
1475
}
1488
1476
1477
+ static llvm::GlobalObject *createForceImportThunk (IRGenModule &IGM) {
1478
+ llvm::SmallString<64 > buf;
1479
+ encodeForceLoadSymbolName (buf, IGM.IRGen .Opts .ForceLoadSymbolName );
1480
+ if (IGM.Triple .isOSBinFormatMachO ()) {
1481
+ // On Mach-O targets, emit a common force-load symbol that resolves to
1482
+ // a global variable so it will be coalesced at static link time into a
1483
+ // single external symbol.
1484
+ //
1485
+ // Looks like C's tentative definitions are good for something after all.
1486
+ auto ForceImportThunk =
1487
+ new llvm::GlobalVariable (IGM.Module ,
1488
+ IGM.Int1Ty ,
1489
+ /* isConstant=*/ false ,
1490
+ llvm::GlobalValue::CommonLinkage,
1491
+ llvm::Constant::getNullValue (IGM.Int1Ty ),
1492
+ buf.str ());
1493
+ ApplyIRLinkage (IRLinkage::ExternalCommon).to (ForceImportThunk);
1494
+ IGM.addUsedGlobal (ForceImportThunk);
1495
+ return ForceImportThunk;
1496
+ } else {
1497
+ // On all other targets, emit an external symbol that resolves to a
1498
+ // function definition. On Windows, linkonce_odr is basically a no-op and
1499
+ // the COMDAT we set by applying linkage gives us the desired coalescing
1500
+ // behavior.
1501
+ auto ForceImportThunk =
1502
+ llvm::Function::Create (llvm::FunctionType::get (IGM.VoidTy , false ),
1503
+ llvm::GlobalValue::LinkOnceODRLinkage, buf,
1504
+ &IGM.Module );
1505
+ ForceImportThunk->setAttributes (IGM.constructInitialAttributes ());
1506
+ ApplyIRLinkage (IRLinkage::ExternalExport).to (ForceImportThunk);
1507
+ if (IGM.Triple .supportsCOMDAT ())
1508
+ if (auto *GO = cast<llvm::GlobalObject>(ForceImportThunk))
1509
+ GO->setComdat (IGM.Module .getOrInsertComdat (ForceImportThunk->getName ()));
1510
+
1511
+ auto BB = llvm::BasicBlock::Create (IGM.getLLVMContext (), " " , ForceImportThunk);
1512
+ llvm::IRBuilder<> IRB (BB);
1513
+ IRB.CreateRetVoid ();
1514
+ return ForceImportThunk;
1515
+ }
1516
+ }
1517
+
1489
1518
void IRGenModule::emitAutolinkInfo () {
1490
1519
auto Autolink =
1491
1520
AutolinkKind::create (TargetInfo, Triple, IRGen.Opts .LLVMLTOKind );
@@ -1504,23 +1533,8 @@ void IRGenModule::emitAutolinkInfo() {
1504
1533
1505
1534
Autolink.writeEntries (Entries, Metadata, *this );
1506
1535
1507
- if (!IRGen.Opts .ForceLoadSymbolName .empty () &&
1508
- (Triple.supportsCOMDAT () || isFirstObjectFileInModule (*this ))) {
1509
- llvm::SmallString<64 > buf;
1510
- encodeForceLoadSymbolName (buf, IRGen.Opts .ForceLoadSymbolName );
1511
- auto ForceImportThunk =
1512
- llvm::Function::Create (llvm::FunctionType::get (VoidTy, false ),
1513
- llvm::GlobalValue::ExternalLinkage, buf,
1514
- &Module);
1515
- ForceImportThunk->setAttributes (constructInitialAttributes ());
1516
- ApplyIRLinkage (IRLinkage::ExternalExport).to (ForceImportThunk);
1517
- if (Triple.supportsCOMDAT ())
1518
- if (auto *GO = cast<llvm::GlobalObject>(ForceImportThunk))
1519
- GO->setComdat (Module.getOrInsertComdat (ForceImportThunk->getName ()));
1520
-
1521
- auto BB = llvm::BasicBlock::Create (getLLVMContext (), " " , ForceImportThunk);
1522
- llvm::IRBuilder<> IRB (BB);
1523
- IRB.CreateRetVoid ();
1536
+ if (!IRGen.Opts .ForceLoadSymbolName .empty ()) {
1537
+ (void ) createForceImportThunk (*this );
1524
1538
}
1525
1539
}
1526
1540
0 commit comments