Index: llvm/trunk/include/llvm/CodeGen/ParallelCG.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/ParallelCG.h +++ llvm/trunk/include/llvm/CodeGen/ParallelCG.h @@ -16,6 +16,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/CodeGen.h" +#include "llvm/Target/TargetMachine.h" namespace llvm { @@ -24,8 +25,8 @@ class raw_pwrite_stream; /// Split M into OSs.size() partitions, and generate code for each. Writes -/// OSs.size() object files to the output streams in OSs. The resulting object -/// files if linked together are intended to be equivalent to the single object +/// OSs.size() output files to the output streams in OSs. The resulting output +/// files if linked together are intended to be equivalent to the single output /// file that would have been code generated from M. /// /// \returns M if OSs.size() == 1, otherwise returns std::unique_ptr(). @@ -34,7 +35,8 @@ StringRef CPU, StringRef Features, const TargetOptions &Options, Reloc::Model RM = Reloc::Default, CodeModel::Model CM = CodeModel::Default, - CodeGenOpt::Level OL = CodeGenOpt::Default); + CodeGenOpt::Level OL = CodeGenOpt::Default, + TargetMachine::CodeGenFileType FT = TargetMachine::CGFT_ObjectFile); } // namespace llvm Index: llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h =================================================================== --- llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h +++ llvm/trunk/include/llvm/LTO/LTOCodeGenerator.h @@ -40,6 +40,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/Linker/Linker.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include #include @@ -74,6 +75,10 @@ void setTargetOptions(TargetOptions Options); void setDebugInfo(lto_debug_model); void setCodePICModel(Reloc::Model Model) { RelocModel = Model; } + + /// Set the file type to be emitted (assembly or object code). + /// The default is TargetMachine::CGFT_ObjectFile. + void setFileType(TargetMachine::CodeGenFileType FT) { FileType = FT; } void setCpu(const char *MCpu) { this->MCpu = MCpu; } void setAttr(const char *MAttr) { this->MAttr = MAttr; } @@ -103,21 +108,21 @@ /// true on success. bool writeMergedModules(const char *Path); - /// Compile the merged module into a *single* object file; the path to object + /// Compile the merged module into a *single* output file; the path to output /// file is returned to the caller via argument "name". Return true on /// success. /// - /// \note It is up to the linker to remove the intermediate object file. Do + /// \note It is up to the linker to remove the intermediate output file. Do /// not try to remove the object file in LTOCodeGenerator's destructor as we - /// don't who (LTOCodeGenerator or the obj file) will last longer. + /// don't who (LTOCodeGenerator or the output file) will last longer. bool compile_to_file(const char **Name, bool DisableVerify, bool DisableInline, bool DisableGVNLoadPRE, bool DisableVectorization); /// As with compile_to_file(), this function compiles the merged module into - /// single object file. Instead of returning the object-file-path to the - /// caller (linker), it brings the object to a buffer, and return the buffer - /// to the caller. This function should delete intermediate object file once + /// single output file. Instead of returning the output file path to the + /// caller (linker), it brings the output to a buffer, and returns the buffer + /// to the caller. This function should delete the intermediate file once /// its content is brought to memory. Return NULL if the compilation was not /// successful. std::unique_ptr compile(bool DisableVerify, bool DisableInline, @@ -128,15 +133,15 @@ bool optimize(bool DisableVerify, bool DisableInline, bool DisableGVNLoadPRE, bool DisableVectorization); - /// Compiles the merged optimized module into a single object file. It brings - /// the object to a buffer, and returns the buffer to the caller. Return NULL + /// Compiles the merged optimized module into a single output file. It brings + /// the output to a buffer, and returns the buffer to the caller. Return NULL /// if the compilation was not successful. std::unique_ptr compileOptimized(); - /// Compile the merged optimized module into out.size() object files each + /// Compile the merged optimized module into out.size() output files each /// representing a linkable partition of the module. If out contains more /// than one element, code generation is done in parallel with out.size() - /// threads. Object files will be written to members of out. Returns true on + /// threads. Output files will be written to members of out. Returns true on /// success. bool compileOptimized(ArrayRef Out); @@ -185,6 +190,7 @@ void *DiagContext = nullptr; bool ShouldInternalize = true; bool ShouldEmbedUselists = false; + TargetMachine::CodeGenFileType FileType = TargetMachine::CGFT_ObjectFile; }; } #endif Index: llvm/trunk/lib/CodeGen/ParallelCG.cpp =================================================================== --- llvm/trunk/lib/CodeGen/ParallelCG.cpp +++ llvm/trunk/lib/CodeGen/ParallelCG.cpp @@ -28,13 +28,13 @@ static void codegen(Module *M, llvm::raw_pwrite_stream &OS, const Target *TheTarget, StringRef CPU, StringRef Features, const TargetOptions &Options, Reloc::Model RM, - CodeModel::Model CM, CodeGenOpt::Level OL) { + CodeModel::Model CM, CodeGenOpt::Level OL, + TargetMachine::CodeGenFileType FileType) { std::unique_ptr TM(TheTarget->createTargetMachine( M->getTargetTriple(), CPU, Features, Options, RM, CM, OL)); legacy::PassManager CodeGenPasses; - if (TM->addPassesToEmitFile(CodeGenPasses, OS, - TargetMachine::CGFT_ObjectFile)) + if (TM->addPassesToEmitFile(CodeGenPasses, OS, FileType)) report_fatal_error("Failed to setup codegen"); CodeGenPasses.run(*M); } @@ -43,7 +43,8 @@ llvm::splitCodeGen(std::unique_ptr M, ArrayRef OSs, StringRef CPU, StringRef Features, const TargetOptions &Options, - Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL) { + Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL, + TargetMachine::CodeGenFileType FileType) { StringRef TripleStr = M->getTargetTriple(); std::string ErrMsg; const Target *TheTarget = TargetRegistry::lookupTarget(TripleStr, ErrMsg); @@ -52,7 +53,7 @@ if (OSs.size() == 1) { codegen(M.get(), *OSs[0], TheTarget, CPU, Features, Options, RM, CM, - OL); + OL, FileType); return M; } @@ -69,7 +70,7 @@ llvm::raw_pwrite_stream *ThreadOS = OSs[Threads.size()]; Threads.emplace_back( - [TheTarget, CPU, Features, Options, RM, CM, OL, + [TheTarget, CPU, Features, Options, RM, CM, OL, FileType, ThreadOS](const SmallVector &BC) { LLVMContext Ctx; ErrorOr> MOrErr = @@ -81,7 +82,7 @@ std::unique_ptr MPartInCtx = std::move(MOrErr.get()); codegen(MPartInCtx.get(), *ThreadOS, TheTarget, CPU, Features, - Options, RM, CM, OL); + Options, RM, CM, OL, FileType); }, // Pass BC using std::move to ensure that it get moved rather than // copied into the thread's context. Index: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp @@ -206,11 +206,15 @@ } bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) { - // make unique temp .o file to put generated object file + // make unique temp output file to put generated code SmallString<128> Filename; int FD; + + const char *Extension = + (FileType == TargetMachine::CGFT_AssemblyFile ? "s" : "o"); + std::error_code EC = - sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename); + sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename); if (EC) { emitError(EC.message()); return false; @@ -514,7 +518,7 @@ // MergedModule. MergedModule = splitCodeGen(std::move(MergedModule), Out, MCpu, FeatureStr, Options, - RelocModel, CodeModel::Default, CGOptLevel); + RelocModel, CodeModel::Default, CGOptLevel, FileType); return true; }