@@ -1108,8 +1108,6 @@ llvm::SmallString<32> getTargetDependentLibraryOption(const llvm::Triple &T,
11081108}
11091109
11101110void IRGenModule::addLinkLibrary (const LinkLibrary &linkLib) {
1111- llvm::LLVMContext &ctx = Module.getContext ();
1112-
11131111 // The debugger gets the autolink information directly from
11141112 // the LinkLibraries of the module, so there's no reason to
11151113 // emit it into the IR of debugger expressions.
@@ -1118,10 +1116,7 @@ void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) {
11181116
11191117 switch (linkLib.getKind ()) {
11201118 case LibraryKind::Library: {
1121- llvm::SmallString<32 > opt =
1122- getTargetDependentLibraryOption (Triple, linkLib.getName ());
1123- AutolinkEntries.push_back (
1124- llvm::MDNode::get (ctx, llvm::MDString::get (ctx, opt)));
1119+ AutolinkEntries.emplace_back (linkLib);
11251120 break ;
11261121 }
11271122 case LibraryKind::Framework: {
@@ -1130,12 +1125,7 @@ void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) {
11301125 if (std::find (frameworks.begin (), frameworks.end (), linkLib.getName ())
11311126 != frameworks.end ())
11321127 return ;
1133-
1134- llvm::Metadata *args[] = {
1135- llvm::MDString::get (ctx, " -framework" ),
1136- llvm::MDString::get (ctx, linkLib.getName ())
1137- };
1138- AutolinkEntries.push_back (llvm::MDNode::get (ctx, args));
1128+ AutolinkEntries.emplace_back (linkLib);
11391129 break ;
11401130 }
11411131 }
@@ -1205,63 +1195,197 @@ static bool isFirstObjectFileInModule(IRGenModule &IGM) {
12051195 return containingModule->getFiles ().front () == file;
12061196}
12071197
1208- void IRGenModule::emitAutolinkInfo () {
1209- // Collect the linker options already in the module (from ClangCodeGen).
1198+ static bool
1199+ doesTargetAutolinkUsingAutolinkExtract (const SwiftTargetInfo &TargetInfo,
1200+ const llvm::Triple &Triple) {
1201+ if (TargetInfo.OutputObjectFormat == llvm::Triple::ELF && !Triple.isPS4 ())
1202+ return true ;
1203+
1204+ if (TargetInfo.OutputObjectFormat == llvm::Triple::Wasm)
1205+ return true ;
1206+
1207+ if (Triple.isOSCygMing ())
1208+ return true ;
1209+
1210+ return false ;
1211+ }
1212+
1213+ namespace {
1214+
1215+ struct AutolinkKind {
1216+ enum ValueTy {
1217+ LLVMLinkerOptions,
1218+ LLVMDependentLibraries,
1219+ SwiftAutoLinkExtract,
1220+ };
1221+
1222+ ValueTy Value;
1223+
1224+ AutolinkKind (ValueTy value) : Value(value) {}
1225+ AutolinkKind (const AutolinkKind &kind) : Value(kind.Value) {}
1226+
1227+ StringRef getSectionNameMetadata ();
1228+
1229+ template <typename Vector, typename Set>
1230+ void collectEntriesFromLibraries (llvm::SetVector<llvm::MDNode *, Vector, Set> &Entries,
1231+ ArrayRef<LinkLibrary> AutolinkEntries,
1232+ IRGenModule &IGM);
1233+
1234+ template <typename Vector, typename Set>
1235+ void writeEntries (llvm::SetVector<llvm::MDNode *, Vector, Set> Entries,
1236+ llvm::NamedMDNode *Metadata, IRGenModule &IGM);
1237+
1238+ static AutolinkKind create (const SwiftTargetInfo &TargetInfo,
1239+ llvm::Triple Triple, IRGenLLVMLTOKind LLVMLTOKind);
1240+ };
1241+
1242+ } // anonymous namespace
1243+
1244+ StringRef AutolinkKind::getSectionNameMetadata () {
12101245 // FIXME: This constant should be vended by LLVM somewhere.
1211- auto *Metadata = Module.getOrInsertNamedMetadata (" llvm.linker.options" );
1212- for (llvm::MDNode *LinkOption : Metadata->operands ())
1213- AutolinkEntries.push_back (LinkOption);
1214-
1215- // Remove duplicates.
1216- llvm::SmallPtrSet<llvm::MDNode *, 4 > knownAutolinkEntries;
1217- AutolinkEntries.erase (std::remove_if (AutolinkEntries.begin (),
1218- AutolinkEntries.end (),
1219- [&](llvm::MDNode *entry) -> bool {
1220- return !knownAutolinkEntries.insert (
1221- entry).second ;
1222- }),
1223- AutolinkEntries.end ());
1224-
1225- const bool AutolinkExtractRequired =
1226- (TargetInfo.OutputObjectFormat == llvm::Triple::ELF && !Triple.isPS4 ()) ||
1227- TargetInfo.OutputObjectFormat == llvm::Triple::Wasm ||
1228- Triple.isOSCygMing ();
1229-
1230- if (!AutolinkExtractRequired) {
1246+ switch (Value) {
1247+ case AutolinkKind::LLVMDependentLibraries:
1248+ return " llvm.dependent-libraries" ;
1249+ case AutolinkKind::LLVMLinkerOptions:
1250+ case AutolinkKind::SwiftAutoLinkExtract:
1251+ return " llvm.linker.options" ;
1252+ }
1253+
1254+ llvm_unreachable (" Unhandled AutolinkKind in switch." );
1255+ }
1256+
1257+ template <typename Vector, typename Set>
1258+ void AutolinkKind::collectEntriesFromLibraries (
1259+ llvm::SetVector<llvm::MDNode *, Vector, Set> &Entries,
1260+ ArrayRef<LinkLibrary> AutolinkEntries, IRGenModule &IGM) {
1261+ llvm::LLVMContext &ctx = IGM.getLLVMContext ();
1262+
1263+ switch (Value) {
1264+ case AutolinkKind::LLVMLinkerOptions:
1265+ case AutolinkKind::SwiftAutoLinkExtract: {
1266+ // On platforms that support autolinking, continue to use the metadata.
1267+ for (LinkLibrary linkLib : AutolinkEntries) {
1268+ switch (linkLib.getKind ()) {
1269+ case LibraryKind::Library: {
1270+ llvm::SmallString<32 > opt =
1271+ getTargetDependentLibraryOption (IGM.Triple , linkLib.getName ());
1272+ Entries.insert (llvm::MDNode::get (ctx, llvm::MDString::get (ctx, opt)));
1273+ continue ;
1274+ }
1275+ case LibraryKind::Framework: {
1276+ llvm::Metadata *args[] = {llvm::MDString::get (ctx, " -framework" ),
1277+ llvm::MDString::get (ctx, linkLib.getName ())};
1278+ Entries.insert (llvm::MDNode::get (ctx, args));
1279+ continue ;
1280+ }
1281+ }
1282+ llvm_unreachable (" Unhandled LibraryKind in switch." );
1283+ }
1284+ return ;
1285+ }
1286+ case AutolinkKind::LLVMDependentLibraries: {
1287+ for (LinkLibrary linkLib : AutolinkEntries) {
1288+ switch (linkLib.getKind ()) {
1289+ case LibraryKind::Library: {
1290+ Entries.insert (llvm::MDNode::get (
1291+ ctx, llvm::MDString::get (ctx, linkLib.getName ())));
1292+ continue ;
1293+ }
1294+ case LibraryKind::Framework: {
1295+ llvm_unreachable (
1296+ " llvm.dependent-libraries doesn't support framework dependency" );
1297+ }
1298+ }
1299+ llvm_unreachable (" Unhandled LibraryKind in switch." );
1300+ }
1301+ return ;
1302+ }
1303+ }
1304+ llvm_unreachable (" Unhandled AutolinkKind in switch." );
1305+ }
1306+
1307+ template <typename Vector, typename Set>
1308+ void AutolinkKind::writeEntries (llvm::SetVector<llvm::MDNode *, Vector, Set> Entries,
1309+ llvm::NamedMDNode *Metadata, IRGenModule &IGM) {
1310+ switch (Value) {
1311+ case AutolinkKind::LLVMLinkerOptions:
1312+ case AutolinkKind::LLVMDependentLibraries: {
12311313 // On platforms that support autolinking, continue to use the metadata.
12321314 Metadata->clearOperands ();
1233- for (auto *Entry : AutolinkEntries )
1315+ for (auto *Entry : Entries )
12341316 Metadata->addOperand (Entry);
1235- } else {
1317+ return ;
1318+ }
1319+ case AutolinkKind::SwiftAutoLinkExtract: {
12361320 // Merge the entries into null-separated string.
12371321 llvm::SmallString<64 > EntriesString;
1238- for (auto & EntryNode : AutolinkEntries ) {
1239- const llvm::MDNode *MD = cast<llvm::MDNode>(EntryNode);
1322+ for (auto EntryNode : Entries ) {
1323+ const auto *MD = cast<llvm::MDNode>(EntryNode);
12401324 for (auto &Entry : MD->operands ()) {
12411325 const llvm::MDString *MS = cast<llvm::MDString>(Entry);
12421326 EntriesString += MS->getString ();
12431327 EntriesString += ' \0 ' ;
12441328 }
12451329 }
12461330 auto EntriesConstant = llvm::ConstantDataArray::getString (
1247- getLLVMContext (), EntriesString, /* AddNull=*/ false );
1331+ IGM. getLLVMContext (), EntriesString, /* AddNull=*/ false );
12481332 // Mark the swift1_autolink_entries section with the SHF_EXCLUDE attribute
12491333 // to get the linker to drop it in the final linked binary.
1250- // LLVM doesn't provide an interface to specify section attributs in the IR
1251- // so we pass the attribute with inline assembly.
1252- if (TargetInfo.OutputObjectFormat == llvm::Triple::ELF)
1253- Module.appendModuleInlineAsm (" .section .swift1_autolink_entries,"
1254- " \" 0x80000000\" " );
1334+ // LLVM doesn't provide an interface to specify section attributs in the
1335+ // IR so we pass the attribute with inline assembly.
1336+ if (IGM. TargetInfo .OutputObjectFormat == llvm::Triple::ELF)
1337+ IGM. Module .appendModuleInlineAsm (" .section .swift1_autolink_entries,"
1338+ " \" 0x80000000\" " );
12551339 auto var =
1256- new llvm::GlobalVariable (*getModule (), EntriesConstant->getType (), true ,
1257- llvm::GlobalValue::PrivateLinkage,
1340+ new llvm::GlobalVariable (*IGM. getModule (), EntriesConstant->getType (),
1341+ true , llvm::GlobalValue::PrivateLinkage,
12581342 EntriesConstant, " _swift1_autolink_entries" );
12591343 var->setSection (" .swift1_autolink_entries" );
1260- var->setAlignment (llvm::MaybeAlign (getPointerAlignment ().getValue ()));
1344+ var->setAlignment (llvm::MaybeAlign (IGM. getPointerAlignment ().getValue ()));
12611345
1262- disableAddressSanitizer (*this , var);
1263- addUsedGlobal (var);
1346+ disableAddressSanitizer (IGM, var);
1347+ IGM.addUsedGlobal (var);
1348+ return ;
12641349 }
1350+ }
1351+ llvm_unreachable (" Unhandled AutolinkKind in switch." );
1352+ }
1353+
1354+ AutolinkKind AutolinkKind::create (const SwiftTargetInfo &TargetInfo,
1355+ llvm::Triple Triple,
1356+ IRGenLLVMLTOKind LLVMLTOKind) {
1357+ // When performing LTO, we always use lld that supports auto linking
1358+ // mechanism with ELF. So embed dependent libraries names in
1359+ // "llvm.dependent-libraries" instead of "llvm.linker.options".
1360+ if (TargetInfo.OutputObjectFormat == llvm::Triple::ELF &&
1361+ LLVMLTOKind != IRGenLLVMLTOKind::None) {
1362+ return AutolinkKind::LLVMDependentLibraries;
1363+ }
1364+
1365+ if (doesTargetAutolinkUsingAutolinkExtract (TargetInfo, Triple)) {
1366+ return AutolinkKind::SwiftAutoLinkExtract;
1367+ }
1368+
1369+ return AutolinkKind::LLVMLinkerOptions;
1370+ }
1371+
1372+ void IRGenModule::emitAutolinkInfo () {
1373+ auto Autolink =
1374+ AutolinkKind::create (TargetInfo, Triple, IRGen.Opts .LLVMLTOKind );
1375+
1376+ StringRef AutolinkSectionName = Autolink.getSectionNameMetadata ();
1377+
1378+ auto *Metadata = Module.getOrInsertNamedMetadata (AutolinkSectionName);
1379+ llvm::SmallSetVector<llvm::MDNode *, 4 > Entries;
1380+
1381+ // Collect the linker options already in the module (from ClangCodeGen).
1382+ for (auto Entry : Metadata->operands ()) {
1383+ Entries.insert (Entry);
1384+ }
1385+
1386+ Autolink.collectEntriesFromLibraries (Entries, AutolinkEntries, *this );
1387+
1388+ Autolink.writeEntries (Entries, Metadata, *this );
12651389
12661390 if (!IRGen.Opts .ForceLoadSymbolName .empty () &&
12671391 (Triple.supportsCOMDAT () || isFirstObjectFileInModule (*this ))) {
0 commit comments