[ThinLTO] Implement -pass-remarks-output in ThinLTOCodeGenerator
authorMehdi Amini <mehdi.amini@apple.com>
Sat, 19 Nov 2016 18:20:05 +0000 (18:20 +0000)
committerMehdi Amini <mehdi.amini@apple.com>
Sat, 19 Nov 2016 18:20:05 +0000 (18:20 +0000)
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

llvm/lib/LTO/LTOCodeGenerator.cpp
llvm/lib/LTO/ThinLTOCodeGenerator.cpp
llvm/test/ThinLTO/X86/Inputs/diagnostic-handler-remarks.ll [new file with mode: 0644]
llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll [new file with mode: 0644]

index 146ad45..2b31afc 100644 (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;
index 4d3154b..fdb54ee 100644 (file)
 #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);
diff --git a/llvm/test/ThinLTO/X86/Inputs/diagnostic-handler-remarks.ll b/llvm/test/ThinLTO/X86/Inputs/diagnostic-handler-remarks.ll
new file mode 100644 (file)
index 0000000..35154e6
--- /dev/null
@@ -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
+}
+
diff --git a/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll b/llvm/test/ThinLTO/X86/diagnostic-handler-remarks.ll
new file mode 100644 (file)
index 0000000..9dc0e96
--- /dev/null
@@ -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
+}
+