Index: include/llvm/IR/ThinLTOInfo.h =================================================================== --- /dev/null +++ include/llvm/IR/ThinLTOInfo.h @@ -0,0 +1,178 @@ +//===-- llvm/ThinLTOInfo.h - ThinLTO Index and Summary ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// @file +/// ThinLtoInfo.h This file contains the declarations the classes that hold +// the ThinLTO function index and summary. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_THINLTOINFO_H +#define LLVM_IR_THINLTOINFO_H + +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/MemoryBuffer.h" + +namespace llvm { + +// Function summary information to aid in importing decisions. +class ThinLTOFunctionSummary { + private: + // TBD (includes function size, hotness, ...) +}; + +// Class to hold function's bitcode index and summary info. +class ThinLTOFunctionInfo { + // Path of module containing function IR + StringRef ModulePath; + // Index of function within bitcode module block in its module. + uint64_t BitcodeIndex; + // Function summary information used to help make importing decisions. + ThinLTOFunctionSummary *FunctionSummary; + // Used during bitcode parsing and writing to hold the offset of the + // corresponding function summary in the function summary section. + uint64_t FunctionSummarySecOffset; + // True if we are still parsing into this instance. + bool Parsing; + // Used to flag functions that have local linkage types and need to + // have module identifier appended before placing into the combined + // index, to disambiguiate from other functions with the same name. + bool IsLocalFunction; + + public: + // Constructed during parsing + ThinLTOFunctionInfo(uint64_t SecOffset) : + FunctionSummary(nullptr), + FunctionSummarySecOffset(SecOffset), + Parsing(true), + IsLocalFunction(false) { } + + ~ThinLTOFunctionInfo() { + // Support sharing FunctionSummary object between per-module and + // combined indexes. + if (FunctionSummary) + delete FunctionSummary; + } + + // Use the default copy constructor (when creating combined index), + // which will cause the same ThinLTOFunctionSummary object to be shared. + + // Record the function information parsed out of the function + // summary block. + void recordParsedInfo(StringRef ModPath, uint64_t BitcodeIdx, + ThinLTOFunctionSummary *FuncSummary) { + assert(Parsing); + Parsing = false; + ModulePath = ModPath; + BitcodeIndex = BitcodeIdx; + FunctionSummary = FuncSummary; + } + + StringRef modulePath() const { + assert(!Parsing); + return ModulePath; + } + + uint64_t bitcodeIndex() const { + assert(!Parsing); + return BitcodeIndex; + } + + ThinLTOFunctionSummary *functionSummary() const { + assert(!Parsing); + return FunctionSummary; + } + + void isLocalFunction(bool Local) { + IsLocalFunction = Local; + } + bool isLocalFunction() const { + return IsLocalFunction; + } +}; + +typedef std::vector ThinLTOFunctionInfoList; +typedef StringMap ThinLTOFunctionMap; +typedef StringMap ThinLTOModulePathStringTable; + +// Class to hold module path string table and ThinLTOFunctionMap, +// and encapsulate methods for operating on them. +class ThinLTOFunctionSummaryIndex { + public: + typedef ThinLTOFunctionMap::const_iterator const_funcinfo_iterator; + + private: + // Map from function name to list of function information instances + // for functions of that name (may be duplicates in the COMDAT case, e.g.). + ThinLTOFunctionMap FunctionMap; + + // Holds strings for combined index, mapping to the corresponding module ID. + ThinLTOModulePathStringTable ModulePathStringTable; + + // Used for assigning module ids when per-module index structures merged + // to form combined index, necessary for consistent renaming of promoted + // static (local) variables. + static uint64_t NextModuleId; + + public: + ThinLTOFunctionSummaryIndex() { } + + // Use default copy constructor. For the StringMaps this will + // call std::swap during the assignment. + + // Use when the ThinLTOFunctionMap has already been created + // (e.g. from a native object wrapped bitcode file's symtab). + void setFunctionMap(ThinLTOFunctionMap &&FuncMap) { + FunctionMap = std::move(FuncMap); + } + + const_funcinfo_iterator funcinfo_begin() const { + return FunctionMap.begin(); + } + const_funcinfo_iterator funcinfo_end() const { + return FunctionMap.end(); + } + + // Return the list of function info objects for a given function. + ThinLTOFunctionInfoList getFunctionInfoList(StringRef FuncName) const { + return FunctionMap.lookup(FuncName); + } + + // Add a function info for a function of the given name. + void addFunctionInfo(StringRef FuncName, + ThinLTOFunctionInfo Info) { + if (FunctionMap.count(FuncName)) + FunctionMap.lookup(FuncName).push_back(Info); + else + FunctionMap.insert(std::make_pair(FuncName, + ThinLTOFunctionInfoList(1, Info))); + } + + // Add a new module path, mapped to the given module Id, and return StringRef + // owned by string table map. + StringRef addModulePath(StringRef ModPath, uint64_t ModId) { + return ModulePathStringTable.insert( + std::make_pair(ModPath, ModId)).first->first(); + } + + // Iterator to allow writer to walk through table during emission. + iterator_range::const_iterator> + modPathStringEntries() const { + return llvm::make_range(ModulePathStringTable.begin(), + ModulePathStringTable.end()); + } + + // Used to create the combined function index/summary from multiple + // per-module instances. + void mergeFrom(ThinLTOFunctionSummaryIndex *Other); +}; + +} // End llvm namespace + +#endif Index: lib/IR/CMakeLists.txt =================================================================== --- lib/IR/CMakeLists.txt +++ lib/IR/CMakeLists.txt @@ -39,6 +39,7 @@ PassManager.cpp PassRegistry.cpp Statepoint.cpp + ThinLTOInfo.cpp Type.cpp TypeFinder.cpp Use.cpp Index: lib/IR/ThinLTOInfo.cpp =================================================================== --- /dev/null +++ lib/IR/ThinLTOInfo.cpp @@ -0,0 +1,68 @@ +//===-- ThinLTOInfo.cpp - ThinLTO Index and Summary -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements ThinLTO function index and summary classes for the +// IR library. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/ThinLTOInfo.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringMap.h" +using namespace llvm; + +uint64_t ThinLTOFunctionSummaryIndex::NextModuleId = 0; + +// Used to create the combined function index/summary from multiple +// per-module instances. +void ThinLTOFunctionSummaryIndex::mergeFrom( + ThinLTOFunctionSummaryIndex *Other) { + + ++NextModuleId; + + const_funcinfo_iterator OtherFuncInfoLists = Other->funcinfo_begin(); + StringRef ModPath; + for (; OtherFuncInfoLists != Other->funcinfo_end(); OtherFuncInfoLists++) { + StringRef FuncName = OtherFuncInfoLists->getKey(); + ThinLTOFunctionInfoList List = OtherFuncInfoLists->second; + + // Assert that the func info list only has one entry. + assert(List.size() == 1); + // Note the module path string ref is copied and still owned by the + // original per-module ThinLTOFunctionInfo. This should be ok, we + // just need to keep those around until the combined index is written. + // The string ref is eventually just used to get the offset of the + // string in the string table we are building, after it is finalized. + ThinLTOFunctionInfo Info = List.front(); + + if (ModPath.empty()) { + ModPath = Info.modulePath(); + addModulePath(ModPath, NextModuleId); + } + else + assert(ModPath == Info.modulePath()); + + // If it is a local function, rename it. + if (Info.isLocalFunction()) { + // Any local functions are virtually renamed when being added to the + // combined index map, to disambiguate from other functions with + // the same name. The symbol table created for the compiled index + // file should contain the renamed symbols. + SmallString<256> NewName(FuncName); + NewName += ".llvm."; + NewName += NextModuleId; + FuncName = NewName.str(); + } + + // Add func info to existing list. + // There may be duplicates when combining ThinLTOFunctionMap entries, + // due to COMDAT functions. Any local functions are virtually renamed + addFunctionInfo(FuncName, Info); + } +}