1 //===-ThinLTOCodeGenerator.h - LLVM Link Time Optimizer -------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file declares the ThinLTOCodeGenerator class, similar to the 11 // LTOCodeGenerator but for the ThinLTO scheme. It provides an interface for 12 // linker plugin. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #ifndef LLVM_LTO_THINLTOCODEGENERATOR_H 17 #define LLVM_LTO_THINLTOCODEGENERATOR_H 18 19 #include "llvm-c/lto.h" 20 #include "llvm/ADT/StringSet.h" 21 #include "llvm/ADT/Triple.h" 22 #include "llvm/IR/ModuleSummaryIndex.h" 23 #include "llvm/Support/CodeGen.h" 24 #include "llvm/Support/MemoryBuffer.h" 25 #include "llvm/Target/TargetOptions.h" 26 27 #include <string> 28 29 namespace llvm { 30 class StringRef; 31 class LLVMContext; 32 class TargetMachine; 33 34 /// Helper to gather options relevant to the target machine creation 35 struct TargetMachineBuilder { 36 Triple TheTriple; 37 std::string MCpu; 38 std::string MAttr; 39 TargetOptions Options; 40 Optional<Reloc::Model> RelocModel; 41 CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; 42 43 std::unique_ptr<TargetMachine> create() const; 44 }; 45 46 /// This class define an interface similar to the LTOCodeGenerator, but adapted 47 /// for ThinLTO processing. 48 /// The ThinLTOCodeGenerator is not intended to be reuse for multiple 49 /// compilation: the model is that the client adds modules to the generator and 50 /// ask to perform the ThinLTO optimizations / codegen, and finally destroys the 51 /// codegenerator. 52 class ThinLTOCodeGenerator { 53 public: 54 /// Add given module to the code generator. 55 void addModule(StringRef Identifier, StringRef Data); 56 57 /** 58 * Adds to a list of all global symbols that must exist in the final generated 59 * code. If a symbol is not listed there, it will be optimized away if it is 60 * inlined into every usage. 61 */ 62 void preserveSymbol(StringRef Name); 63 64 /** 65 * Adds to a list of all global symbols that are cross-referenced between 66 * ThinLTO files. If the ThinLTO CodeGenerator can ensure that every 67 * references from a ThinLTO module to this symbol is optimized away, then 68 * the symbol can be discarded. 69 */ 70 void crossReferenceSymbol(StringRef Name); 71 72 /** 73 * Process all the modules that were added to the code generator in parallel. 74 * 75 * Client can access the resulting object files using getProducedBinaries() 76 */ 77 void run(); 78 79 /** 80 * Return the "in memory" binaries produced by the code generator. 81 */ getProducedBinaries()82 std::vector<std::unique_ptr<MemoryBuffer>> &getProducedBinaries() { 83 return ProducedBinaries; 84 } 85 86 /** 87 * \defgroup Options setters 88 * @{ 89 */ 90 91 /** 92 * \defgroup Cache controlling options 93 * 94 * These entry points control the ThinLTO cache. The cache is intended to 95 * support incremental build, and thus needs to be persistent accross build. 96 * The client enabled the cache by supplying a path to an existing directory. 97 * The code generator will use this to store objects files that may be reused 98 * during a subsequent build. 99 * To avoid filling the disk space, a few knobs are provided: 100 * - The pruning interval limit the frequency at which the garbage collector 101 * will try to scan the cache directory to prune it from expired entries. 102 * Setting to -1 disable the pruning (default). 103 * - The pruning expiration time indicates to the garbage collector how old 104 * an entry needs to be to be removed. 105 * - Finally, the garbage collector can be instructed to prune the cache till 106 * the occupied space goes below a threshold. 107 * @{ 108 */ 109 110 struct CachingOptions { 111 std::string Path; // Path to the cache, empty to disable. 112 int PruningInterval = 1200; // seconds, -1 to disable pruning. 113 unsigned int Expiration = 7 * 24 * 3600; // seconds (1w default). 114 unsigned MaxPercentageOfAvailableSpace = 75; // percentage. 115 }; 116 117 /// Provide a path to a directory where to store the cached files for 118 /// incremental build. setCacheDir(std::string Path)119 void setCacheDir(std::string Path) { CacheOptions.Path = std::move(Path); } 120 121 /// Cache policy: interval (seconds) between two prune of the cache. Set to a 122 /// negative value (default) to disable pruning. A value of 0 will be ignored. setCachePruningInterval(int Interval)123 void setCachePruningInterval(int Interval) { 124 if (Interval) 125 CacheOptions.PruningInterval = Interval; 126 } 127 128 /// Cache policy: expiration (in seconds) for an entry. 129 /// A value of 0 will be ignored. setCacheEntryExpiration(unsigned Expiration)130 void setCacheEntryExpiration(unsigned Expiration) { 131 if (Expiration) 132 CacheOptions.Expiration = Expiration; 133 } 134 135 /** 136 * Sets the maximum cache size that can be persistent across build, in terms 137 * of percentage of the available space on the the disk. Set to 100 to 138 * indicate no limit, 50 to indicate that the cache size will not be left over 139 * half the available space. A value over 100 will be reduced to 100, and a 140 * value of 0 will be ignored. 141 * 142 * 143 * The formula looks like: 144 * AvailableSpace = FreeSpace + ExistingCacheSize 145 * NewCacheSize = AvailableSpace * P/100 146 * 147 */ setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage)148 void setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage) { 149 if (Percentage) 150 CacheOptions.MaxPercentageOfAvailableSpace = Percentage; 151 } 152 153 /**@}*/ 154 155 /// Set the path to a directory where to save temporaries at various stages of 156 /// the processing. setSaveTempsDir(std::string Path)157 void setSaveTempsDir(std::string Path) { SaveTempsDir = std::move(Path); } 158 159 /// CPU to use to initialize the TargetMachine setCpu(std::string Cpu)160 void setCpu(std::string Cpu) { TMBuilder.MCpu = std::move(Cpu); } 161 162 /// Subtarget attributes setAttr(std::string MAttr)163 void setAttr(std::string MAttr) { TMBuilder.MAttr = std::move(MAttr); } 164 165 /// TargetMachine options setTargetOptions(TargetOptions Options)166 void setTargetOptions(TargetOptions Options) { 167 TMBuilder.Options = std::move(Options); 168 } 169 170 /// CodeModel setCodePICModel(Optional<Reloc::Model> Model)171 void setCodePICModel(Optional<Reloc::Model> Model) { 172 TMBuilder.RelocModel = Model; 173 } 174 175 /// CodeGen optimization level setCodeGenOptLevel(CodeGenOpt::Level CGOptLevel)176 void setCodeGenOptLevel(CodeGenOpt::Level CGOptLevel) { 177 TMBuilder.CGOptLevel = CGOptLevel; 178 } 179 180 /// Disable CodeGen, only run the stages till codegen and stop. The output 181 /// will be bitcode. disableCodeGen(bool Disable)182 void disableCodeGen(bool Disable) { DisableCodeGen = Disable; } 183 184 /// Perform CodeGen only: disable all other stages. setCodeGenOnly(bool CGOnly)185 void setCodeGenOnly(bool CGOnly) { CodeGenOnly = CGOnly; } 186 187 /**@}*/ 188 189 /** 190 * \defgroup Set of APIs to run individual stages in isolation. 191 * @{ 192 */ 193 194 /** 195 * Produce the combined summary index from all the bitcode files: 196 * "thin-link". 197 */ 198 std::unique_ptr<ModuleSummaryIndex> linkCombinedIndex(); 199 200 /** 201 * Perform promotion and renaming of exported internal functions, 202 * and additionally resolve weak and linkonce symbols. 203 * Index is updated to reflect linkage changes from weak resolution. 204 */ 205 void promote(Module &Module, ModuleSummaryIndex &Index); 206 207 /** 208 * Compute and emit the imported files for module at \p ModulePath. 209 */ 210 static void emitImports(StringRef ModulePath, StringRef OutputName, 211 ModuleSummaryIndex &Index); 212 213 /** 214 * Perform cross-module importing for the module identified by 215 * ModuleIdentifier. 216 */ 217 void crossModuleImport(Module &Module, ModuleSummaryIndex &Index); 218 219 /** 220 * Compute the list of summaries needed for importing into module. 221 */ 222 static void gatherImportedSummariesForModule( 223 StringRef ModulePath, ModuleSummaryIndex &Index, 224 std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex); 225 226 /** 227 * Perform internalization. Index is updated to reflect linkage changes. 228 */ 229 void internalize(Module &Module, ModuleSummaryIndex &Index); 230 231 /** 232 * Perform post-importing ThinLTO optimizations. 233 */ 234 void optimize(Module &Module); 235 236 /** 237 * Perform ThinLTO CodeGen. 238 */ 239 std::unique_ptr<MemoryBuffer> codegen(Module &Module); 240 241 /**@}*/ 242 243 private: 244 /// Helper factory to build a TargetMachine 245 TargetMachineBuilder TMBuilder; 246 247 /// Vector holding the in-memory buffer containing the produced binaries. 248 std::vector<std::unique_ptr<MemoryBuffer>> ProducedBinaries; 249 250 /// Vector holding the input buffers containing the bitcode modules to 251 /// process. 252 std::vector<MemoryBufferRef> Modules; 253 254 /// Set of symbols that need to be preserved outside of the set of bitcode 255 /// files. 256 StringSet<> PreservedSymbols; 257 258 /// Set of symbols that are cross-referenced between bitcode files. 259 StringSet<> CrossReferencedSymbols; 260 261 /// Control the caching behavior. 262 CachingOptions CacheOptions; 263 264 /// Path to a directory to save the temporary bitcode files. 265 std::string SaveTempsDir; 266 267 /// Flag to enable/disable CodeGen. When set to true, the process stops after 268 /// optimizations and a bitcode is produced. 269 bool DisableCodeGen = false; 270 271 /// Flag to indicate that only the CodeGen will be performed, no cross-module 272 /// importing or optimization. 273 bool CodeGenOnly = false; 274 }; 275 } 276 #endif 277