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