pcc created this revision.
pcc added reviewers: tejohnson, mehdi_amini.
pcc added a subscriber: cfe-commits.
pcc added dependencies: D21542: CodeGen: Replace test/CodeGen/thinlto_backend.c 
with a functional test., D20268: [wip] Resolution-based LTO API., D21537: 
Frontend: Simplify ownership model for clang's output streams..
Herald added a subscriber: mehdi_amini.

This changes clang to use the llvm::lto::thinBackend function instead of
its own less comprehensive ThinLTO backend implementation.

Depends on D20268

Depends on D21537

Depends on D21542

http://reviews.llvm.org/D21545

Files:
  lib/CodeGen/BackendUtil.cpp
  lib/CodeGen/CMakeLists.txt
  lib/Driver/Tools.cpp
  test/Driver/thinlto_backend.c

Index: test/Driver/thinlto_backend.c
===================================================================
--- test/Driver/thinlto_backend.c
+++ test/Driver/thinlto_backend.c
@@ -6,5 +6,9 @@
 // CHECK-THINLTOBE-ACTION: -fthinlto-index=
 
 // Ensure clang driver gives the expected error for incorrect input type
-// RUN: not %clang -O2 -o %t1.o %s -c -fthinlto-index=%t.thinlto.bc 2>&1 | FileCheck %s -check-prefix=CHECK-WARNING
-// CHECK-WARNING: error: invalid argument '-fthinlto-index={{.*}}' only allowed with '-x ir'
+// RUN: not %clang -O2 -o %t1.o %s -c -fthinlto-index=%t.thinlto.bc 2>&1 | FileCheck %s -check-prefix=CHECK-ERR1
+// CHECK-ERR1: error: invalid argument '-fthinlto-index={{.*}}' only allowed with '-x ir'
+
+// And for incorrect output type
+// RUN: not %clang -O2 -o %t1.o -x ir %s -S -fthinlto-index=%t.thinlto.bc 2>&1 | FileCheck %s -check-prefix=CHECK-ERR2
+// CHECK-ERR2: error: invalid argument '-fthinlto-index={{.*}}' only allowed with '-c'
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -3891,6 +3891,9 @@
     if (!types::isLLVMIR(Input.getType()))
       D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
                                                        << "-x ir";
+    if (!isa<AssembleJobAction>(JA))
+      D.Diag(diag::err_drv_argument_only_allowed_with) << A->getAsString(Args)
+                                                       << "-c";
     Args.AddLastArg(CmdArgs, options::OPT_fthinlto_index_EQ);
   }
 
Index: lib/CodeGen/CMakeLists.txt
===================================================================
--- lib/CodeGen/CMakeLists.txt
+++ lib/CodeGen/CMakeLists.txt
@@ -8,6 +8,7 @@
   IRReader
   InstCombine
   Instrumentation
+  LTOResolution
   Linker
   MC
   ObjCARCOpts
Index: lib/CodeGen/BackendUtil.cpp
===================================================================
--- lib/CodeGen/BackendUtil.cpp
+++ lib/CodeGen/BackendUtil.cpp
@@ -29,9 +29,11 @@
 #include "llvm/IR/LegacyPassManager.h"
 #include "llvm/IR/Module.h"
 #include "llvm/IR/Verifier.h"
+#include "llvm/LTO/Resolution/LTOBackend.h"
 #include "llvm/MC/SubtargetFeature.h"
 #include "llvm/Object/ModuleSummaryIndexObjectFile.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/PrettyStackTrace.h"
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/Timer.h"
@@ -74,8 +76,7 @@
   /// Set LLVM command line options passed through -backend-option.
   void setCommandLineOpts();
 
-  void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM,
-                    ModuleSummaryIndex *ModuleSummary);
+  void CreatePasses(legacy::PassManager &MPM, legacy::FunctionPassManager &FPM);
 
   /// Generates the TargetMachine.
   /// Leaves TM unchanged if it is unable to create the target machine.
