1cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//===- FunctionImport.cpp - ThinLTO Summary-based Function Import ---------===//
2cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//
3cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//                     The LLVM Compiler Infrastructure
4cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//
5cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// This file is distributed under the University of Illinois Open Source
6cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// License. See LICENSE.TXT for details.
7cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//
8cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
9cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//
10cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// This file implements Function import based on summaries.
11cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//
12cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//===----------------------------------------------------------------------===//
13cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
14cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/Transforms/IPO/FunctionImport.h"
15cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
16cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/ADT/StringSet.h"
17cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/IR/AutoUpgrade.h"
18cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/IR/DiagnosticPrinter.h"
19cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/IR/IntrinsicInst.h"
20cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/IR/Module.h"
21cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/IRReader/IRReader.h"
22cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/Linker/Linker.h"
23cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/Object/FunctionIndexObjectFile.h"
24cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/Support/CommandLine.h"
25cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/Support/Debug.h"
26cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/Support/SourceMgr.h"
27cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
28cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include <map>
29cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
30cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarusing namespace llvm;
31cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
32cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#define DEBUG_TYPE "function-import"
33cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
34cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// Limit on instruction count of imported functions.
35cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic cl::opt<unsigned> ImportInstrLimit(
36cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    "import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"),
37cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    cl::desc("Only import functions with less than N instructions"));
38cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
39cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// Load lazily a module from \p FileName in \p Context.
40cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic std::unique_ptr<Module> loadFile(const std::string &FileName,
41cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                        LLVMContext &Context) {
42cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  SMDiagnostic Err;
43cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  DEBUG(dbgs() << "Loading '" << FileName << "'\n");
44cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::unique_ptr<Module> Result = getLazyIRFileModule(FileName, Err, Context);
45cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (!Result) {
46cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Err.print("function-import", errs());
47cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return nullptr;
48cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
49cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
50cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Result->materializeMetadata();
51cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  UpgradeDebugInfo(*Result);
52cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
53cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return Result;
54cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
55cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
56cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarnamespace {
57cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// Helper to load on demand a Module from file and cache it for subsequent
58cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// queries. It can be used with the FunctionImporter.
59cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarclass ModuleLazyLoaderCache {
60cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  /// Cache of lazily loaded module for import.
61cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  StringMap<std::unique_ptr<Module>> ModuleMap;
62cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
63cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  /// Retrieve a Module from the cache or lazily load it on demand.
64cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::function<std::unique_ptr<Module>(StringRef FileName)> createLazyModule;
65cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
66cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarpublic:
67cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  /// Create the loader, Module will be initialized in \p Context.
68cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ModuleLazyLoaderCache(std::function<
69cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      std::unique_ptr<Module>(StringRef FileName)> createLazyModule)
70cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      : createLazyModule(createLazyModule) {}
71cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
72cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  /// Retrieve a Module from the cache or lazily load it on demand.
73cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Module &operator()(StringRef FileName);
74cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
75cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::unique_ptr<Module> takeModule(StringRef FileName) {
76cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto I = ModuleMap.find(FileName);
77cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    assert(I != ModuleMap.end());
78cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    std::unique_ptr<Module> Ret = std::move(I->second);
79cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    ModuleMap.erase(I);
80cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return Ret;
81cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
82cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar};
83cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
84cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// Get a Module for \p FileName from the cache, or load it lazily.
85cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarModule &ModuleLazyLoaderCache::operator()(StringRef Identifier) {
86cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  auto &Module = ModuleMap[Identifier];
87cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (!Module)
88cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Module = createLazyModule(Identifier);
89cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return *Module;
90cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
91cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar} // anonymous namespace
92cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
93cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// Walk through the instructions in \p F looking for external
94cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// calls not already in the \p CalledFunctions set. If any are
95cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// found they are added to the \p Worklist for importing.
96cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic void findExternalCalls(const Module &DestModule, Function &F,
97cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                              const FunctionInfoIndex &Index,
98cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                              StringSet<> &CalledFunctions,
99cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                              SmallVector<StringRef, 64> &Worklist) {
100cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // We need to suffix internal function calls imported from other modules,
101cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // prepare the suffix ahead of time.
102cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::string Suffix;
103cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (F.getParent() != &DestModule)
104cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Suffix =
105cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        (Twine(".llvm.") +
106cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar         Twine(Index.getModuleId(F.getParent()->getModuleIdentifier()))).str();
107cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
108cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  for (auto &BB : F) {
109cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    for (auto &I : BB) {
110cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      if (isa<CallInst>(I)) {
111cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        auto CalledFunction = cast<CallInst>(I).getCalledFunction();
112cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        // Insert any new external calls that have not already been
113cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        // added to set/worklist.
114cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        if (!CalledFunction || !CalledFunction->hasName())
115cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          continue;
116cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        // Ignore intrinsics early
117cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        if (CalledFunction->isIntrinsic()) {
118cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          assert(CalledFunction->getIntrinsicID() != 0);
119cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          continue;
120cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        }
121cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        auto ImportedName = CalledFunction->getName();
122cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        auto Renamed = (ImportedName + Suffix).str();
123cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        // Rename internal functions
124cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        if (CalledFunction->hasInternalLinkage()) {
125cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          ImportedName = Renamed;
126cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        }
127cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        auto It = CalledFunctions.insert(ImportedName);
128cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        if (!It.second) {
129cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          // This is a call to a function we already considered, skip.
130cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          continue;
131cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        }
132cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        // Ignore functions already present in the destination module
133cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        auto *SrcGV = DestModule.getNamedValue(ImportedName);
134cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        if (SrcGV) {
135cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          assert(isa<Function>(SrcGV) && "Name collision during import");
136cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          if (!cast<Function>(SrcGV)->isDeclaration()) {
137cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar            DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Ignoring "
138cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                         << ImportedName << " already in DestinationModule\n");
139cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar            continue;
140cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          }
141cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        }
142cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
143cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        Worklist.push_back(It.first->getKey());
144cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        DEBUG(dbgs() << DestModule.getModuleIdentifier()
145cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                     << ": Adding callee for : " << ImportedName << " : "
146cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                     << F.getName() << "\n");
147cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      }
148cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
149cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
150cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
151cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
152cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// Helper function: given a worklist and an index, will process all the worklist
153cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// and decide what to import based on the summary information.
154cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//
155cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// Nothing is actually imported, functions are materialized in their source
156cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// module and analyzed there.
157cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//
158cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// \p ModuleToFunctionsToImportMap is filled with the set of Function to import
159cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// per Module.
160cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic void GetImportList(Module &DestModule,
161cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                          SmallVector<StringRef, 64> &Worklist,
162cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                          StringSet<> &CalledFunctions,
163cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                          std::map<StringRef, DenseSet<const GlobalValue *>>
164cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                              &ModuleToFunctionsToImportMap,
165cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                          const FunctionInfoIndex &Index,
166cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                          ModuleLazyLoaderCache &ModuleLoaderCache) {
167cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  while (!Worklist.empty()) {
168cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto CalledFunctionName = Worklist.pop_back_val();
169cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Process import for "
170cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                 << CalledFunctionName << "\n");
171cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
172cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // Try to get a summary for this function call.
173cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto InfoList = Index.findFunctionInfoList(CalledFunctionName);
174cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (InfoList == Index.end()) {
175cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": No summary for "
176cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                   << CalledFunctionName << " Ignoring.\n");
177cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      continue;
178cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
179cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    assert(!InfoList->second.empty() && "No summary, error at import?");
180cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
181cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // Comdat can have multiple entries, FIXME: what do we do with them?
182cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto &Info = InfoList->second[0];
183cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    assert(Info && "Nullptr in list, error importing summaries?\n");
184cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
185cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto *Summary = Info->functionSummary();
186cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (!Summary) {
187cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      // FIXME: in case we are lazyloading summaries, we can do it now.
188cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      DEBUG(dbgs() << DestModule.getModuleIdentifier()
189cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                   << ": Missing summary for  " << CalledFunctionName
190cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                   << ", error at import?\n");
191cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      llvm_unreachable("Missing summary");
192cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
193cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
194cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (Summary->instCount() > ImportInstrLimit) {
195cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Skip import of "
196cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                   << CalledFunctionName << " with " << Summary->instCount()
197cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                   << " instructions (limit " << ImportInstrLimit << ")\n");
198cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      continue;
199cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
200cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
201cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // Get the module path from the summary.
202cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto ModuleIdentifier = Summary->modulePath();
203cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    DEBUG(dbgs() << DestModule.getModuleIdentifier() << ": Importing "
204cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                 << CalledFunctionName << " from " << ModuleIdentifier << "\n");
205cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
206cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto &SrcModule = ModuleLoaderCache(ModuleIdentifier);
207cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
208cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // The function that we will import!
209cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    GlobalValue *SGV = SrcModule.getNamedValue(CalledFunctionName);
210cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
211cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (!SGV) {
212cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      // The destination module is referencing function using their renamed name
213cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      // when importing a function that was originally local in the source
214cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      // module. The source module we have might not have been renamed so we try
215cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      // to remove the suffix added during the renaming to recover the original
216cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      // name in the source module.
217cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      std::pair<StringRef, StringRef> Split =
218cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          CalledFunctionName.split(".llvm.");
219cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      SGV = SrcModule.getNamedValue(Split.first);
220cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      assert(SGV && "Can't find function to import in source module");
221cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
222cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (!SGV) {
223cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      report_fatal_error(Twine("Can't load function '") + CalledFunctionName +
224cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                         "' in Module '" + SrcModule.getModuleIdentifier() +
225cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                         "', error in the summary?\n");
226cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
227cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
228cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Function *F = dyn_cast<Function>(SGV);
229cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (!F && isa<GlobalAlias>(SGV)) {
230cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      auto *SGA = dyn_cast<GlobalAlias>(SGV);
231cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      F = dyn_cast<Function>(SGA->getBaseObject());
232cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      CalledFunctionName = F->getName();
233cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
234cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    assert(F && "Imported Function is ... not a Function");
235cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
236cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // We cannot import weak_any functions/aliases without possibly affecting
237cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // the order they are seen and selected by the linker, changing program
238cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // semantics.
239cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (SGV->hasWeakAnyLinkage()) {
240cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      DEBUG(dbgs() << DestModule.getModuleIdentifier()
241cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                   << ": Ignoring import request for weak-any "
242cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                   << (isa<Function>(SGV) ? "function " : "alias ")
243cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                   << CalledFunctionName << " from "
244cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                   << SrcModule.getModuleIdentifier() << "\n");
245cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      continue;
246cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
247cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
248cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // Add the function to the import list
249cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto &Entry = ModuleToFunctionsToImportMap[SrcModule.getModuleIdentifier()];
250cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Entry.insert(F);
251cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
252cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // Process the newly imported functions and add callees to the worklist.
253cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    F->materialize();
254cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    findExternalCalls(DestModule, *F, Index, CalledFunctions, Worklist);
255cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
256cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
257cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
258cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// Automatically import functions in Module \p DestModule based on the summaries
259cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// index.
260cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar//
261cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// The current implementation imports every called functions that exists in the
262cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar// summaries index.
263cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarbool FunctionImporter::importFunctions(Module &DestModule) {
264cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  DEBUG(dbgs() << "Starting import for Module "
265cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar               << DestModule.getModuleIdentifier() << "\n");
266cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  unsigned ImportedCount = 0;
267cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
268cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  /// First step is collecting the called external functions.
269cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  StringSet<> CalledFunctions;
270cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  SmallVector<StringRef, 64> Worklist;
271cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  for (auto &F : DestModule) {
272cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (F.isDeclaration() || F.hasFnAttribute(Attribute::OptimizeNone))
273cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      continue;
274cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    findExternalCalls(DestModule, F, Index, CalledFunctions, Worklist);
275cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
276cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (Worklist.empty())
277cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return false;
278cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
279cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  /// Second step: for every call to an external function, try to import it.
280cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
281cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Linker that will be used for importing function
282cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Linker TheLinker(DestModule);
283cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
284cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Map of Module -> List of Function to import from the Module
285cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::map<StringRef, DenseSet<const GlobalValue *>>
286cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      ModuleToFunctionsToImportMap;
287cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
288cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Analyze the summaries and get the list of functions to import by
289cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // populating ModuleToFunctionsToImportMap
290cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ModuleLazyLoaderCache ModuleLoaderCache(ModuleLoader);
291cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  GetImportList(DestModule, Worklist, CalledFunctions,
292cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                ModuleToFunctionsToImportMap, Index, ModuleLoaderCache);
293cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  assert(Worklist.empty() && "Worklist hasn't been flushed in GetImportList");
294cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
295cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  StringMap<std::unique_ptr<DenseMap<unsigned, MDNode *>>>
296cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      ModuleToTempMDValsMap;
297cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
298cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Do the actual import of functions now, one Module at a time
299cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  for (auto &FunctionsToImportPerModule : ModuleToFunctionsToImportMap) {
300cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // Get the module for the import
301cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto &FunctionsToImport = FunctionsToImportPerModule.second;
302cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    std::unique_ptr<Module> SrcModule =
303cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        ModuleLoaderCache.takeModule(FunctionsToImportPerModule.first);
304cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    assert(&DestModule.getContext() == &SrcModule->getContext() &&
305cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar           "Context mismatch");
306cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
307cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // Save the mapping of value ids to temporary metadata created when
308cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // importing this function. If we have already imported from this module,
309cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // add new temporary metadata to the existing mapping.
310cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto &TempMDVals = ModuleToTempMDValsMap[SrcModule->getModuleIdentifier()];
311cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (!TempMDVals)
312cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      TempMDVals = llvm::make_unique<DenseMap<unsigned, MDNode *>>();
313cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
314cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // Link in the specified functions.
315cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (TheLinker.linkInModule(std::move(SrcModule), Linker::Flags::None,
316cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                               &Index, &FunctionsToImport, TempMDVals.get()))
317cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      report_fatal_error("Function Import: link error");
318cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
319cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    ImportedCount += FunctionsToImport.size();
320cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
321cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
322cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  // Now link in metadata for all modules from which we imported functions.
323cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  for (StringMapEntry<std::unique_ptr<DenseMap<unsigned, MDNode *>>> &SME :
324cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar       ModuleToTempMDValsMap) {
325cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // Load the specified source module.
326cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto &SrcModule = ModuleLoaderCache(SME.getKey());
327cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
328cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // Link in all necessary metadata from this module.
329cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (TheLinker.linkInMetadata(SrcModule, SME.getValue().get()))
330cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      return false;
331cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
332cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
333cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  DEBUG(dbgs() << "Imported " << ImportedCount << " functions for Module "
334cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar               << DestModule.getModuleIdentifier() << "\n");
335cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return ImportedCount;
336cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
337cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
338cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// Summary file to use for function importing when using -function-import from
339cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// the command line.
340cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic cl::opt<std::string>
341cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    SummaryFile("summary-file",
342cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                cl::desc("The summary file to use for function importing."));
343cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
344cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic void diagnosticHandler(const DiagnosticInfo &DI) {
345cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  raw_ostream &OS = errs();
346cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  DiagnosticPrinterRawOStream DP(OS);
347cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  DI.print(DP);
348cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  OS << '\n';
349cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
350cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
351cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// Parse the function index out of an IR file and return the function
352cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// index object if found, or nullptr if not.
353cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarstatic std::unique_ptr<FunctionInfoIndex>
354cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainargetFunctionIndexForFile(StringRef Path, std::string &Error,
355cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                        DiagnosticHandlerFunction DiagnosticHandler) {
356cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  std::unique_ptr<MemoryBuffer> Buffer;
357cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
358cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      MemoryBuffer::getFile(Path);
359cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (std::error_code EC = BufferOrErr.getError()) {
360cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Error = EC.message();
361cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return nullptr;
362cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
363cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  Buffer = std::move(BufferOrErr.get());
364cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr =
365cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      object::FunctionIndexObjectFile::create(Buffer->getMemBufferRef(),
366cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                                              DiagnosticHandler);
367cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  if (std::error_code EC = ObjOrErr.getError()) {
368cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Error = EC.message();
369cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return nullptr;
370cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
371cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return (*ObjOrErr)->takeIndex();
372cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
373cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
374cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar/// Pass that performs cross-module function import provided a summary file.
375cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarclass FunctionImportPass : public ModulePass {
376cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  /// Optional function summary index to use for importing, otherwise
377cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  /// the summary-file option must be specified.
378cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  const FunctionInfoIndex *Index;
379cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
380cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarpublic:
381cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  /// Pass identification, replacement for typeid
382cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  static char ID;
383cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
384cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  /// Specify pass name for debug output
385cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  const char *getPassName() const override {
386cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return "Function Importing";
387cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
388cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
389cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  explicit FunctionImportPass(const FunctionInfoIndex *Index = nullptr)
390cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      : ModulePass(ID), Index(Index) {}
391cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
392cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  bool runOnModule(Module &M) override {
393cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (SummaryFile.empty() && !Index)
394cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      report_fatal_error("error: -function-import requires -summary-file or "
395cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                         "file from frontend\n");
396cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    std::unique_ptr<FunctionInfoIndex> IndexPtr;
397cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    if (!SummaryFile.empty()) {
398cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      if (Index)
399cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        report_fatal_error("error: -summary-file and index from frontend\n");
400cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      std::string Error;
401cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      IndexPtr = getFunctionIndexForFile(SummaryFile, Error, diagnosticHandler);
402cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      if (!IndexPtr) {
403cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        errs() << "Error loading file '" << SummaryFile << "': " << Error
404cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar               << "\n";
405cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        return false;
406cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      }
407cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      Index = IndexPtr.get();
408cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
409cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
410cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    // Perform the import now.
411cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    auto ModuleLoader = [&M](StringRef Identifier) {
412cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      return loadFile(Identifier, M.getContext());
413cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    };
414cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    FunctionImporter Importer(*Index, ModuleLoader);
415cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return Importer.importFunctions(M);
416cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
417cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    return false;
418cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  }
419cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar};
420cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
421cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarchar FunctionImportPass::ID = 0;
422cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarINITIALIZE_PASS_BEGIN(FunctionImportPass, "function-import",
423cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                      "Summary Based Function Import", false, false)
424cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarINITIALIZE_PASS_END(FunctionImportPass, "function-import",
425cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar                    "Summary Based Function Import", false, false)
426cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar
427cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainarnamespace llvm {
428cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga NainarPass *createFunctionImportPass(const FunctionInfoIndex *Index = nullptr) {
429cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar  return new FunctionImportPass(Index);
430cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
431cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar}
432