diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6936,7 +6936,9 @@ StringRef InputName = Clang::getBaseInputStem(Args, Inputs); CmdArgs.push_back(Args.MakeArgString( - "-fembed-offload-object=" + File + "," + TC->getTripleString() + "." + + "-fembed-offload-object=" + File + "," + + Action::GetOffloadKindName(Action::OFK_OpenMP) + "." + + TC->getTripleString() + "." + TCArgs.getLastArgValue(options::OPT_march_EQ) + "." + InputName)); } } diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -151,15 +151,43 @@ /// Information for a device offloading file extracted from the host. struct DeviceFile { - DeviceFile(StringRef TheTriple, StringRef Arch, StringRef Filename) - : TheTriple(TheTriple), Arch(Arch), Filename(Filename) {} - - const std::string TheTriple; - const std::string Arch; - const std::string Filename; + DeviceFile(StringRef OffloadKind, StringRef TheTriple, StringRef Arch, + StringRef Filename) + : OffloadKind(OffloadKind), TheTriple(TheTriple), Arch(Arch), + Filename(Filename) {} + + std::string OffloadKind; + std::string TheTriple; + std::string Arch; + std::string Filename; +}; - operator std::string() const { return TheTriple + "-" + Arch; } +namespace llvm { +/// Helper that allows DeviceFile to be used as a key in a DenseMap. +template <> struct DenseMapInfo { + static DeviceFile getEmptyKey() { + return {DenseMapInfo::getEmptyKey(), + DenseMapInfo::getEmptyKey(), + DenseMapInfo::getEmptyKey(), + DenseMapInfo::getEmptyKey()}; + } + static DeviceFile getTombstoneKey() { + return {DenseMapInfo::getTombstoneKey(), + DenseMapInfo::getTombstoneKey(), + DenseMapInfo::getTombstoneKey(), + DenseMapInfo::getTombstoneKey()}; + } + static unsigned getHashValue(const DeviceFile &I) { + return DenseMapInfo::getHashValue(I.OffloadKind) ^ + DenseMapInfo::getHashValue(I.TheTriple) ^ + DenseMapInfo::getHashValue(I.Arch); + } + static bool isEqual(const DeviceFile &LHS, const DeviceFile &RHS) { + return LHS.OffloadKind == RHS.OffloadKind && + LHS.TheTriple == RHS.TheTriple && LHS.Arch == RHS.Arch; + } }; +} // namespace llvm namespace { @@ -187,7 +215,7 @@ DeviceFile getBitcodeLibrary(StringRef LibraryStr) { auto DeviceAndPath = StringRef(LibraryStr).split('='); auto TripleAndArch = DeviceAndPath.first.rsplit('-'); - return DeviceFile(TripleAndArch.first, TripleAndArch.second, + return DeviceFile("openmp", TripleAndArch.first, TripleAndArch.second, DeviceAndPath.second); } @@ -266,16 +294,17 @@ SmallVector SectionFields; Name->split(SectionFields, '.'); - StringRef DeviceTriple = SectionFields[3]; - StringRef Arch = SectionFields[4]; + StringRef Kind = SectionFields[3]; + StringRef DeviceTriple = SectionFields[4]; + StringRef Arch = SectionFields[5]; if (Expected Contents = Sec.getContents()) { SmallString<128> TempFile; StringRef DeviceExtension = getDeviceFileExtension( DeviceTriple, identify_magic(*Contents) == file_magic::bitcode); - if (Error Err = - createOutputFile(Prefix + "-device-" + DeviceTriple + "-" + Arch, - DeviceExtension, TempFile)) + if (Error Err = createOutputFile(Prefix + "-" + Kind + "-" + + DeviceTriple + "-" + Arch, + DeviceExtension, TempFile)) return std::move(Err); Expected> OutputOrErr = @@ -287,7 +316,7 @@ if (Error E = Output->commit()) return std::move(E); - DeviceFiles.emplace_back(DeviceTriple, Arch, TempFile); + DeviceFiles.emplace_back(Kind, DeviceTriple, Arch, TempFile); ToBeStripped.push_back(*Name); } } @@ -376,6 +405,7 @@ SmallVector SectionFields; GV.getSection().split(SectionFields, '.'); + StringRef Kind = SectionFields[3]; StringRef DeviceTriple = SectionFields[3]; StringRef Arch = SectionFields[4]; @@ -383,9 +413,9 @@ SmallString<128> TempFile; StringRef DeviceExtension = getDeviceFileExtension( DeviceTriple, identify_magic(Contents) == file_magic::bitcode); - if (Error Err = - createOutputFile(Prefix + "-device-" + DeviceTriple + "-" + Arch, - DeviceExtension, TempFile)) + if (Error Err = createOutputFile(Prefix + "-" + Kind + "-" + DeviceTriple + + "-" + Arch, + DeviceExtension, TempFile)) return std::move(Err); Expected> OutputOrErr = @@ -397,7 +427,7 @@ if (Error E = Output->commit()) return std::move(E); - DeviceFiles.emplace_back(DeviceTriple, Arch, TempFile); + DeviceFiles.emplace_back(Kind, DeviceTriple, Arch, TempFile); ToBeDeleted.push_back(&GV); } @@ -1035,28 +1065,28 @@ Error linkDeviceFiles(ArrayRef DeviceFiles, SmallVectorImpl &LinkedImages) { // Get the list of inputs for a specific device. - StringMap> LinkerInputMap; + DenseMap> LinkerInputMap; for (auto &File : DeviceFiles) - LinkerInputMap[StringRef(File)].push_back(File.Filename); + LinkerInputMap[File].push_back(File.Filename); // Try to link each device toolchain. for (auto &LinkerInput : LinkerInputMap) { - auto TargetFeatures = LinkerInput.getKey().rsplit('-'); - Triple TheTriple(TargetFeatures.first); - StringRef Arch(TargetFeatures.second); + DeviceFile &File = LinkerInput.getFirst(); + Triple TheTriple = Triple(File.TheTriple); // Run LTO on any bitcode files and replace the input with the result. - if (Error Err = linkBitcodeFiles(LinkerInput.getValue(), TheTriple, Arch)) + if (Error Err = + linkBitcodeFiles(LinkerInput.getSecond(), TheTriple, File.Arch)) return Err; // If we are embedding bitcode for JIT, skip the final device linking. if (EmbedBitcode) { - assert(!LinkerInput.getValue().empty() && "No bitcode image to embed"); - LinkedImages.push_back(LinkerInput.getValue().front()); + assert(!LinkerInput.getSecond().empty() && "No bitcode image to embed"); + LinkedImages.push_back(LinkerInput.getSecond().front()); continue; } - auto ImageOrErr = linkDevice(LinkerInput.getValue(), TheTriple, Arch); + auto ImageOrErr = linkDevice(LinkerInput.getSecond(), TheTriple, File.Arch); if (!ImageOrErr) return ImageOrErr.takeError();