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 @@ -510,6 +510,43 @@ } } +Expected assemble(StringRef InputFile, const ArgList &Args) { + llvm::TimeTraceScope TimeScope("Clang Assembler"); + // Use `clang` to invoke the generic assembler. + Expected ClangPath = + findProgram("clang", {getMainExecutable("clang")}); + if (!ClangPath) + return ClangPath.takeError(); + + const llvm::Triple Triple(Args.getLastArgValue(OPT_triple_EQ)); + StringRef Arch = Args.getLastArgValue(OPT_arch_EQ); + // Create a new file to write the linked device image to. Assume that the + // input filename already has the device and architecture. + auto TempFileOrErr = createOutputFile(sys::path::stem(InputFile), "o"); + if (!TempFileOrErr) + return TempFileOrErr.takeError(); + + SmallVector CmdArgs; + StringRef OptLevel = Args.getLastArgValue(OPT_opt_level, "O2"); + CmdArgs.push_back(*ClangPath); + CmdArgs.push_back("-o"); + CmdArgs.push_back(*TempFileOrErr); + CmdArgs.push_back("-fPIC"); + CmdArgs.push_back("-c"); + CmdArgs.push_back(Args.MakeArgString("--target=" + Triple.getTriple())); + CmdArgs.push_back(Args.MakeArgString("-" + OptLevel)); + if (Triple.isAMDGPU()) + CmdArgs.push_back(Args.MakeArgString("-mcpu=" + Arch)); + else + CmdArgs.push_back(Args.MakeArgString("-march=" + Arch)); + CmdArgs.push_back(InputFile); + + if (Error Err = executeCommands(*ClangPath, CmdArgs)) + return std::move(Err); + + return *TempFileOrErr; +} + Expected link(ArrayRef InputFiles, const ArgList &Args) { llvm::TimeTraceScope TimeScope("Generic linker"); const llvm::Triple Triple(Args.getLastArgValue(OPT_triple_EQ)); @@ -685,7 +722,8 @@ }; } Conf.PostOptModuleHook = Hook; - Conf.CGFileType = Triple.isNVPTX() ? CGFT_AssemblyFile : CGFT_ObjectFile; + Conf.CGFileType = + (Triple.isNVPTX() || SaveTemps) ? CGFT_AssemblyFile : CGFT_ObjectFile; // TODO: Handle remark files Conf.HasWholeProgramVisibility = Args.hasArg(OPT_whole_program); @@ -852,7 +890,7 @@ const Twine &ModuleName) -> std::unique_ptr { int FD = -1; auto &TempFile = Files[Task]; - StringRef Extension = (Triple.isNVPTX()) ? "s" : "o"; + StringRef Extension = (Triple.isNVPTX() || SaveTemps) ? "s" : "o"; std::string TaskStr = Task ? "." + std::to_string(Task) : ""; auto TempFileOrErr = createOutputFile(sys::path::filename(ExecutableName) + "-device-" + @@ -885,9 +923,12 @@ } // Is we are compiling for NVPTX we need to run the assembler first. - if (Triple.isNVPTX()) { + if (Triple.isNVPTX() || SaveTemps) { for (StringRef &File : Files) { - auto FileOrErr = nvptx::assemble(File, Args, !SingleOutput); + + auto FileOrErr = Triple.isNVPTX() + ? nvptx::assemble(File, Args, !SingleOutput) + : generic::assemble(File, Args); if (!FileOrErr) return FileOrErr.takeError(); File = *FileOrErr;