timshen updated this revision to Diff 100488.
timshen added a comment.

Add opt support and llvm test.


https://reviews.llvm.org/D33525

Files:
  clang/lib/CodeGen/BackendUtil.cpp
  clang/test/CodeGen/thin_link_bitcode.c
  llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
  llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
  llvm/test/Transforms/ThinLTOBitcodeWriter/new-pm.ll
  llvm/tools/opt/NewPMDriver.cpp
  llvm/tools/opt/NewPMDriver.h
  llvm/tools/opt/opt.cpp

Index: llvm/tools/opt/opt.cpp
===================================================================
--- llvm/tools/opt/opt.cpp
+++ llvm/tools/opt/opt.cpp
@@ -529,12 +529,19 @@
     // The user has asked to use the new pass manager and provided a pipeline
     // string. Hand off the rest of the functionality to the new code for that
     // layer.
-    return runPassPipeline(argv[0], *M, TM.get(), Out.get(),
-                           PassPipeline, OK, VK, PreserveAssemblyUseListOrder,
-                           PreserveBitcodeUseListOrder, EmitSummaryIndex,
-                           EmitModuleHash)
-               ? 0
-               : 1;
+    Optional<tool_output_file *> ThinLTOBC;
+    if (OutputThinLTOBC)
+      ThinLTOBC.emplace(ThinLinkOut.get());
+    if (!runPassPipeline(argv[0], *M, TM.get(), Out.get(), PassPipeline, OK, VK,
+                         PreserveAssemblyUseListOrder,
+                         PreserveBitcodeUseListOrder, EmitSummaryIndex,
+                         EmitModuleHash, ThinLTOBC))
+      return 1;
+
+    if (ThinLinkOut)
+      ThinLinkOut->keep();
+
+    return 0;
   }
 
   // Create a PassManager to hold and optimize the collection of passes we are
Index: llvm/tools/opt/NewPMDriver.h
===================================================================
--- llvm/tools/opt/NewPMDriver.h
+++ llvm/tools/opt/NewPMDriver.h
@@ -21,6 +21,8 @@
 #ifndef LLVM_TOOLS_OPT_NEWPMDRIVER_H
 #define LLVM_TOOLS_OPT_NEWPMDRIVER_H
 
+#include <llvm/ADT/Optional.h>
+
 namespace llvm {
 class StringRef;
 class LLVMContext;
@@ -47,13 +49,16 @@
 /// inclusion of the new pass manager headers and the old headers into the same
 /// file. It's interface is consequentially somewhat ad-hoc, but will go away
 /// when the transition finishes.
-bool runPassPipeline(StringRef Arg0, Module &M,
-                     TargetMachine *TM, tool_output_file *Out,
-                     StringRef PassPipeline, opt_tool::OutputKind OK,
-                     opt_tool::VerifierKind VK,
+///
+/// ThinLTOBC indicates whether to use ThinLTO's bitcode writer, and if so,
+/// the optional link file path.
+bool runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
+                     tool_output_file *Out, StringRef PassPipeline,
+                     opt_tool::OutputKind OK, opt_tool::VerifierKind VK,
                      bool ShouldPreserveAssemblyUseListOrder,
                      bool ShouldPreserveBitcodeUseListOrder,
-                     bool EmitSummaryIndex, bool EmitModuleHash);
+                     bool EmitSummaryIndex, bool EmitModuleHash,
+                     Optional<tool_output_file *> ThinLTOBC);
 }
 
 #endif
Index: llvm/tools/opt/NewPMDriver.cpp
===================================================================
--- llvm/tools/opt/NewPMDriver.cpp
+++ llvm/tools/opt/NewPMDriver.cpp
@@ -29,6 +29,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/ToolOutputFile.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Scalar/LoopPassManager.h"
 
 using namespace llvm;
@@ -47,13 +48,13 @@
                         "pipeline for handling managed aliasing queries"),
                cl::Hidden);
 
-bool llvm::runPassPipeline(StringRef Arg0, Module &M,
-                           TargetMachine *TM, tool_output_file *Out,
-                           StringRef PassPipeline, OutputKind OK,
-                           VerifierKind VK,
+bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
+                           tool_output_file *Out, StringRef PassPipeline,
+                           OutputKind OK, VerifierKind VK,
                            bool ShouldPreserveAssemblyUseListOrder,
                            bool ShouldPreserveBitcodeUseListOrder,
-                           bool EmitSummaryIndex, bool EmitModuleHash) {
+                           bool EmitSummaryIndex, bool EmitModuleHash,
+                           Optional<tool_output_file *> ThinLTOBC) {
   PassBuilder PB(TM);
 
   // Specially handle the alias analysis manager so that we can register
@@ -101,8 +102,12 @@
         PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder));
     break;
   case OK_OutputBitcode:
-    MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder,
-                                  EmitSummaryIndex, EmitModuleHash));
+    if (ThinLTOBC)
+      MPM.addPass(ThinLTOBitcodeWriterPass(
+          Out->os(), *ThinLTOBC ? &(*ThinLTOBC)->os() : nullptr));
+    else
+      MPM.addPass(BitcodeWriterPass(
+          Out->os(), ShouldPreserveBitcodeUseListOrder, false, EmitModuleHash));
     break;
   }
 