@@ -275,8 +276,7 @@
 }
 
 void EmitAssemblyHelper::CreatePasses(legacy::PassManager &MPM,
-                                      legacy::FunctionPassManager &FPM,
-                                      ModuleSummaryIndex *ModuleSummary) {
+                                      legacy::FunctionPassManager &FPM) {
   if (CodeGenOpts.DisableLLVMPasses)
     return;
 
@@ -327,14 +327,6 @@
   PMBuilder.PrepareForLTO = CodeGenOpts.PrepareForLTO;
   PMBuilder.RerollLoops = CodeGenOpts.RerollLoops;
 
-  // If we are performing a ThinLTO importing compile, invoke the LTO
-  // pipeline and pass down the in-memory module summary index.
-  if (ModuleSummary) {
-    PMBuilder.ModuleSummary = ModuleSummary;
-    PMBuilder.populateThinLTOPassManager(MPM);
-    return;
-  }
-
   // Add target-specific passes that need to run as early as possible.
   if (TM)
     PMBuilder.addExtension(
@@ -652,35 +644,15 @@
   if (TM)
     TheModule->setDataLayout(TM->createDataLayout());
 
-  // If we are performing a ThinLTO importing compile, load the function
-  // index into memory and pass it into CreatePasses, which will add it
-  // to the PassManagerBuilder and invoke LTO passes.
-  std::unique_ptr<ModuleSummaryIndex> ModuleSummary;
-  if (!CodeGenOpts.ThinLTOIndexFile.empty()) {
-    ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
-        llvm::getModuleSummaryIndexForFile(
-            CodeGenOpts.ThinLTOIndexFile, [&](const DiagnosticInfo &DI) {
-              TheModule->getContext().diagnose(DI);
-            });
-    if (std::error_code EC = IndexOrErr.getError()) {
-      std::string Error = EC.message();
-      errs() << "Error loading index file '" << CodeGenOpts.ThinLTOIndexFile
-             << "': " << Error << "\n";
-      return;
-    }
-    ModuleSummary = std::move(IndexOrErr.get());
-    assert(ModuleSummary && "Expected non-empty module summary index");
-  }
-
   legacy::PassManager PerModulePasses;
   PerModulePasses.add(
       createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
 
   legacy::FunctionPassManager PerFunctionPasses(TheModule);
   PerFunctionPasses.add(
       createTargetTransformInfoWrapperPass(getTargetIRAnalysis()));
 
-  CreatePasses(PerModulePasses, PerFunctionPasses, ModuleSummary.get());
+  CreatePasses(PerModulePasses, PerFunctionPasses);
 
   legacy::PassManager CodeGenPasses;
   CodeGenPasses.add(
@@ -733,12 +705,72 @@
   }
 }
 
+static void runThinLTOBackend(const CodeGenOptions &CGOpts, Module *M,
+                              std::unique_ptr<raw_pwrite_stream> OS) {
+  // If we are performing a ThinLTO importing compile, load the function index
+  // into memory and pass it into thinBackend, which will run the function
+  // importer and invoke LTO passes.
+  ErrorOr<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
+      llvm::getModuleSummaryIndexForFile(
+          CGOpts.ThinLTOIndexFile,
+          [&](const DiagnosticInfo &DI) { M->getContext().diagnose(DI); });
+  if (std::error_code EC = IndexOrErr.getError()) {
+    std::string Error = EC.message();
+    errs() << "Error loading index file '" << CGOpts.ThinLTOIndexFile
+           << "': " << Error << "\n";
+    return;
+  }
+  std::unique_ptr<ModuleSummaryIndex> CombinedIndex = std::move(*IndexOrErr);
+
+  auto AddStream = [&](size_t Task) { return std::move(OS); };
+
+  StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>>
+      ModuleToDefinedGVSummaries;
+  CombinedIndex->collectDefinedGVSummariesPerModule(ModuleToDefinedGVSummaries);
+
+  StringMap<FunctionImporter::ImportMapTy> ImportLists;
+  StringMap<FunctionImporter::ExportSetTy> ExportLists;
+  ComputeCrossModuleImport(*CombinedIndex, ModuleToDefinedGVSummaries,
+                           ImportLists, ExportLists);
+
+  std::vector<std::unique_ptr<llvm::MemoryBuffer>> OwnedImports;
+  MapVector<llvm::StringRef, llvm::MemoryBufferRef> ModuleMap;
+
+  auto &ImportList = ImportLists[M->getModuleIdentifier()];
+  for (auto &I : ImportList) {
+    ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> MBOrErr =
+        llvm::MemoryBuffer::getFile(I.first());
+    if (!MBOrErr) {
+      errs() << "Error loading imported file '" << I.first()
+             << "': " << MBOrErr.getError().message() << "\n";
+      return;
+    }
+    ModuleMap[I.first()] = (*MBOrErr)->getMemBufferRef();
+    OwnedImports.push_back(std::move(*MBOrErr));
+  }
+
+  lto::Config Conf;
+  if (Error E = thinBackend(
+          Conf, 0, AddStream, *M, *CombinedIndex,
+          ImportLists[M->getModuleIdentifier()],
+          ModuleToDefinedGVSummaries[M->getModuleIdentifier()], ModuleMap)) {
+    handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
+      errs() << "Error running ThinLTO backend: " << EIB.message() << '\n';
+    });
+  }
+}
+
 void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
                               const CodeGenOptions &CGOpts,
                               const clang::TargetOptions &TOpts,
                               const LangOptions &LOpts, const llvm::DataLayout &TDesc,
                               Module *M, BackendAction Action,
                               std::unique_ptr<raw_pwrite_stream> OS) {
+  if (!CGOpts.ThinLTOIndexFile.empty()) {
+    runThinLTOBackend(CGOpts, M, std::move(OS));
+    return;
+  }
+
   EmitAssemblyHelper AsmHelper(Diags, CGOpts, TOpts, LOpts, M);
 
   AsmHelper.EmitAssembly(Action, std::move(OS));
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to