@@ -1300,18 +1300,6 @@ static bool replaceModuleFlagsEntry(llvm::LLVMContext &Ctx,
13001300 llvm_unreachable (" Could not replace old linker options entry?" );
13011301}
13021302
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-
13151303static bool
13161304doesTargetAutolinkUsingAutolinkExtract (const SwiftTargetInfo &TargetInfo,
13171305 const llvm::Triple &Triple) {
@@ -1486,6 +1474,47 @@ AutolinkKind AutolinkKind::create(const SwiftTargetInfo &TargetInfo,
14861474 return AutolinkKind::LLVMLinkerOptions;
14871475}
14881476
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+
14891518void IRGenModule::emitAutolinkInfo () {
14901519 auto Autolink =
14911520 AutolinkKind::create (TargetInfo, Triple, IRGen.Opts .LLVMLTOKind );
@@ -1504,23 +1533,8 @@ void IRGenModule::emitAutolinkInfo() {
15041533
15051534 Autolink.writeEntries (Entries, Metadata, *this );
15061535
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 );
15241538 }
15251539}
15261540
0 commit comments