Index: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp @@ -91,12 +91,12 @@ cl::init(false), #endif cl::Hidden); -} -static cl::opt - RemarksFilename("pass-remarks-output", - cl::desc("Output filename for pass remarks"), - cl::value_desc("filename")); +cl::opt + LTORemarksFilename("pass-remarks-output", + cl::desc("Output filename for pass remarks"), + cl::value_desc("filename")); +} LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context) : Context(Context), MergedModule(new Module("ld-temp.o", Context)), @@ -502,10 +502,10 @@ } bool LTOCodeGenerator::setupOptimizationRemarks() { - if (RemarksFilename != "") { + if (LTORemarksFilename != "") { std::error_code EC; DiagnosticOutputFile = llvm::make_unique( - RemarksFilename, EC, sys::fs::F_None); + LTORemarksFilename, EC, sys::fs::F_None); if (EC) { emitError(EC.message()); return false; Index: llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp =================================================================== --- llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp +++ llvm/trunk/lib/LTO/ThinLTOCodeGenerator.cpp @@ -40,11 +40,13 @@ #include "llvm/Object/ModuleSummaryIndexObjectFile.h" #include "llvm/Support/CachePruning.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Error.h" #include "llvm/Support/Path.h" #include "llvm/Support/SHA1.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/ThreadPool.h" #include "llvm/Support/Threading.h" +#include "llvm/Support/ToolOutputFile.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/FunctionImport.h" @@ -62,6 +64,7 @@ namespace llvm { // Flags -discard-value-names, defined in LTOCodeGenerator.cpp extern cl::opt LTODiscardValueNames; +extern cl::opt LTORemarksFilename; } namespace { @@ -69,6 +72,24 @@ static cl::opt ThreadCount("threads", cl::init(llvm::heavyweight_hardware_concurrency())); +Expected> +setupOptimizationRemarks(LLVMContext &Ctx, int Count) { + if (LTORemarksFilename.empty()) + return nullptr; + + std::string FileName = + LTORemarksFilename + ".thin." + llvm::utostr(Count) + ".yaml"; + std::error_code EC; + auto DiagnosticOutputFile = + llvm::make_unique(FileName, EC, sys::fs::F_None); + if (EC) + return errorCodeToError(EC); + Ctx.setDiagnosticsOutputFile( + llvm::make_unique(DiagnosticOutputFile->os())); + DiagnosticOutputFile->keep(); + return std::move(DiagnosticOutputFile); +} + // Simple helper to save temporary files for debug. static void saveTempBitcode(const Module &TheModule, StringRef TempDir, unsigned count, StringRef Suffix) { @@ -834,6 +855,12 @@ LLVMContext Context; Context.setDiscardValueNames(LTODiscardValueNames); Context.enableDebugTypeODRUniquing(); + auto DiagFileOrErr = setupOptimizationRemarks(Context, count); + if (!DiagFileOrErr) { + errs() << "Error: " << toString(DiagFileOrErr.takeError()) << "\n"; + report_fatal_error("ThinLTO: Can't get an output file for the " + "remarks"); + } // Parse module now auto TheModule = loadModuleFromBuffer(ModuleBuffer, Context, false); Index: llvm/trunk/test/ThinLTO/X86/Inputs/diagnostic-handler-remarks.ll =================================================================== --- llvm/trunk/test/ThinLTO/X86/Inputs/diagnostic-handler-remarks.ll +++ llvm/trunk/test/ThinLTO/X86/Inputs/diagnostic-handler-remarks.ll @@ -0,0 +1,10 @@ +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.11.0" + + +declare i32 @bar() +define i32 @foo() { + %a = call i32 @bar() + ret i32 %a +} + Index: llvm/trunk/test/ThinLTO/X86/diagnostic-handler-remarks.ll =================================================================== --- llvm/trunk/test/ThinLTO/X86/diagnostic-handler-remarks.ll +++ llvm/trunk/test/ThinLTO/X86/diagnostic-handler-remarks.ll @@ -0,0 +1,51 @@ +; RUN: opt -module-summary %s -o %t1.bc +; RUN: opt -module-summary %p/Inputs/diagnostic-handler-remarks.ll -o %t2.bc + +; Optimization records are collected regardless of the diagnostic handler +; RUN: llvm-lto -thinlto-action=run \ +; RUN: -pass-remarks-output=%t.yaml \ +; RUN: -exported-symbol _func2 \ +; RUN: -exported-symbol _main %t1.bc %t2.bc 2>&1 | \ +; RUN: FileCheck %s -allow-empty +; CHECK-NOT: remark: +; CHECK-NOT: llvm-lto: + + +; Verify that bar is imported and inlined into foo +; RUN: cat %t.yaml.thin.0.yaml | FileCheck %s -check-prefix=YAML1 +; YAML1: --- !Passed +; YAML1: Pass: inline +; YAML1: Name: Inlined +; YAML1: Function: main +; YAML1: Args: +; YAML1: - Callee: foo +; YAML1: - String: ' inlined into ' +; YAML1: - Caller: main +; YAML1: ... + + +; Verify that bar is imported and inlined into foo +; RUN: cat %t.yaml.thin.1.yaml | FileCheck %s -check-prefix=YAML2 +; YAML2: --- !Passed +; YAML2: Pass: inline +; YAML2: Name: Inlined +; YAML2: Function: foo +; YAML2: Args: +; YAML2: - Callee: bar +; YAML2: - String: ' inlined into ' +; YAML2: - Caller: foo +; YAML2: ... + + +target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.11.0" + +define i32 @bar() { + ret i32 42 +} +declare i32 @foo() +define i32 @main() { + %i = call i32 @foo() + ret i32 %i +} +