@@ -538,7 +538,8 @@ std::unique_ptr<lto::LTO> createLTO(
538
538
const ArgList &Args, const std::vector<std::string> &Features,
539
539
ModuleHook Hook = [](size_t , const Module &) { return true ; }) {
540
540
const llvm::Triple Triple (Args.getLastArgValue (OPT_triple_EQ));
541
- StringRef Arch = Args.getLastArgValue (OPT_arch_EQ);
541
+ // We need to remove AMD's target-id from the processor if present.
542
+ StringRef Arch = Args.getLastArgValue (OPT_arch_EQ).split (" :" ).first ;
542
543
lto::Config Conf;
543
544
lto::ThinBackend Backend;
544
545
// TODO: Handle index-only thin-LTO
@@ -1066,24 +1067,14 @@ DerivedArgList getLinkerArgs(ArrayRef<OffloadFile> Input,
1066
1067
1067
1068
// / Transforms all the extracted offloading input files into an image that can
1068
1069
// / be registered by the runtime.
1069
- Expected<SmallVector<StringRef>>
1070
- linkAndWrapDeviceFiles ( SmallVectorImpl<OffloadFile> &LinkerInputFiles,
1071
- const InputArgList &Args, char **Argv, int Argc) {
1070
+ Expected<SmallVector<StringRef>> linkAndWrapDeviceFiles (
1071
+ SmallVectorImpl<SmallVector< OffloadFile> > &LinkerInputFiles,
1072
+ const InputArgList &Args, char **Argv, int Argc) {
1072
1073
llvm::TimeTraceScope TimeScope (" Handle all device input" );
1073
1074
1074
- DenseMap<OffloadFile::TargetID, SmallVector<OffloadFile>> InputMap;
1075
- for (auto &File : LinkerInputFiles)
1076
- InputMap[File].emplace_back (std::move (File));
1077
- LinkerInputFiles.clear ();
1078
-
1079
- SmallVector<SmallVector<OffloadFile>> InputsForTarget;
1080
- for (auto &[ID, Input] : InputMap)
1081
- InputsForTarget.emplace_back (std::move (Input));
1082
- InputMap.clear ();
1083
-
1084
1075
std::mutex ImageMtx;
1085
1076
DenseMap<OffloadKind, SmallVector<OffloadingImage>> Images;
1086
- auto Err = parallelForEachError (InputsForTarget , [&](auto &Input) -> Error {
1077
+ auto Err = parallelForEachError (LinkerInputFiles , [&](auto &Input) -> Error {
1087
1078
llvm::TimeTraceScope TimeScope (" Link device input" );
1088
1079
1089
1080
// Each thread needs its own copy of the base arguments to maintain
@@ -1359,8 +1350,9 @@ Expected<bool> getSymbols(StringRef Image, OffloadKind Kind, bool IsArchive,
1359
1350
// / Search the input files and libraries for embedded device offloading code
1360
1351
// / and add it to the list of files to be linked. Files coming from static
1361
1352
// / libraries are only added to the input if they are used by an existing
1362
- // / input file.
1363
- Expected<SmallVector<OffloadFile>> getDeviceInput (const ArgList &Args) {
1353
+ // / input file. Returns a list of input files intended for a single linking job.
1354
+ Expected<SmallVector<SmallVector<OffloadFile>>>
1355
+ getDeviceInput (const ArgList &Args) {
1364
1356
llvm::TimeTraceScope TimeScope (" ExtractDeviceCode" );
1365
1357
1366
1358
StringRef Root = Args.getLastArgValue (OPT_sysroot_EQ);
@@ -1372,7 +1364,7 @@ Expected<SmallVector<OffloadFile>> getDeviceInput(const ArgList &Args) {
1372
1364
StringSaver Saver (Alloc);
1373
1365
1374
1366
// Try to extract device code from the linker input files.
1375
- SmallVector<OffloadFile> InputFiles;
1367
+ DenseMap<OffloadFile::TargetID, SmallVector<OffloadFile> > InputFiles;
1376
1368
DenseMap<OffloadFile::TargetID, DenseMap<StringRef, Symbol>> Syms;
1377
1369
bool WholeArchive = Args.hasArg (OPT_wholearchive_flag) ? true : false ;
1378
1370
for (const opt::Arg *Arg : Args.filtered (
@@ -1416,25 +1408,39 @@ Expected<SmallVector<OffloadFile>> getDeviceInput(const ArgList &Args) {
1416
1408
while (Extracted) {
1417
1409
Extracted = false ;
1418
1410
for (OffloadFile &Binary : Binaries) {
1411
+ // If the binary was previously extracted it will be set to null.
1419
1412
if (!Binary.getBinary ())
1420
1413
continue ;
1421
1414
1422
- // If we don't have an object file for this architecture do not
1423
- // extract.
1424
- if (IsArchive && !WholeArchive && !Syms.count (Binary))
1425
- continue ;
1426
-
1427
- Expected<bool > ExtractOrErr =
1428
- getSymbols (Binary.getBinary ()->getImage (),
1429
- Binary.getBinary ()->getOffloadKind (), IsArchive, Saver,
1430
- Syms[Binary]);
1431
- if (!ExtractOrErr)
1432
- return ExtractOrErr.takeError ();
1433
-
1434
- Extracted = !WholeArchive && *ExtractOrErr;
1435
-
1436
- if (!IsArchive || WholeArchive || Extracted)
1437
- InputFiles.emplace_back (std::move (Binary));
1415
+ SmallVector<OffloadFile::TargetID> CompatibleTargets = {Binary};
1416
+ for (const auto &[ID, Input] : InputFiles)
1417
+ if (object::areTargetsCompatible (Binary, ID))
1418
+ CompatibleTargets.emplace_back (ID);
1419
+
1420
+ for (const auto &[Index, ID] : llvm::enumerate (CompatibleTargets)) {
1421
+ // Only extract an if we have an an object matching this target.
1422
+ if (IsArchive && !WholeArchive && !InputFiles.count (ID))
1423
+ continue ;
1424
+
1425
+ Expected<bool > ExtractOrErr = getSymbols (
1426
+ Binary.getBinary ()->getImage (),
1427
+ Binary.getBinary ()->getOffloadKind (), IsArchive, Saver, Syms[ID]);
1428
+ if (!ExtractOrErr)
1429
+ return ExtractOrErr.takeError ();
1430
+
1431
+ Extracted = !WholeArchive && *ExtractOrErr;
1432
+
1433
+ // Skip including the file if it is an archive that does not resolve
1434
+ // any symbols.
1435
+ if (IsArchive && !WholeArchive && !Extracted)
1436
+ continue ;
1437
+
1438
+ // If another target needs this binary it must be copied instead.
1439
+ if (Index == CompatibleTargets.size () - 1 )
1440
+ InputFiles[ID].emplace_back (std::move (Binary));
1441
+ else
1442
+ InputFiles[ID].emplace_back (std::move (Binary.copy ()));
1443
+ }
1438
1444
1439
1445
// If we extracted any files we need to check all the symbols again.
1440
1446
if (Extracted)
@@ -1447,10 +1453,14 @@ Expected<SmallVector<OffloadFile>> getDeviceInput(const ArgList &Args) {
1447
1453
auto FileOrErr = getInputBitcodeLibrary (Library);
1448
1454
if (!FileOrErr)
1449
1455
return FileOrErr.takeError ();
1450
- InputFiles.push_back (std::move (*FileOrErr));
1456
+ InputFiles[*FileOrErr] .push_back (std::move (*FileOrErr));
1451
1457
}
1452
1458
1453
- return std::move (InputFiles);
1459
+ SmallVector<SmallVector<OffloadFile>> InputsForTarget;
1460
+ for (auto &[ID, Input] : InputFiles)
1461
+ InputsForTarget.emplace_back (std::move (Input));
1462
+
1463
+ return std::move (InputsForTarget);
1454
1464
}
1455
1465
1456
1466
} // namespace
0 commit comments