@@ -1108,8 +1108,6 @@ llvm::SmallString<32> getTargetDependentLibraryOption(const llvm::Triple &T,
1108
1108
}
1109
1109
1110
1110
void IRGenModule::addLinkLibrary (const LinkLibrary &linkLib) {
1111
- llvm::LLVMContext &ctx = Module.getContext ();
1112
-
1113
1111
// The debugger gets the autolink information directly from
1114
1112
// the LinkLibraries of the module, so there's no reason to
1115
1113
// emit it into the IR of debugger expressions.
@@ -1118,10 +1116,7 @@ void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) {
1118
1116
1119
1117
switch (linkLib.getKind ()) {
1120
1118
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);
1125
1120
break ;
1126
1121
}
1127
1122
case LibraryKind::Framework: {
@@ -1130,12 +1125,7 @@ void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) {
1130
1125
if (std::find (frameworks.begin (), frameworks.end (), linkLib.getName ())
1131
1126
!= frameworks.end ())
1132
1127
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);
1139
1129
break ;
1140
1130
}
1141
1131
}
@@ -1205,63 +1195,197 @@ static bool isFirstObjectFileInModule(IRGenModule &IGM) {
1205
1195
return containingModule->getFiles ().front () == file;
1206
1196
}
1207
1197
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 () {
1210
1245
// 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: {
1231
1313
// On platforms that support autolinking, continue to use the metadata.
1232
1314
Metadata->clearOperands ();
1233
- for (auto *Entry : AutolinkEntries )
1315
+ for (auto *Entry : Entries )
1234
1316
Metadata->addOperand (Entry);
1235
- } else {
1317
+ return ;
1318
+ }
1319
+ case AutolinkKind::SwiftAutoLinkExtract: {
1236
1320
// Merge the entries into null-separated string.
1237
1321
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);
1240
1324
for (auto &Entry : MD->operands ()) {
1241
1325
const llvm::MDString *MS = cast<llvm::MDString>(Entry);
1242
1326
EntriesString += MS->getString ();
1243
1327
EntriesString += ' \0 ' ;
1244
1328
}
1245
1329
}
1246
1330
auto EntriesConstant = llvm::ConstantDataArray::getString (
1247
- getLLVMContext (), EntriesString, /* AddNull=*/ false );
1331
+ IGM. getLLVMContext (), EntriesString, /* AddNull=*/ false );
1248
1332
// Mark the swift1_autolink_entries section with the SHF_EXCLUDE attribute
1249
1333
// 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\" " );
1255
1339
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,
1258
1342
EntriesConstant, " _swift1_autolink_entries" );
1259
1343
var->setSection (" .swift1_autolink_entries" );
1260
- var->setAlignment (llvm::MaybeAlign (getPointerAlignment ().getValue ()));
1344
+ var->setAlignment (llvm::MaybeAlign (IGM. getPointerAlignment ().getValue ()));
1261
1345
1262
- disableAddressSanitizer (*this , var);
1263
- addUsedGlobal (var);
1346
+ disableAddressSanitizer (IGM, var);
1347
+ IGM.addUsedGlobal (var);
1348
+ return ;
1264
1349
}
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 );
1265
1389
1266
1390
if (!IRGen.Opts .ForceLoadSymbolName .empty () &&
1267
1391
(Triple.supportsCOMDAT () || isFirstObjectFileInModule (*this ))) {
0 commit comments