[clang] bf499c5 - [OpenMP] Implement save temps functionality in linker wrapper
Joseph Huber via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 31 20:12:12 PST 2022
Author: Joseph Huber
Date: 2022-01-31T23:11:42-05:00
New Revision: bf499c58af3d3a96661f5c7ef81b264eac575541
URL: https://github.com/llvm/llvm-project/commit/bf499c58af3d3a96661f5c7ef81b264eac575541
DIFF: https://github.com/llvm/llvm-project/commit/bf499c58af3d3a96661f5c7ef81b264eac575541.diff
LOG: [OpenMP] Implement save temps functionality in linker wrapper
Summary:
This patch implements the `-save-temps` flag for the linker wrapper.
This allows the user to inspect the intermeditary outpout that the
linker wrapper creates.
Added:
Modified:
clang/lib/Driver/ToolChains/Clang.cpp
clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 1ddffcdc24f48..537b9ca829262 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -8244,6 +8244,8 @@ void LinkerWrapper::ConstructJob(Compilation &C, const JobAction &JA,
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_analysis_EQ))
CmdArgs.push_back(
Args.MakeArgString(Twine("-pass-remarks-analysis=") + A->getValue()));
+ if (Args.getLastArg(options::OPT_save_temps_EQ))
+ CmdArgs.push_back("-save-temps");
// Add the linker arguments to be forwarded by the wrapper.
CmdArgs.push_back("-linker-path");
diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
index 8331bda62420b..56a1859c337e2 100644
--- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
+++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
@@ -111,6 +111,10 @@ static cl::opt<DebugKind> DebugInfo(
"Direction information"),
clEnumValN(FullDebugInfo, "g", "Full debugging support")));
+static cl::opt<bool> SaveTemps("save-temps", cl::ZeroOrMore,
+ cl::desc("Save intermediary results."),
+ cl::cat(ClangLinkerWrapperCategory));
+
// Do not parse linker options.
static cl::list<std::string>
HostLinkerArgs(cl::Positional,
@@ -157,6 +161,21 @@ static StringRef getDeviceFileExtension(StringRef DeviceTriple,
return "o";
}
+Error createOutputFile(const Twine &Prefix, StringRef Extension,
+ SmallString<128> &NewFilename) {
+ if (!SaveTemps) {
+ if (std::error_code EC =
+ sys::fs::createTemporaryFile(Prefix, Extension, NewFilename))
+ return createFileError(NewFilename, EC);
+ TempFiles.push_back(static_cast<std::string>(NewFilename));
+ } else {
+ const Twine &Filename = Prefix + "." + Extension;
+ Filename.toNullTerminatedStringRef(NewFilename);
+ }
+
+ return Error::success();
+}
+
Error runLinker(std::string &LinkerPath, SmallVectorImpl<std::string> &Args) {
std::vector<StringRef> LinkerArgs;
LinkerArgs.push_back(LinkerPath);
@@ -204,11 +223,8 @@ void removeFromCompilerUsed(Module &M, GlobalValue &Value) {
Expected<Optional<std::string>>
extractFromBinary(const ObjectFile &Obj,
SmallVectorImpl<DeviceFile> &DeviceFiles) {
-
StringRef Extension = sys::path::extension(Obj.getFileName()).drop_front();
- StringRef Prefix = sys::path::stem(Obj.getFileName()).take_until([](char C) {
- return C == '-';
- });
+ StringRef Prefix = sys::path::stem(Obj.getFileName());
SmallVector<StringRef, 4> ToBeStripped;
// Extract data from sections of the form `.llvm.offloading.<triple>.<arch>`.
@@ -226,10 +242,9 @@ extractFromBinary(const ObjectFile &Obj,
SmallString<128> TempFile;
StringRef DeviceExtension = getDeviceFileExtension(
DeviceTriple, identify_magic(*Contents) == file_magic::bitcode);
- if (std::error_code EC = sys::fs::createTemporaryFile(
- Prefix + "-device-" + DeviceTriple, DeviceExtension, TempFile))
- return createFileError(TempFile, EC);
- TempFiles.push_back(static_cast<std::string>(TempFile));
+ if (Error Err = createOutputFile(Prefix + "-device-" + DeviceTriple,
+ DeviceExtension, TempFile))
+ return std::move(Err);
Expected<std::unique_ptr<FileOutputBuffer>> OutputOrErr =
FileOutputBuffer::create(TempFile, Sec.getSize());
@@ -253,10 +268,9 @@ extractFromBinary(const ObjectFile &Obj,
SmallString<128> StripFile = Obj.getFileName();
if (!sys::fs::exists(StripFile)) {
SmallString<128> TempFile;
- if (std::error_code EC = sys::fs::createTemporaryFile(
- sys::path::stem(StripFile), "o", TempFile))
- return createFileError(TempFile, EC);
- TempFiles.push_back(static_cast<std::string>(TempFile));
+ if (Error Err = createOutputFile(sys::path::stem(StripFile),
+ sys::path::extension(StripFile), TempFile))
+ return std::move(Err);
auto Contents = Obj.getMemoryBufferRef().getBuffer();
Expected<std::unique_ptr<FileOutputBuffer>> OutputOrErr =
@@ -278,10 +292,8 @@ extractFromBinary(const ObjectFile &Obj,
"Unable to find 'llvm-strip' in path");
SmallString<128> TempFile;
- if (std::error_code EC =
- sys::fs::createTemporaryFile(Prefix + "-host", Extension, TempFile))
- return createFileError(TempFile, EC);
- TempFiles.push_back(static_cast<std::string>(TempFile));
+ if (Error Err = createOutputFile(Prefix + "-host", Extension, TempFile))
+ return std::move(Err);
SmallVector<StringRef, 8> StripArgs;
StripArgs.push_back(*StripPath);
@@ -336,10 +348,9 @@ extractFromBitcode(std::unique_ptr<MemoryBuffer> Buffer,
SmallString<128> TempFile;
StringRef DeviceExtension = getDeviceFileExtension(
DeviceTriple, identify_magic(Contents) == file_magic::bitcode);
- if (std::error_code EC = sys::fs::createTemporaryFile(
- Prefix + "-device-" + DeviceTriple, DeviceExtension, TempFile))
- return createFileError(TempFile, EC);
- TempFiles.push_back(static_cast<std::string>(TempFile));
+ if (Error Err = createOutputFile(Prefix + "-device-" + DeviceTriple,
+ DeviceExtension, TempFile))
+ return std::move(Err);
Expected<std::unique_ptr<FileOutputBuffer>> OutputOrErr =
FileOutputBuffer::create(TempFile, Contents.size());
@@ -368,10 +379,8 @@ extractFromBitcode(std::unique_ptr<MemoryBuffer> Buffer,
}
SmallString<128> TempFile;
- if (std::error_code EC =
- sys::fs::createTemporaryFile(Prefix + "-host", Extension, TempFile))
- return createFileError(TempFile, EC);
- TempFiles.push_back(static_cast<std::string>(TempFile));
+ if (Error Err = createOutputFile(Prefix + "-host", Extension, TempFile))
+ return std::move(Err);
std::error_code EC;
raw_fd_ostream HostOutput(TempFile, EC, sys::fs::OF_None);
@@ -385,13 +394,6 @@ Expected<Optional<std::string>>
extractFromArchive(const Archive &Library,
SmallVectorImpl<DeviceFile> &DeviceFiles) {
- StringRef Extension =
- sys::path::extension(Library.getFileName()).drop_front();
- StringRef Prefix =
- sys::path::stem(Library.getFileName()).take_until([](char C) {
- return C == '-';
- });
-
bool NewMembers = false;
SmallVector<NewArchiveMember, 8> Members;
@@ -440,10 +442,9 @@ extractFromArchive(const Archive &Library,
// Create a new static library using the stripped host files.
SmallString<128> TempFile;
- if (std::error_code EC =
- sys::fs::createTemporaryFile(Prefix + "-host", Extension, TempFile))
- return createFileError(TempFile, EC);
- TempFiles.push_back(static_cast<std::string>(TempFile));
+ StringRef Prefix = sys::path::stem(Library.getFileName());
+ if (Error Err = createOutputFile(Prefix + "-host", "a", TempFile))
+ return std::move(Err);
std::unique_ptr<MemoryBuffer> Buffer =
MemoryBuffer::getMemBuffer(Library.getMemoryBufferRef(), false);
@@ -500,10 +501,9 @@ Expected<std::string> assemble(StringRef InputFile, Triple TheTriple,
// Create a new file to write the linked device image to.
SmallString<128> TempFile;
- if (std::error_code EC = sys::fs::createTemporaryFile(
+ if (Error Err = createOutputFile(
"lto-" + TheTriple.getArchName() + "-" + Arch, "cubin", TempFile))
- return createFileError(TempFile, EC);
- TempFiles.push_back(static_cast<std::string>(TempFile));
+ return std::move(Err);
// TODO: Pass in arguments like `-g` and `-v` from the driver.
SmallVector<StringRef, 16> CmdArgs;
@@ -544,10 +544,9 @@ Expected<std::string> link(ArrayRef<std::string> InputFiles,
// Create a new file to write the linked device image to.
SmallString<128> TempFile;
- if (std::error_code EC = sys::fs::createTemporaryFile(
+ if (Error Err = createOutputFile(
TheTriple.getArchName() + "-" + Arch + "-image", "out", TempFile))
- return createFileError(TempFile, EC);
- TempFiles.push_back(static_cast<std::string>(TempFile));
+ return std::move(Err);
SmallVector<StringRef, 16> CmdArgs;
CmdArgs.push_back(*NvlinkPath);
@@ -591,10 +590,9 @@ Expected<std::string> link(ArrayRef<std::string> InputFiles,
// Create a new file to write the linked device image to.
SmallString<128> TempFile;
- if (std::error_code EC = sys::fs::createTemporaryFile(
+ if (Error Err = createOutputFile(
TheTriple.getArchName() + "-" + Arch + "-image", "out", TempFile))
- return createFileError(TempFile, EC);
- TempFiles.push_back(static_cast<std::string>(TempFile));
+ return std::move(Err);
SmallVector<StringRef, 16> CmdArgs;
CmdArgs.push_back(*LLDPath);
@@ -710,6 +708,26 @@ std::unique_ptr<lto::LTO> createLTO(
Conf.PTO.LoopVectorization = Conf.OptLevel > 1;
Conf.PTO.SLPVectorization = Conf.OptLevel > 1;
+ if (SaveTemps) {
+ auto HandleError = [&](Error Err) {
+ logAllUnhandledErrors(std::move(Err),
+ WithColor::error(errs(), LinkerExecutable));
+ exit(1);
+ };
+ Conf.PostInternalizeModuleHook = [&](size_t, const Module &M) {
+ SmallString<128> TempFile;
+ if (Error Err =
+ createOutputFile("lto-" + TheTriple.getTriple(), "bc", TempFile))
+ HandleError(std::move(Err));
+
+ std::error_code EC;
+ raw_fd_ostream LinkedBitcode(TempFile, EC, sys::fs::OF_None);
+ if (EC)
+ HandleError(errorCodeToError(EC));
+ WriteBitcodeToFile(M, LinkedBitcode);
+ return true;
+ };
+ }
Conf.PostOptModuleHook = Hook;
if (TheTriple.isNVPTX())
Conf.CGFileType = CGFT_AssemblyFile;
@@ -783,33 +801,33 @@ Error linkBitcodeFiles(SmallVectorImpl<std::string> &InputFiles,
assert(!BitcodeLibrary.empty() && "Bitcode linking without `-foffload-lto`");
- auto HandleError = [&](std::error_code EC) {
- logAllUnhandledErrors(errorCodeToError(EC),
+ auto HandleError = [&](Error Err) {
+ logAllUnhandledErrors(std::move(Err),
WithColor::error(errs(), LinkerExecutable));
exit(1);
};
// LTO Module hook to output bitcode without running the backend.
- auto LinkOnly = [&](size_t Task, const Module &M) {
+ auto OutputBitcode = [&](size_t Task, const Module &M) {
SmallString<128> TempFile;
- if (std::error_code EC = sys::fs::createTemporaryFile(
- "jit-" + TheTriple.getTriple(), "bc", TempFile))
- HandleError(EC);
+ if (Error Err =
+ createOutputFile("jit-" + TheTriple.getTriple(), "bc", TempFile))
+ HandleError(std::move(Err));
+
std::error_code EC;
raw_fd_ostream LinkedBitcode(TempFile, EC, sys::fs::OF_None);
if (EC)
- HandleError(EC);
+ HandleError(errorCodeToError(EC));
WriteBitcodeToFile(M, LinkedBitcode);
- TempFiles.push_back(static_cast<std::string>(TempFile));
NewInputFiles.push_back(static_cast<std::string>(TempFile));
return false;
};
// We assume visibility of the whole program if every input file was bitcode.
bool WholeProgram = BitcodeFiles.size() == InputFiles.size();
- auto LTOBackend = (EmbedBitcode)
- ? createLTO(TheTriple, Arch, WholeProgram, LinkOnly)
- : createLTO(TheTriple, Arch, WholeProgram);
+ auto LTOBackend =
+ (EmbedBitcode) ? createLTO(TheTriple, Arch, WholeProgram, OutputBitcode)
+ : createLTO(TheTriple, Arch, WholeProgram);
// We need to resolve the symbols so the LTO backend knows which symbols need
// to be kept or can be internalized. This is a simplified symbol resolution
@@ -869,9 +887,11 @@ Error linkBitcodeFiles(SmallVectorImpl<std::string> &InputFiles,
int FD = -1;
auto &TempFile = Files[Task];
StringRef Extension = (TheTriple.isNVPTX()) ? "s" : "o";
- if (std::error_code EC = sys::fs::createTemporaryFile(
- "lto-" + TheTriple.getTriple(), Extension, FD, TempFile))
- HandleError(EC);
+ if (Error Err = createOutputFile("lto-" + TheTriple.getTriple(), Extension,
+ TempFile))
+ HandleError(std::move(Err));
+ if (std::error_code EC = sys::fs::openFileForWrite(TempFile, FD))
+ HandleError(errorCodeToError(EC));
TempFiles.push_back(static_cast<std::string>(TempFile));
return std::make_unique<CachedFileStream>(
std::make_unique<llvm::raw_fd_ostream>(FD, true));
@@ -947,17 +967,13 @@ Expected<std::string> wrapDeviceImage(StringRef ImageFile) {
// Create a new file to write the wrapped bitcode file to.
SmallString<128> BitcodeFile;
- if (std::error_code EC =
- sys::fs::createTemporaryFile("wrapper", "bc", BitcodeFile))
- return createFileError(BitcodeFile, EC);
- TempFiles.push_back(static_cast<std::string>(BitcodeFile));
+ if (Error Err = createOutputFile("offload-wrapper", "bc", BitcodeFile))
+ return std::move(Err);
- // TODO: Optionally pass the host triple in somewhere.
- Triple HostTriple(sys::getDefaultTargetTriple());
SmallVector<StringRef, 4> WrapperArgs;
WrapperArgs.push_back(*WrapperPath);
WrapperArgs.push_back("-target");
- WrapperArgs.push_back(HostTriple.getTriple());
+ WrapperArgs.push_back(HostTriple);
WrapperArgs.push_back("-o");
WrapperArgs.push_back(BitcodeFile);
WrapperArgs.push_back(ImageFile);
@@ -973,10 +989,8 @@ Expected<std::string> wrapDeviceImage(StringRef ImageFile) {
// Create a new file to write the wrapped bitcode file to.
SmallString<128> ObjectFile;
- if (std::error_code EC =
- sys::fs::createTemporaryFile("image", "o", ObjectFile))
- return createFileError(BitcodeFile, EC);
- TempFiles.push_back(static_cast<std::string>(ObjectFile));
+ if (Error Err = createOutputFile("offload-wrapper", "o", ObjectFile))
+ return std::move(Err);
SmallVector<StringRef, 4> CompilerArgs;
CompilerArgs.push_back(*CompilerPath);
More information about the cfe-commits
mailing list