Home | History | Annotate | Line # | Download | only in legacy
      1 //===-LTOModule.h - LLVM Link Time Optimizer ------------------------------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // This file declares the LTOModule class.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #ifndef LLVM_LTO_LEGACY_LTOMODULE_H
     14 #define LLVM_LTO_LEGACY_LTOMODULE_H
     15 
     16 #include "llvm-c/lto.h"
     17 #include "llvm/ADT/StringMap.h"
     18 #include "llvm/ADT/StringSet.h"
     19 #include "llvm/IR/Module.h"
     20 #include "llvm/LTO/LTO.h"
     21 #include "llvm/Object/IRObjectFile.h"
     22 #include "llvm/Object/ModuleSymbolTable.h"
     23 #include "llvm/Target/TargetMachine.h"
     24 #include <string>
     25 #include <vector>
     26 
     27 // Forward references to llvm classes.
     28 namespace llvm {
     29   class Function;
     30   class GlobalValue;
     31   class MemoryBuffer;
     32   class TargetOptions;
     33   class Value;
     34 
     35 //===----------------------------------------------------------------------===//
     36 /// C++ class which implements the opaque lto_module_t type.
     37 ///
     38 struct LTOModule {
     39 private:
     40   struct NameAndAttributes {
     41     StringRef name;
     42     uint32_t           attributes = 0;
     43     bool               isFunction = 0;
     44     const GlobalValue *symbol = 0;
     45   };
     46 
     47   std::unique_ptr<LLVMContext> OwnedContext;
     48 
     49   std::string LinkerOpts;
     50 
     51   std::unique_ptr<Module> Mod;
     52   MemoryBufferRef MBRef;
     53   ModuleSymbolTable SymTab;
     54   std::unique_ptr<TargetMachine> _target;
     55   std::vector<NameAndAttributes> _symbols;
     56 
     57   // _defines and _undefines only needed to disambiguate tentative definitions
     58   StringSet<>                             _defines;
     59   StringMap<NameAndAttributes> _undefines;
     60   std::vector<StringRef> _asm_undefines;
     61 
     62   LTOModule(std::unique_ptr<Module> M, MemoryBufferRef MBRef,
     63             TargetMachine *TM);
     64 
     65 public:
     66   ~LTOModule();
     67 
     68   /// Returns 'true' if the file or memory contents is LLVM bitcode.
     69   static bool isBitcodeFile(const void *mem, size_t length);
     70   static bool isBitcodeFile(StringRef path);
     71 
     72   /// Returns 'true' if the Module is produced for ThinLTO.
     73   bool isThinLTO();
     74 
     75   /// Returns 'true' if the memory buffer is LLVM bitcode for the specified
     76   /// triple.
     77   static bool isBitcodeForTarget(MemoryBuffer *memBuffer,
     78                                  StringRef triplePrefix);
     79 
     80   /// Returns a string representing the producer identification stored in the
     81   /// bitcode, or "" if the bitcode does not contains any.
     82   ///
     83   static std::string getProducerString(MemoryBuffer *Buffer);
     84 
     85   /// Create a MemoryBuffer from a memory range with an optional name.
     86   static std::unique_ptr<MemoryBuffer>
     87   makeBuffer(const void *mem, size_t length, StringRef name = "");
     88 
     89   /// Create an LTOModule. N.B. These methods take ownership of the buffer. The
     90   /// caller must have initialized the Targets, the TargetMCs, the AsmPrinters,
     91   /// and the AsmParsers by calling:
     92   ///
     93   /// InitializeAllTargets();
     94   /// InitializeAllTargetMCs();
     95   /// InitializeAllAsmPrinters();
     96   /// InitializeAllAsmParsers();
     97   static ErrorOr<std::unique_ptr<LTOModule>>
     98   createFromFile(LLVMContext &Context, StringRef path,
     99                  const TargetOptions &options);
    100   static ErrorOr<std::unique_ptr<LTOModule>>
    101   createFromOpenFile(LLVMContext &Context, int fd, StringRef path, size_t size,
    102                      const TargetOptions &options);
    103   static ErrorOr<std::unique_ptr<LTOModule>>
    104   createFromOpenFileSlice(LLVMContext &Context, int fd, StringRef path,
    105                           size_t map_size, off_t offset,
    106                           const TargetOptions &options);
    107   static ErrorOr<std::unique_ptr<LTOModule>>
    108   createFromBuffer(LLVMContext &Context, const void *mem, size_t length,
    109                    const TargetOptions &options, StringRef path = "");
    110   static ErrorOr<std::unique_ptr<LTOModule>>
    111   createInLocalContext(std::unique_ptr<LLVMContext> Context, const void *mem,
    112                        size_t length, const TargetOptions &options,
    113                        StringRef path);
    114 
    115   const Module &getModule() const { return *Mod; }
    116   Module &getModule() { return *Mod; }
    117 
    118   std::unique_ptr<Module> takeModule() { return std::move(Mod); }
    119 
    120   /// Return the Module's target triple.
    121   const std::string &getTargetTriple() {
    122     return getModule().getTargetTriple();
    123   }
    124 
    125   /// Set the Module's target triple.
    126   void setTargetTriple(StringRef Triple) {
    127     getModule().setTargetTriple(Triple);
    128   }
    129 
    130   /// Get the number of symbols
    131   uint32_t getSymbolCount() {
    132     return _symbols.size();
    133   }
    134 
    135   /// Get the attributes for a symbol at the specified index.
    136   lto_symbol_attributes getSymbolAttributes(uint32_t index) {
    137     if (index < _symbols.size())
    138       return lto_symbol_attributes(_symbols[index].attributes);
    139     return lto_symbol_attributes(0);
    140   }
    141 
    142   /// Get the name of the symbol at the specified index.
    143   StringRef getSymbolName(uint32_t index) {
    144     if (index < _symbols.size())
    145       return _symbols[index].name;
    146     return StringRef();
    147   }
    148 
    149   const GlobalValue *getSymbolGV(uint32_t index) {
    150     if (index < _symbols.size())
    151       return _symbols[index].symbol;
    152     return nullptr;
    153   }
    154 
    155   StringRef getLinkerOpts() { return LinkerOpts; }
    156 
    157   const std::vector<StringRef> &getAsmUndefinedRefs() { return _asm_undefines; }
    158 
    159   static lto::InputFile *createInputFile(const void *buffer, size_t buffer_size,
    160                                          const char *path, std::string &out_error);
    161 
    162   static size_t getDependentLibraryCount(lto::InputFile *input);
    163 
    164   static const char *getDependentLibrary(lto::InputFile *input, size_t index, size_t *size);
    165 
    166   Expected<uint32_t> getMachOCPUType() const;
    167 
    168   Expected<uint32_t> getMachOCPUSubType() const;
    169 
    170 private:
    171   /// Parse metadata from the module
    172   // FIXME: it only parses "llvm.linker.options" metadata at the moment
    173   // FIXME: can't access metadata in lazily loaded modules
    174   void parseMetadata();
    175 
    176   /// Parse the symbols from the module and model-level ASM and add them to
    177   /// either the defined or undefined lists.
    178   void parseSymbols();
    179 
    180   /// Add a symbol which isn't defined just yet to a list to be resolved later.
    181   void addPotentialUndefinedSymbol(ModuleSymbolTable::Symbol Sym,
    182                                    bool isFunc);
    183 
    184   /// Add a defined symbol to the list.
    185   void addDefinedSymbol(StringRef Name, const GlobalValue *def,
    186                         bool isFunction);
    187 
    188   /// Add a data symbol as defined to the list.
    189   void addDefinedDataSymbol(ModuleSymbolTable::Symbol Sym);
    190   void addDefinedDataSymbol(StringRef Name, const GlobalValue *v);
    191 
    192   /// Add a function symbol as defined to the list.
    193   void addDefinedFunctionSymbol(ModuleSymbolTable::Symbol Sym);
    194   void addDefinedFunctionSymbol(StringRef Name, const Function *F);
    195 
    196   /// Add a global symbol from module-level ASM to the defined list.
    197   void addAsmGlobalSymbol(StringRef, lto_symbol_attributes scope);
    198 
    199   /// Add a global symbol from module-level ASM to the undefined list.
    200   void addAsmGlobalSymbolUndef(StringRef);
    201 
    202   /// Parse i386/ppc ObjC class data structure.
    203   void addObjCClass(const GlobalVariable *clgv);
    204 
    205   /// Parse i386/ppc ObjC category data structure.
    206   void addObjCCategory(const GlobalVariable *clgv);
    207 
    208   /// Parse i386/ppc ObjC class list data structure.
    209   void addObjCClassRef(const GlobalVariable *clgv);
    210 
    211   /// Get string that the data pointer points to.
    212   bool objcClassNameFromExpression(const Constant *c, std::string &name);
    213 
    214   /// Create an LTOModule (private version).
    215   static ErrorOr<std::unique_ptr<LTOModule>>
    216   makeLTOModule(MemoryBufferRef Buffer, const TargetOptions &options,
    217                 LLVMContext &Context, bool ShouldBeLazy);
    218 };
    219 }
    220 #endif
    221