From 9375f1563e87e115cc8f9d052760d68460889f4e Mon Sep 17 00:00:00 2001 From: Joseph Huber Date: Tue, 25 Jan 2022 11:23:27 -0500 Subject: [PATCH] [OpenMP] Cleanup the Linker Wrapper Summary: Various changes and cleanup for the Linker Wrapper tool. --- clang/lib/Driver/ToolChains/Clang.cpp | 13 ++-- .../clang-linker-wrapper/ClangLinkerWrapper.cpp | 88 +++++++++------------- 2 files changed, 43 insertions(+), 58 deletions(-) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 537b9ca..7aac977 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -8153,9 +8153,9 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, if (getToolChain().getDriver().isUsingLTO(/* IsOffload */ true)) { // Pass in target features for each toolchain. auto OpenMPTCRange = C.getOffloadToolChains(); - for (auto TI = OpenMPTCRange.first, TE = OpenMPTCRange.second; TI != TE; - ++TI) { - const ToolChain *TC = TI->second; + for (auto &I : + llvm::make_range(OpenMPTCRange.first, OpenMPTCRange.second)) { + const ToolChain *TC = I.second; const ArgList &TCArgs = C.getArgsForToolChain(TC, "", Action::OFK_OpenMP); ArgStringList FeatureArgs; TC->addClangTargetOptions(TCArgs, FeatureArgs, Action::OFK_OpenMP); @@ -8165,9 +8165,8 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, } // Pass in the bitcode library to be linked during LTO. - for (auto TI = OpenMPTCRange.first, TE = OpenMPTCRange.second; TI != TE; - ++TI) { - const ToolChain *TC = TI->second; + for (auto &I : llvm::make_range(OpenMPTCRange.first, OpenMPTCRange.second)) { + const ToolChain *TC = I.second; const Driver &D = TC->getDriver(); const ArgList &TCArgs = C.getArgsForToolChain(TC, "", Action::OFK_OpenMP); StringRef Arch = TCArgs.getLastArgValue(options::OPT_march_EQ); @@ -8232,7 +8231,7 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA, } for (const auto &A : Args.getAllArgValues(options::OPT_Xcuda_ptxas)) - CmdArgs.push_back(Args.MakeArgString("-ptxas-option=" + A)); + CmdArgs.push_back(Args.MakeArgString("-ptxas-args=" + A)); // Forward remarks passes to the LLVM backend in the wrapper. if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ)) diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index 8339351..1dd95cb 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -78,10 +78,10 @@ static cl::opt OptLevel("opt-level", cl::ZeroOrMore, cl::init("O2"), cl::cat(ClangLinkerWrapperCategory)); -static cl::opt - BitcodeLibrary("target-library", cl::ZeroOrMore, - cl::desc("Path for the target bitcode library"), - cl::cat(ClangLinkerWrapperCategory)); +static cl::list + BitcodeLibraries("target-library", cl::ZeroOrMore, + cl::desc("Path for the target bitcode library"), + cl::cat(ClangLinkerWrapperCategory)); static cl::opt EmbedBitcode( "target-embed-bc", cl::ZeroOrMore, @@ -94,8 +94,8 @@ static cl::opt cl::init(sys::getDefaultTargetTriple()), cl::cat(ClangLinkerWrapperCategory)); -static cl::opt - PtxasOption("ptxas-option", cl::ZeroOrMore, +static cl::list + PtxasArgs("ptxas-args", cl::ZeroOrMore, cl::desc("Argument to pass to the ptxas invocation"), cl::cat(ClangLinkerWrapperCategory)); @@ -164,6 +164,15 @@ static StringRef getDeviceFileExtension(StringRef DeviceTriple, return "o"; } +/// Extract the device file from the string '-=.bc'. +DeviceFile getBitcodeLibrary(StringRef LibraryStr) { + auto DeviceAndPath = StringRef(LibraryStr).split('='); + auto TripleAndArch = DeviceAndPath.first.rsplit('-'); + return DeviceFile(TripleAndArch.first, TripleAndArch.second, + DeviceAndPath.second); +} + +/// Get a temporary filename suitable for output. Error createOutputFile(const Twine &Prefix, StringRef Extension, SmallString<128> &NewFilename) { if (!SaveTemps) { @@ -264,7 +273,7 @@ extractFromBinary(const ObjectFile &Obj, } } - if (ToBeStripped.empty()) + if (ToBeStripped.empty() || !StripSections) return None; // If the object file to strip doesn't exist we need to write it so we can @@ -272,8 +281,9 @@ extractFromBinary(const ObjectFile &Obj, SmallString<128> StripFile = Obj.getFileName(); if (!sys::fs::exists(StripFile)) { SmallString<128> TempFile; - if (Error Err = createOutputFile(sys::path::stem(StripFile), - sys::path::extension(StripFile), TempFile)) + if (Error Err = createOutputFile( + sys::path::stem(StripFile), + sys::path::extension(StripFile).drop_front(), TempFile)) return std::move(Err); auto Contents = Obj.getMemoryBufferRef().getBuffer(); @@ -370,7 +380,7 @@ extractFromBitcode(std::unique_ptr Buffer, ToBeDeleted.push_back(&GV); } - if (ToBeDeleted.empty()) + if (ToBeDeleted.empty() || !StripSections) return None; // We need to materialize the lazy module before we make any changes. @@ -398,7 +408,6 @@ extractFromBitcode(std::unique_ptr Buffer, Expected> extractFromArchive(const Archive &Library, SmallVectorImpl &DeviceFiles) { - bool NewMembers = false; SmallVector Members; @@ -442,7 +451,7 @@ extractFromArchive(const Archive &Library, if (Err) return std::move(Err); - if (!NewMembers) + if (!NewMembers || !StripSections) return None; // Create a new static library using the stripped host files. @@ -512,7 +521,6 @@ Expected assemble(StringRef InputFile, Triple TheTriple, "cubin", TempFile)) return std::move(Err); - // TODO: Pass in arguments like `-g` and `-v` from the driver. SmallVector CmdArgs; std::string Opt = "-" + OptLevel; CmdArgs.push_back(*PtxasPath); @@ -523,8 +531,8 @@ Expected assemble(StringRef InputFile, Triple TheTriple, CmdArgs.push_back("-lineinfo"); else if (DebugInfo == FullDebugInfo && OptLevel[1] == '0') CmdArgs.push_back("-g"); - if (!PtxasOption.empty()) - CmdArgs.push_back(PtxasOption); + for (auto &Arg : PtxasArgs) + CmdArgs.push_back(Arg); CmdArgs.push_back("-o"); CmdArgs.push_back(TempFile); CmdArgs.push_back(Opt); @@ -540,8 +548,7 @@ Expected assemble(StringRef InputFile, Triple TheTriple, return static_cast(TempFile); } -Expected link(ArrayRef InputFiles, - ArrayRef LinkerArgs, Triple TheTriple, +Expected link(ArrayRef InputFiles, Triple TheTriple, StringRef Arch) { // NVPTX uses the nvlink binary to link device object files. ErrorOr NvlinkPath = sys::findProgramByName("nvlink"); @@ -569,11 +576,6 @@ Expected link(ArrayRef InputFiles, CmdArgs.push_back("-arch"); CmdArgs.push_back(Arch); - // Copy system library paths used by the host linker. - for (StringRef Arg : LinkerArgs) - if (Arg.startswith("-L")) - CmdArgs.push_back(Arg); - // Add extracted input files. for (StringRef Input : InputFiles) CmdArgs.push_back(Input); @@ -585,8 +587,7 @@ Expected link(ArrayRef InputFiles, } } // namespace nvptx namespace amdgcn { -Expected link(ArrayRef InputFiles, - ArrayRef LinkerArgs, Triple TheTriple, +Expected link(ArrayRef InputFiles, Triple TheTriple, StringRef Arch) { // AMDGPU uses the lld binary to link device object files. ErrorOr LLDPath = @@ -613,11 +614,6 @@ Expected link(ArrayRef InputFiles, CmdArgs.push_back("-o"); CmdArgs.push_back(TempFile); - // Copy system library paths used by the host linker. - for (StringRef Arg : LinkerArgs) - if (Arg.startswith("-L")) - CmdArgs.push_back(Arg); - // Add extracted input files. for (StringRef Input : InputFiles) CmdArgs.push_back(Input); @@ -630,14 +626,13 @@ Expected link(ArrayRef InputFiles, } // namespace amdgcn Expected linkDevice(ArrayRef InputFiles, - ArrayRef LinkerArgs, Triple TheTriple, StringRef Arch) { switch (TheTriple.getArch()) { case Triple::nvptx: case Triple::nvptx64: - return nvptx::link(InputFiles, LinkerArgs, TheTriple, Arch); + return nvptx::link(InputFiles, TheTriple, Arch); case Triple::amdgcn: - return amdgcn::link(InputFiles, LinkerArgs, TheTriple, Arch); + return amdgcn::link(InputFiles, TheTriple, Arch); case Triple::x86: case Triple::x86_64: // TODO: x86 linking support. @@ -790,9 +785,9 @@ Error linkBitcodeFiles(SmallVectorImpl &InputFiles, return Name.takeError(); // Record if we've seen these symbols in any object or shared libraries. - if ((*ObjFile)->isRelocatableObject()) { + if ((*ObjFile)->isRelocatableObject()) UsedInRegularObj[*Name] = true; - } else + else UsedInSharedLib[*Name] = true; } } else { @@ -898,7 +893,7 @@ Error linkBitcodeFiles(SmallVectorImpl &InputFiles, auto &TempFile = Files[Task]; StringRef Extension = (TheTriple.isNVPTX()) ? "s" : "o"; if (Error Err = createOutputFile(sys::path::filename(ExecutableName) + - "-lto-" + TheTriple.getTriple(), + "-device-" + TheTriple.getTriple(), Extension, TempFile)) HandleError(std::move(Err)); if (std::error_code EC = sys::fs::openFileForWrite(TempFile, FD)) @@ -931,7 +926,6 @@ Error linkBitcodeFiles(SmallVectorImpl &InputFiles, /// Runs the appropriate linking action on all the device files specified in \p /// DeviceFiles. The linked device images are returned in \p LinkedImages. Error linkDeviceFiles(ArrayRef DeviceFiles, - ArrayRef LinkerArgs, SmallVectorImpl &LinkedImages) { // Get the list of inputs for a specific device. StringMap> LinkerInputMap; @@ -955,8 +949,7 @@ Error linkDeviceFiles(ArrayRef DeviceFiles, continue; } - auto ImageOrErr = - linkDevice(LinkerInput.getValue(), LinkerArgs, TheTriple, Arch); + auto ImageOrErr = linkDevice(LinkerInput.getValue(), TheTriple, Arch); if (!ImageOrErr) return ImageOrErr.takeError(); @@ -1091,18 +1084,15 @@ int main(int argc, const char **argv) { return EXIT_FAILURE; }; + ExecutableName = *(llvm::find(HostLinkerArgs, "-o") + 1); SmallVector LinkerArgs; for (const std::string &Arg : HostLinkerArgs) LinkerArgs.push_back(Arg); SmallVector LibraryPaths; - for (auto AI = LinkerArgs.begin(), AE = LinkerArgs.end(); AI != AE; ++AI) { - StringRef Arg = *AI; - + for (StringRef Arg : LinkerArgs) { if (Arg.startswith("-L")) LibraryPaths.push_back(Arg.drop_front(2)); - if (Arg == "-o") - ExecutableName = *(AI + 1); } // Try to extract device code from the linker input and replace the linker @@ -1135,17 +1125,13 @@ int main(int argc, const char **argv) { } } - // Add the device bitcode library to the device files if it was passed in. - if (!BitcodeLibrary.empty()) { - auto DeviceAndPath = StringRef(BitcodeLibrary).split('='); - auto TripleAndArch = DeviceAndPath.first.rsplit('-'); - DeviceFiles.emplace_back(TripleAndArch.first, TripleAndArch.second, - DeviceAndPath.second); - } + // Add the device bitcode libraries to the device files if any were passed in. + for (StringRef LibraryStr : BitcodeLibraries) + DeviceFiles.push_back(getBitcodeLibrary(LibraryStr)); // Link the device images extracted from the linker input. SmallVector LinkedImages; - if (Error Err = linkDeviceFiles(DeviceFiles, LinkerArgs, LinkedImages)) + if (Error Err = linkDeviceFiles(DeviceFiles, LinkedImages)) return reportError(std::move(Err)); // Wrap each linked device image into a linkable host binary and add it to the -- 2.7.4