From 7f9b89f0e2df513546bfb2f54976d40121918b35 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Mon, 21 May 2018 20:16:41 +0000 Subject: [PATCH] CodeGen: Add a dwo output file argument to addPassesToEmitFile and hook it up to dwo output. Part of PR37466. Differential Revision: https://reviews.llvm.org/D47089 llvm-svn: 332881 --- include/llvm/Target/TargetMachine.h | 8 ++-- lib/CodeGen/LLVMTargetMachine.cpp | 15 ++++--- lib/CodeGen/ParallelCG.cpp | 2 +- lib/LTO/LTOBackend.cpp | 5 ++- lib/LTO/ThinLTOCodeGenerator.cpp | 2 +- lib/Target/TargetMachineC.cpp | 2 +- test/CodeGen/X86/dwarf-headers.ll | 48 +++++++++++---------- test/CodeGen/X86/dwarf-split-line-1.ll | 7 +-- test/CodeGen/X86/dwarf-split-line-2.ll | 7 +-- tools/llc/llc.cpp | 22 +++++++++- tools/llvm-exegesis/lib/Assembler.cpp | 4 +- tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp | 2 +- 12 files changed, 79 insertions(+), 45 deletions(-) diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index b40994a739e..1dfb9ddcc86 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -252,7 +252,7 @@ public: /// \p MMI is an optional parameter that, if set to non-nullptr, /// will be used to set the MachineModuloInfo for this PM. virtual bool addPassesToEmitFile(PassManagerBase &, raw_pwrite_stream &, - CodeGenFileType, + raw_pwrite_stream *, CodeGenFileType, bool /*DisableVerify*/ = true, MachineModuleInfo *MMI = nullptr) { return true; @@ -321,7 +321,8 @@ public: /// \p MMI is an optional parameter that, if set to non-nullptr, /// will be used to set the MachineModuloInfofor this PM. bool addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out, - CodeGenFileType FileType, bool DisableVerify = true, + raw_pwrite_stream *DwoOut, CodeGenFileType FileType, + bool DisableVerify = true, MachineModuleInfo *MMI = nullptr) override; /// Add passes to the specified pass manager to get machine code emitted with @@ -341,7 +342,8 @@ public: /// Adds an AsmPrinter pass to the pipeline that prints assembly or /// machine code from the MI representation. bool addAsmPrinter(PassManagerBase &PM, raw_pwrite_stream &Out, - CodeGenFileType FileTYpe, MCContext &Context); + raw_pwrite_stream *DwoOut, CodeGenFileType FileTYpe, + MCContext &Context); }; } // end namespace llvm diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index 27b1d96773e..2cd389ce2c1 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -121,8 +121,10 @@ addPassesToGenerateCode(LLVMTargetMachine *TM, PassManagerBase &PM, } bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM, - raw_pwrite_stream &Out, CodeGenFileType FileType, - MCContext &Context) { + raw_pwrite_stream &Out, + raw_pwrite_stream *DwoOut, + CodeGenFileType FileType, + MCContext &Context) { if (Options.MCOptions.MCSaveTempLabels) Context.setAllowTemporaryLabels(false); @@ -168,8 +170,9 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM, Triple T(getTargetTriple().str()); AsmStreamer.reset(getTarget().createMCObjectStreamer( T, Context, std::unique_ptr(MAB), - MAB->createObjectWriter(Out), std::unique_ptr(MCE), STI, - Options.MCOptions.MCRelaxAll, + DwoOut ? MAB->createDwoObjectWriter(Out, *DwoOut) + : MAB->createObjectWriter(Out), + std::unique_ptr(MCE), STI, Options.MCOptions.MCRelaxAll, Options.MCOptions.MCIncrementalLinkerCompatible, /*DWARFMustBeAtTheEnd*/ true)); break; @@ -193,6 +196,7 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM, bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out, + raw_pwrite_stream *DwoOut, CodeGenFileType FileType, bool DisableVerify, MachineModuleInfo *MMI) { @@ -203,7 +207,8 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, if (!Context) return true; - if (WillCompleteCodeGenPipeline && addAsmPrinter(PM, Out, FileType, *Context)) + if (WillCompleteCodeGenPipeline && + addAsmPrinter(PM, Out, DwoOut, FileType, *Context)) return true; PM.add(createFreeMachineFunctionPass()); diff --git a/lib/CodeGen/ParallelCG.cpp b/lib/CodeGen/ParallelCG.cpp index 4624b224b95..bc3f2a6e9b5 100644 --- a/lib/CodeGen/ParallelCG.cpp +++ b/lib/CodeGen/ParallelCG.cpp @@ -30,7 +30,7 @@ static void codegen(Module *M, llvm::raw_pwrite_stream &OS, TargetMachine::CodeGenFileType FileType) { std::unique_ptr TM = TMFactory(); legacy::PassManager CodeGenPasses; - if (TM->addPassesToEmitFile(CodeGenPasses, OS, FileType)) + if (TM->addPassesToEmitFile(CodeGenPasses, OS, nullptr, FileType)) report_fatal_error("Failed to setup codegen"); CodeGenPasses.run(*M); } diff --git a/lib/LTO/LTOBackend.cpp b/lib/LTO/LTOBackend.cpp index 6367aac11f3..983ba80c1af 100644 --- a/lib/LTO/LTOBackend.cpp +++ b/lib/LTO/LTOBackend.cpp @@ -304,7 +304,7 @@ void codegenWithSplitDwarf(Config &Conf, TargetMachine *TM, TM->Options.MCOptions.SplitDwarfFile = DwarfFile.str().str(); legacy::PassManager CodeGenPasses; - if (TM->addPassesToEmitFile(CodeGenPasses, OS, Conf.CGFileType)) + if (TM->addPassesToEmitFile(CodeGenPasses, OS, nullptr, Conf.CGFileType)) report_fatal_error("Failed to setup codegen"); CodeGenPasses.run(Mod); @@ -355,7 +355,8 @@ void codegen(Config &Conf, TargetMachine *TM, AddStreamFn AddStream, auto Stream = AddStream(Task); legacy::PassManager CodeGenPasses; - if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS, Conf.CGFileType)) + if (TM->addPassesToEmitFile(CodeGenPasses, *Stream->OS, nullptr, + Conf.CGFileType)) report_fatal_error("Failed to setup codegen"); CodeGenPasses.run(Mod); } diff --git a/lib/LTO/ThinLTOCodeGenerator.cpp b/lib/LTO/ThinLTOCodeGenerator.cpp index f164a034a0b..872b9232e34 100644 --- a/lib/LTO/ThinLTOCodeGenerator.cpp +++ b/lib/LTO/ThinLTOCodeGenerator.cpp @@ -268,7 +268,7 @@ std::unique_ptr codegenModule(Module &TheModule, PM.add(createObjCARCContractPass()); // Setup the codegen now. - if (TM.addPassesToEmitFile(PM, OS, TargetMachine::CGFT_ObjectFile, + if (TM.addPassesToEmitFile(PM, OS, nullptr, TargetMachine::CGFT_ObjectFile, /* DisableVerify */ true)) report_fatal_error("Failed to setup codegen"); diff --git a/lib/Target/TargetMachineC.cpp b/lib/Target/TargetMachineC.cpp index d43124d7123..a6f4790b866 100644 --- a/lib/Target/TargetMachineC.cpp +++ b/lib/Target/TargetMachineC.cpp @@ -196,7 +196,7 @@ static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M, ft = TargetMachine::CGFT_ObjectFile; break; } - if (TM->addPassesToEmitFile(pass, OS, ft)) { + if (TM->addPassesToEmitFile(pass, OS, nullptr, ft)) { error = "TargetMachine can't emit a file of this type"; *ErrorMessage = strdup(error.c_str()); return true; diff --git a/test/CodeGen/X86/dwarf-headers.ll b/test/CodeGen/X86/dwarf-headers.ll index 9aacaca9c76..f30e826a9c1 100644 --- a/test/CodeGen/X86/dwarf-headers.ll +++ b/test/CodeGen/X86/dwarf-headers.ll @@ -2,17 +2,21 @@ ; RUN: -filetype=obj -O0 -mtriple=x86_64-unknown-linux-gnu < %s \ ; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=SINGLE-4 -; RUN: llc -split-dwarf-file=foo.dwo -dwarf-version=4 -generate-type-units \ +; RUN: llc -split-dwarf-file=foo.dwo -split-dwarf-output=%t.dwo \ +; RUN: -dwarf-version=4 -generate-type-units \ ; RUN: -filetype=obj -O0 -mtriple=x86_64-unknown-linux-gnu < %s \ -; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=SPLIT-4 +; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=O-4 +; RUN: llvm-dwarfdump -v %t.dwo | FileCheck %s --check-prefix=DWO-4 ; RUN: llc -dwarf-version=5 -generate-type-units \ ; RUN: -filetype=obj -O0 -mtriple=x86_64-unknown-linux-gnu < %s \ ; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=SINGLE-5 -; RUN: llc -split-dwarf-file=foo.dwo -dwarf-version=5 -generate-type-units \ +; RUN: llc -split-dwarf-file=foo.dwo -split-dwarf-output=%t.dwo \ +; RUN: -dwarf-version=5 -generate-type-units \ ; RUN: -filetype=obj -O0 -mtriple=x86_64-unknown-linux-gnu < %s \ -; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=SPLIT-5 +; RUN: | llvm-dwarfdump -v - | FileCheck %s --check-prefix=O-5 +; RUN: llvm-dwarfdump -v %t.dwo | FileCheck %s --check-prefix=DWO-5 ; Looking for DWARF headers to be generated correctly. ; There are 7 variants: v4 CU, v4 TU, v5 (normal/skeleton/split) CU, @@ -42,17 +46,17 @@ ; Verify the v4 split headers. ; -; SPLIT-4: .debug_info contents: -; SPLIT-4: 0x00000000: Compile Unit: {{.*}} version = 0x0004 abbr_offset -; SPLIT-4: 0x0000000b: DW_TAG_compile_unit +; O-4: .debug_info contents: +; O-4: 0x00000000: Compile Unit: {{.*}} version = 0x0004 abbr_offset +; O-4: 0x0000000b: DW_TAG_compile_unit ; -; SPLIT-4: .debug_info.dwo contents: -; SPLIT-4: 0x00000000: Compile Unit: {{.*}} version = 0x0004 abbr_offset -; SPLIT-4: 0x0000000b: DW_TAG_compile_unit +; DWO-4: .debug_info.dwo contents: +; DWO-4: 0x00000000: Compile Unit: {{.*}} version = 0x0004 abbr_offset +; DWO-4: 0x0000000b: DW_TAG_compile_unit ; -; SPLIT-4: .debug_types.dwo contents: -; SPLIT-4: 0x00000000: Type Unit: {{.*}} version = 0x0004 abbr_offset -; SPLIT-4: 0x00000017: DW_TAG_type_unit +; DWO-4: .debug_types.dwo contents: +; DWO-4: 0x00000000: Type Unit: {{.*}} version = 0x0004 abbr_offset +; DWO-4: 0x00000017: DW_TAG_type_unit ; Verify the v5 non-split headers. ; @@ -67,18 +71,18 @@ ; Verify the v5 split headers. ; -; SPLIT-5: .debug_info contents: -; SPLIT-5: 0x00000000: Compile Unit: {{.*}} version = 0x0005 unit_type = DW_UT_skeleton abbr_offset -; SPLIT-5: 0x0000000c: DW_TAG_compile_unit +; O-5: .debug_info contents: +; O-5: 0x00000000: Compile Unit: {{.*}} version = 0x0005 unit_type = DW_UT_skeleton abbr_offset +; O-5: 0x0000000c: DW_TAG_compile_unit ; -; SPLIT-5: .debug_info.dwo contents: -; SPLIT-5: 0x00000000: Compile Unit: {{.*}} version = 0x0005 unit_type = DW_UT_split_compile abbr_offset -; SPLIT-5: 0x0000000c: DW_TAG_compile_unit +; DWO-5: .debug_info.dwo contents: +; DWO-5: 0x00000000: Compile Unit: {{.*}} version = 0x0005 unit_type = DW_UT_split_compile abbr_offset +; DWO-5: 0x0000000c: DW_TAG_compile_unit ; ; FIXME: V5 wants type units in .debug_info.dwo not .debug_types.dwo. -; SPLIT-5: .debug_types.dwo contents: -; SPLIT-5: 0x00000000: Type Unit: {{.*}} version = 0x0005 unit_type = DW_UT_split_type abbr_offset -; SPLIT-5: 0x00000018: DW_TAG_type_unit +; DWO-5: .debug_types.dwo contents: +; DWO-5: 0x00000000: Type Unit: {{.*}} version = 0x0005 unit_type = DW_UT_split_type abbr_offset +; DWO-5: 0x00000018: DW_TAG_type_unit ; ModuleID = 't.cpp' diff --git a/test/CodeGen/X86/dwarf-split-line-1.ll b/test/CodeGen/X86/dwarf-split-line-1.ll index 9bc74c5c943..6a403668d73 100644 --- a/test/CodeGen/X86/dwarf-split-line-1.ll +++ b/test/CodeGen/X86/dwarf-split-line-1.ll @@ -1,9 +1,10 @@ ; Verify that split type units with no source locations don't have a ; DW_AT_stmt_list attribute, and the .debug_line.dwo section is suppressed. -; RUN: llc -split-dwarf-file=foo.dwo -dwarf-version=5 -generate-type-units \ -; RUN: -filetype=obj -O0 -mtriple=x86_64-unknown-linux-gnu < %s \ -; RUN: | llvm-dwarfdump -v - | FileCheck %s +; RUN: llc -split-dwarf-file=foo.dwo -split-dwarf-output=%t.dwo \ +; RUN: -dwarf-version=5 -generate-type-units \ +; RUN: -filetype=obj -O0 -mtriple=x86_64-unknown-linux-gnu < %s +; RUN: llvm-dwarfdump -v %t.dwo | FileCheck %s ; FIXME: V5 wants type units in .debug_info.dwo not .debug_types.dwo. ; CHECK-NOT: .debug_line.dwo diff --git a/test/CodeGen/X86/dwarf-split-line-2.ll b/test/CodeGen/X86/dwarf-split-line-2.ll index 1124b30d5b6..3cdad4ddac8 100644 --- a/test/CodeGen/X86/dwarf-split-line-2.ll +++ b/test/CodeGen/X86/dwarf-split-line-2.ll @@ -2,9 +2,10 @@ ; one without, the one without locations doesn't have a DW_AT_stmt_list ; attribute, but the other one does and the .debug_line.dwo section is present. -; RUN: llc -split-dwarf-file=foo.dwo -dwarf-version=5 -generate-type-units \ -; RUN: -filetype=obj -O0 -mtriple=x86_64-unknown-linux-gnu < %s \ -; RUN: | llvm-dwarfdump -v - | FileCheck %s +; RUN: llc -split-dwarf-file=foo.dwo -split-dwarf-output=%t.dwo \ +; RUN: -dwarf-version=5 -generate-type-units \ +; RUN: -filetype=obj -O0 -mtriple=x86_64-unknown-linux-gnu < %s +; RUN: llvm-dwarfdump -v %t.dwo | FileCheck %s ; Currently the no-source-location type comes out first. ; FIXME: V5 wants type units in .debug_info.dwo not .debug_types.dwo. diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index b1f458844ff..4a85041daa0 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -66,6 +66,11 @@ InputLanguage("x", cl::desc("Input language ('ir' or 'mir')")); static cl::opt OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); +static cl::opt + SplitDwarfOutputFile("split-dwarf-output", + cl::desc(".dwo output filename"), + cl::value_desc("filename")); + static cl::opt TimeCompilations("time-compilations", cl::Hidden, cl::init(1u), cl::value_desc("N"), @@ -463,6 +468,17 @@ static int compileModule(char **argv, LLVMContext &Context) { GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]); if (!Out) return 1; + std::unique_ptr DwoOut; + if (!SplitDwarfOutputFile.empty()) { + std::error_code EC; + DwoOut = llvm::make_unique(SplitDwarfOutputFile, EC, + sys::fs::F_None); + if (EC) { + errs() << EC.message() << '\n'; + return 1; + } + } + // Build up all of the passes that we want to do to the module. legacy::PassManager PM; @@ -541,7 +557,9 @@ static int compileModule(char **argv, LLVMContext &Context) { TPC.setInitialized(); PM.add(createPrintMIRPass(*OS)); PM.add(createFreeMachineFunctionPass()); - } else if (Target->addPassesToEmitFile(PM, *OS, FileType, NoVerify, MMI)) { + } else if (Target->addPassesToEmitFile(PM, *OS, + DwoOut ? &DwoOut->os() : nullptr, + FileType, NoVerify, MMI)) { errs() << argv0 << ": target does not support generation of this" << " file type!\n"; return 1; @@ -598,6 +616,8 @@ static int compileModule(char **argv, LLVMContext &Context) { // Declare success. Out->keep(); + if (DwoOut) + DwoOut->keep(); return 0; } diff --git a/tools/llvm-exegesis/lib/Assembler.cpp b/tools/llvm-exegesis/lib/Assembler.cpp index 81185064eef..30723e584ce 100644 --- a/tools/llvm-exegesis/lib/Assembler.cpp +++ b/tools/llvm-exegesis/lib/Assembler.cpp @@ -167,8 +167,8 @@ void assembleToStream(std::unique_ptr TM, TPC->setInitialized(); // AsmPrinter is responsible for generating the assembly into AsmBuffer. - if (TM->addAsmPrinter(PM, AsmStream, llvm::TargetMachine::CGFT_ObjectFile, - MCContext)) + if (TM->addAsmPrinter(PM, AsmStream, nullptr, + llvm::TargetMachine::CGFT_ObjectFile, MCContext)) llvm::report_fatal_error("Cannot add AsmPrinter passes"); PM.run(*Module); // Run all the passes diff --git a/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp b/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp index 6b71e0f6b06..0cab6799f22 100644 --- a/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp +++ b/tools/llvm-isel-fuzzer/llvm-isel-fuzzer.cpp @@ -99,7 +99,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { TargetLibraryInfoImpl TLII(TM->getTargetTriple()); PM.add(new TargetLibraryInfoWrapperPass(TLII)); raw_null_ostream OS; - TM->addPassesToEmitFile(PM, OS, TargetMachine::CGFT_Null); + TM->addPassesToEmitFile(PM, OS, nullptr, TargetMachine::CGFT_Null); PM.run(*M); return 0;