[ThinLTO] Implement -pass-remarks-output in ThinLTOCodeGenerator

Summary:
This will also be added to the LTO API, right now this will
bring ThinLTO on par with Monolithic LTO on Darwin.

Reviewers: anemet

Subscribers: tejohnson, llvm-commits

Differential Revision: https://reviews.llvm.org/D26886

llvm-svn: 287450
This commit is contained in:
Mehdi Amini 2016-11-19 18:20:05 +00:00
parent 6f40836823
commit 19f176b982
4 changed files with 95 additions and 7 deletions

View File

@ -91,12 +91,12 @@ cl::opt<bool> LTOStripInvalidDebugInfo(
cl::init(false),
#endif
cl::Hidden);
}
static cl::opt<std::string>
RemarksFilename("pass-remarks-output",
cl::desc("Output filename for pass remarks"),
cl::value_desc("filename"));
cl::opt<std::string>
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 @@ void LTOCodeGenerator::verifyMergedModuleOnce() {
}
bool LTOCodeGenerator::setupOptimizationRemarks() {
if (RemarksFilename != "") {
if (LTORemarksFilename != "") {
std::error_code EC;
DiagnosticOutputFile = llvm::make_unique<tool_output_file>(
RemarksFilename, EC, sys::fs::F_None);
LTORemarksFilename, EC, sys::fs::F_None);
if (EC) {
emitError(EC.message());
return false;

View File

@ -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 @@ using namespace llvm;
namespace llvm {
// Flags -discard-value-names, defined in LTOCodeGenerator.cpp
extern cl::opt<bool> LTODiscardValueNames;
extern cl::opt<std::string> LTORemarksFilename;
}
namespace {
@ -69,6 +72,24 @@ namespace {
static cl::opt<int>
ThreadCount("threads", cl::init(llvm::heavyweight_hardware_concurrency()));
Expected<std::unique_ptr<tool_output_file>>
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<tool_output_file>(FileName, EC, sys::fs::F_None);
if (EC)
return errorCodeToError(EC);
Ctx.setDiagnosticsOutputFile(
llvm::make_unique<yaml::Output>(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 @@ void ThinLTOCodeGenerator::run() {
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);

View File

@ -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
}

View File

@ -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
}