Index: llvm/test/Transforms/ThinLTOBitcodeWriter/new-pm.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/ThinLTOBitcodeWriter/new-pm.ll
@@ -0,0 +1,9 @@
+; RUN: opt -passes='lto<O2>' -debug-pass-manager -thinlto-bc -thin-link-bitcode-file=%t2 -o %t %s 2>&1 | FileCheck %s --check-prefix=DEBUG_PM
+; RUN: llvm-bcanalyzer -dump %t2 | FileCheck %s --check-prefix=BITCODE
+
+; DEBUG_PM: ThinLTOBitcodeWriterPass
+; BITCODE: Foo
+
+define void @Foo() {
+  ret void
+}
Index: llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
===================================================================
--- llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
+++ llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
@@ -7,13 +7,11 @@
 //
 //===----------------------------------------------------------------------===//
 //
-// This pass prepares a module containing type metadata for ThinLTO by splitting
-// it into regular and thin LTO parts if possible, and writing both parts to
-// a multi-module bitcode file. Modules that do not contain type metadata are
-// written unmodified as a single module.
+// Pass implementation.
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Analysis/BasicAliasAnalysis.h"
 #include "llvm/Analysis/ModuleSummaryAnalysis.h"
 #include "llvm/Analysis/ProfileSummaryInfo.h"
@@ -436,3 +434,15 @@
                                                 raw_ostream *ThinLinkOS) {
   return new WriteThinLTOBitcode(Str, ThinLinkOS);
 }
+
+PreservedAnalyses
+llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
+  FunctionAnalysisManager &FAM =
+      AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+  writeThinLTOBitcode(OS, ThinLinkOS,
+                      [&FAM](Function &F) -> AAResults & {
+                        return FAM.getResult<AAManager>(F);
+                      },
+                      M, &AM.getResult<ModuleSummaryIndexAnalysis>(M));
+  return PreservedAnalyses::all();
+}
Index: llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
===================================================================
--- /dev/null
+++ llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
@@ -0,0 +1,39 @@
+//===- ThinLTOBitcodeWriter.h - Bitcode writing pass for ThinLTO ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass prepares a module containing type metadata for ThinLTO by splitting
+// it into regular and thin LTO parts if possible, and writing both parts to
+// a multi-module bitcode file. Modules that do not contain type metadata are
+// written unmodified as a single module.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_IPO_THINLTOBITCODEWRITER_H
+#define LLVM_TRANSFORMS_IPO_THINLTOBITCODEWRITER_H
+
+#include <llvm/IR/PassManager.h>
+#include <llvm/Support/raw_ostream.h>
+
+namespace llvm {
+
+class ThinLTOBitcodeWriterPass
+    : public PassInfoMixin<ThinLTOBitcodeWriterPass> {
+  raw_ostream &OS;
+  raw_ostream *ThinLinkOS;
+
+public:
+  ThinLTOBitcodeWriterPass(raw_ostream &OS, raw_ostream *ThinLinkOS)
+      : OS(OS), ThinLinkOS(ThinLinkOS) {}
+
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif
Index: clang/test/CodeGen/thin_link_bitcode.c
===================================================================
--- clang/test/CodeGen/thin_link_bitcode.c
+++ clang/test/CodeGen/thin_link_bitcode.c
@@ -1,6 +1,9 @@
 // RUN: %clang_cc1 -o %t -flto=thin -fthin-link-bitcode=%t.nodebug -triple x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited %s
 // RUN: llvm-bcanalyzer -dump %t | FileCheck %s
 // RUN: llvm-bcanalyzer -dump %t.nodebug | FileCheck %s --check-prefix=NO_DEBUG
+// RUN: %clang_cc1 -o %t.newpm -flto=thin -fexperimental-new-pass-manager -fthin-link-bitcode=%t.newpm.nodebug -triple x86_64-unknown-linux-gnu -emit-llvm-bc -debug-info-kind=limited  %s
+// RUN: llvm-bcanalyzer -dump %t.newpm | FileCheck %s
+// RUN: llvm-bcanalyzer -dump %t.newpm.nodebug | FileCheck %s --check-prefix=NO_DEBUG
 int main (void) {
   return 0;
 }
Index: clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- clang/lib/CodeGen/BackendUtil.cpp
+++ clang/lib/CodeGen/BackendUtil.cpp
@@ -49,6 +49,7 @@
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
 #include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/ObjCARC.h"
 #include "llvm/Transforms/Scalar.h"
@@ -898,16 +899,32 @@
   // create that pass manager here and use it as needed below.
   legacy::PassManager CodeGenPasses;
   bool NeedCodeGen = false;
+  Optional<raw_fd_ostream> ThinLinkOS;
 
   // Append any output we need to the pass manager.
   switch (Action) {
   case Backend_EmitNothing:
     break;
 
   case Backend_EmitBC:
-    MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
-                                  CodeGenOpts.EmitSummaryIndex,
-                                  CodeGenOpts.EmitSummaryIndex));
+    if (CodeGenOpts.EmitSummaryIndex) {
+      if (!CodeGenOpts.ThinLinkBitcodeFile.empty()) {
+        std::error_code EC;
+        ThinLinkOS.emplace(CodeGenOpts.ThinLinkBitcodeFile, EC,
+                           llvm::sys::fs::F_None);
+        if (EC) {
+          Diags.Report(diag::err_fe_unable_to_open_output)
+              << CodeGenOpts.ThinLinkBitcodeFile << EC.message();
+          return;
+        }
+      }
+      MPM.addPass(
+          ThinLTOBitcodeWriterPass(*OS, ThinLinkOS ? &*ThinLinkOS : nullptr));
+    } else {
+      MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
+                                    CodeGenOpts.EmitSummaryIndex,
+                                    CodeGenOpts.EmitSummaryIndex));
+    }
     break;
 
   case Backend_EmitLL:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to