Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:11

0001 //===-ThinLTOCodeGenerator.h - LLVM Link Time Optimizer -------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file declares the ThinLTOCodeGenerator class, similar to the
0010 // LTOCodeGenerator but for the ThinLTO scheme. It provides an interface for
0011 // linker plugin.
0012 //
0013 //===----------------------------------------------------------------------===//
0014 
0015 #ifndef LLVM_LTO_LEGACY_THINLTOCODEGENERATOR_H
0016 #define LLVM_LTO_LEGACY_THINLTOCODEGENERATOR_H
0017 
0018 #include "llvm-c/lto.h"
0019 #include "llvm/ADT/StringSet.h"
0020 #include "llvm/IR/ModuleSummaryIndex.h"
0021 #include "llvm/LTO/LTO.h"
0022 #include "llvm/Support/CachePruning.h"
0023 #include "llvm/Support/CodeGen.h"
0024 #include "llvm/Support/MemoryBuffer.h"
0025 #include "llvm/Target/TargetOptions.h"
0026 #include "llvm/TargetParser/Triple.h"
0027 
0028 #include <string>
0029 
0030 namespace llvm {
0031 class StringRef;
0032 class TargetMachine;
0033 
0034 /// ThinLTOCodeGeneratorImpl - Namespace used for ThinLTOCodeGenerator
0035 /// implementation details. It should be considered private to the
0036 /// implementation.
0037 namespace ThinLTOCodeGeneratorImpl {
0038 struct TargetMachineBuilder;
0039 }
0040 
0041 /// Helper to gather options relevant to the target machine creation
0042 struct ThinLTOCodeGeneratorImpl::TargetMachineBuilder {
0043   Triple TheTriple;
0044   std::string MCpu;
0045   std::string MAttr;
0046   TargetOptions Options;
0047   std::optional<Reloc::Model> RelocModel;
0048   CodeGenOptLevel CGOptLevel = CodeGenOptLevel::Aggressive;
0049 
0050   std::unique_ptr<TargetMachine> create() const;
0051 };
0052 
0053 /// This class define an interface similar to the LTOCodeGenerator, but adapted
0054 /// for ThinLTO processing.
0055 /// The ThinLTOCodeGenerator is not intended to be reuse for multiple
0056 /// compilation: the model is that the client adds modules to the generator and
0057 /// ask to perform the ThinLTO optimizations / codegen, and finally destroys the
0058 /// codegenerator.
0059 class ThinLTOCodeGenerator {
0060 public:
0061   /// Add given module to the code generator.
0062   void addModule(StringRef Identifier, StringRef Data);
0063 
0064   /**
0065    * Adds to a list of all global symbols that must exist in the final generated
0066    * code. If a symbol is not listed there, it will be optimized away if it is
0067    * inlined into every usage.
0068    */
0069   void preserveSymbol(StringRef Name);
0070 
0071   /**
0072    * Adds to a list of all global symbols that are cross-referenced between
0073    * ThinLTO files. If the ThinLTO CodeGenerator can ensure that every
0074    * references from a ThinLTO module to this symbol is optimized away, then
0075    * the symbol can be discarded.
0076    */
0077   void crossReferenceSymbol(StringRef Name);
0078 
0079   /**
0080    * Process all the modules that were added to the code generator in parallel.
0081    *
0082    * Client can access the resulting object files using getProducedBinaries(),
0083    * unless setGeneratedObjectsDirectory() has been called, in which case
0084    * results are available through getProducedBinaryFiles().
0085    */
0086   void run();
0087 
0088   /**
0089    * Return the "in memory" binaries produced by the code generator. This is
0090    * filled after run() unless setGeneratedObjectsDirectory() has been
0091    * called, in which case results are available through
0092    * getProducedBinaryFiles().
0093    */
0094   std::vector<std::unique_ptr<MemoryBuffer>> &getProducedBinaries() {
0095     return ProducedBinaries;
0096   }
0097 
0098   /**
0099    * Return the "on-disk" binaries produced by the code generator. This is
0100    * filled after run() when setGeneratedObjectsDirectory() has been
0101    * called, in which case results are available through getProducedBinaries().
0102    */
0103   std::vector<std::string> &getProducedBinaryFiles() {
0104     return ProducedBinaryFiles;
0105   }
0106 
0107   /**
0108    * \defgroup Options setters
0109    * @{
0110    */
0111 
0112   /**
0113    * \defgroup Cache controlling options
0114    *
0115    * These entry points control the ThinLTO cache. The cache is intended to
0116    * support incremental build, and thus needs to be persistent accross build.
0117    * The client enabled the cache by supplying a path to an existing directory.
0118    * The code generator will use this to store objects files that may be reused
0119    * during a subsequent build.
0120    * To avoid filling the disk space, a few knobs are provided:
0121    *  - The pruning interval limit the frequency at which the garbage collector
0122    *    will try to scan the cache directory to prune it from expired entries.
0123    *    Setting to -1 disable the pruning (default). Setting to 0 will force
0124    *    pruning to occur.
0125    *  - The pruning expiration time indicates to the garbage collector how old
0126    *    an entry needs to be to be removed.
0127    *  - Finally, the garbage collector can be instructed to prune the cache till
0128    *    the occupied space goes below a threshold.
0129    * @{
0130    */
0131 
0132   struct CachingOptions {
0133     std::string Path;                    // Path to the cache, empty to disable.
0134     CachePruningPolicy Policy;
0135   };
0136 
0137   /// Provide a path to a directory where to store the cached files for
0138   /// incremental build.
0139   void setCacheDir(std::string Path) { CacheOptions.Path = std::move(Path); }
0140 
0141   /// Cache policy: interval (seconds) between two prunes of the cache. Set to a
0142   /// negative value to disable pruning. A value of 0 will force pruning to
0143   /// occur.
0144   void setCachePruningInterval(int Interval) {
0145     if(Interval < 0)
0146       CacheOptions.Policy.Interval.reset();
0147     else
0148       CacheOptions.Policy.Interval = std::chrono::seconds(Interval);
0149   }
0150 
0151   /// Cache policy: expiration (in seconds) for an entry.
0152   /// A value of 0 will be ignored.
0153   void setCacheEntryExpiration(unsigned Expiration) {
0154     if (Expiration)
0155       CacheOptions.Policy.Expiration = std::chrono::seconds(Expiration);
0156   }
0157 
0158   /**
0159    * Sets the maximum cache size that can be persistent across build, in terms
0160    * of percentage of the available space on the disk. Set to 100 to indicate
0161    * no limit, 50 to indicate that the cache size will not be left over
0162    * half the available space. A value over 100 will be reduced to 100, and a
0163    * value of 0 will be ignored.
0164    *
0165    *
0166    * The formula looks like:
0167    *  AvailableSpace = FreeSpace + ExistingCacheSize
0168    *  NewCacheSize = AvailableSpace * P/100
0169    *
0170    */
0171   void setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage) {
0172     if (Percentage)
0173       CacheOptions.Policy.MaxSizePercentageOfAvailableSpace = Percentage;
0174   }
0175 
0176   /// Cache policy: the maximum size for the cache directory in bytes. A value
0177   /// over the amount of available space on the disk will be reduced to the
0178   /// amount of available space. A value of 0 will be ignored.
0179   void setCacheMaxSizeBytes(uint64_t MaxSizeBytes) {
0180     if (MaxSizeBytes)
0181       CacheOptions.Policy.MaxSizeBytes = MaxSizeBytes;
0182   }
0183 
0184   /// Cache policy: the maximum number of files in the cache directory. A value
0185   /// of 0 will be ignored.
0186   void setCacheMaxSizeFiles(unsigned MaxSizeFiles) {
0187     if (MaxSizeFiles)
0188       CacheOptions.Policy.MaxSizeFiles = MaxSizeFiles;
0189   }
0190 
0191   /**@}*/
0192 
0193   /// Set the path to a directory where to save temporaries at various stages of
0194   /// the processing.
0195   void setSaveTempsDir(std::string Path) { SaveTempsDir = std::move(Path); }
0196 
0197   /// Set the path to a directory where to save generated object files. This
0198   /// path can be used by a linker to request on-disk files instead of in-memory
0199   /// buffers. When set, results are available through getProducedBinaryFiles()
0200   /// instead of getProducedBinaries().
0201   void setGeneratedObjectsDirectory(std::string Path) {
0202     SavedObjectsDirectoryPath = std::move(Path);
0203   }
0204 
0205   /// CPU to use to initialize the TargetMachine
0206   void setCpu(std::string Cpu) { TMBuilder.MCpu = std::move(Cpu); }
0207 
0208   /// Subtarget attributes
0209   void setAttr(std::string MAttr) { TMBuilder.MAttr = std::move(MAttr); }
0210 
0211   /// TargetMachine options
0212   void setTargetOptions(TargetOptions Options) {
0213     TMBuilder.Options = std::move(Options);
0214   }
0215 
0216   /// Enable the Freestanding mode: indicate that the optimizer should not
0217   /// assume builtins are present on the target.
0218   void setFreestanding(bool Enabled) { Freestanding = Enabled; }
0219 
0220   /// CodeModel
0221   void setCodePICModel(std::optional<Reloc::Model> Model) {
0222     TMBuilder.RelocModel = Model;
0223   }
0224 
0225   /// CodeGen optimization level
0226   void setCodeGenOptLevel(CodeGenOptLevel CGOptLevel) {
0227     TMBuilder.CGOptLevel = CGOptLevel;
0228   }
0229 
0230   /// IR optimization level: from 0 to 3.
0231   void setOptLevel(unsigned NewOptLevel) {
0232     OptLevel = (NewOptLevel > 3) ? 3 : NewOptLevel;
0233   }
0234 
0235   /// Enable or disable debug output for the new pass manager.
0236   void setDebugPassManager(unsigned Enabled) { DebugPassManager = Enabled; }
0237 
0238   /// Disable CodeGen, only run the stages till codegen and stop. The output
0239   /// will be bitcode.
0240   void disableCodeGen(bool Disable) { DisableCodeGen = Disable; }
0241 
0242   /// Perform CodeGen only: disable all other stages.
0243   void setCodeGenOnly(bool CGOnly) { CodeGenOnly = CGOnly; }
0244 
0245   /**@}*/
0246 
0247   /**
0248    * \defgroup Set of APIs to run individual stages in isolation.
0249    * @{
0250    */
0251 
0252   /**
0253    * Produce the combined summary index from all the bitcode files:
0254    * "thin-link".
0255    */
0256   std::unique_ptr<ModuleSummaryIndex> linkCombinedIndex();
0257 
0258   /**
0259    * Perform promotion and renaming of exported internal functions,
0260    * and additionally resolve weak and linkonce symbols.
0261    * Index is updated to reflect linkage changes from weak resolution.
0262    */
0263   void promote(Module &Module, ModuleSummaryIndex &Index,
0264                const lto::InputFile &File);
0265 
0266   /**
0267    * Compute and emit the imported files for module at \p ModulePath.
0268    */
0269   void emitImports(Module &Module, StringRef OutputName,
0270                    ModuleSummaryIndex &Index,
0271                    const lto::InputFile &File);
0272 
0273   /**
0274    * Perform cross-module importing for the module identified by
0275    * ModuleIdentifier.
0276    */
0277   void crossModuleImport(Module &Module, ModuleSummaryIndex &Index,
0278                          const lto::InputFile &File);
0279 
0280   /**
0281    * Compute the list of summaries and the subset of declaration summaries
0282    * needed for importing into module.
0283    */
0284   void gatherImportedSummariesForModule(
0285       Module &Module, ModuleSummaryIndex &Index,
0286       ModuleToSummariesForIndexTy &ModuleToSummariesForIndex,
0287       GVSummaryPtrSet &DecSummaries, const lto::InputFile &File);
0288 
0289   /**
0290    * Perform internalization. Index is updated to reflect linkage changes.
0291    */
0292   void internalize(Module &Module, ModuleSummaryIndex &Index,
0293                    const lto::InputFile &File);
0294 
0295   /**
0296    * Perform post-importing ThinLTO optimizations.
0297    */
0298   void optimize(Module &Module);
0299 
0300   /**
0301    * Write temporary object file to SavedObjectDirectoryPath, write symlink
0302    * to Cache directory if needed. Returns the path to the generated file in
0303    * SavedObjectsDirectoryPath.
0304    */
0305   std::string writeGeneratedObject(int count, StringRef CacheEntryPath,
0306                                    const MemoryBuffer &OutputBuffer);
0307   /**@}*/
0308 
0309 private:
0310   /// Helper factory to build a TargetMachine
0311   ThinLTOCodeGeneratorImpl::TargetMachineBuilder TMBuilder;
0312 
0313   /// Vector holding the in-memory buffer containing the produced binaries, when
0314   /// SavedObjectsDirectoryPath isn't set.
0315   std::vector<std::unique_ptr<MemoryBuffer>> ProducedBinaries;
0316 
0317   /// Path to generated files in the supplied SavedObjectsDirectoryPath if any.
0318   std::vector<std::string> ProducedBinaryFiles;
0319 
0320   /// Vector holding the input buffers containing the bitcode modules to
0321   /// process.
0322   std::vector<std::unique_ptr<lto::InputFile>> Modules;
0323 
0324   /// Set of symbols that need to be preserved outside of the set of bitcode
0325   /// files.
0326   StringSet<> PreservedSymbols;
0327 
0328   /// Set of symbols that are cross-referenced between bitcode files.
0329   StringSet<> CrossReferencedSymbols;
0330 
0331   /// Control the caching behavior.
0332   CachingOptions CacheOptions;
0333 
0334   /// Path to a directory to save the temporary bitcode files.
0335   std::string SaveTempsDir;
0336 
0337   /// Path to a directory to save the generated object files.
0338   std::string SavedObjectsDirectoryPath;
0339 
0340   /// Flag to enable/disable CodeGen. When set to true, the process stops after
0341   /// optimizations and a bitcode is produced.
0342   bool DisableCodeGen = false;
0343 
0344   /// Flag to indicate that only the CodeGen will be performed, no cross-module
0345   /// importing or optimization.
0346   bool CodeGenOnly = false;
0347 
0348   /// Flag to indicate that the optimizer should not assume builtins are present
0349   /// on the target.
0350   bool Freestanding = false;
0351 
0352   /// IR Optimization Level [0-3].
0353   unsigned OptLevel = 3;
0354 
0355   /// Flag to indicate whether debug output should be enabled for the new pass
0356   /// manager.
0357   bool DebugPassManager = false;
0358 };
0359 }
0360 #endif