Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===-LTOCodeGenerator.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 LTOCodeGenerator class.
0010 //
0011 //   LTO compilation consists of three phases: Pre-IPO, IPO and Post-IPO.
0012 //
0013 //   The Pre-IPO phase compiles source code into bitcode file. The resulting
0014 // bitcode files, along with object files and libraries, will be fed to the
0015 // linker to through the IPO and Post-IPO phases. By using obj-file extension,
0016 // the resulting bitcode file disguises itself as an object file, and therefore
0017 // obviates the need of writing a special set of the make-rules only for LTO
0018 // compilation.
0019 //
0020 //   The IPO phase perform inter-procedural analyses and optimizations, and
0021 // the Post-IPO consists two sub-phases: intra-procedural scalar optimizations
0022 // (SOPT), and intra-procedural target-dependent code generator (CG).
0023 //
0024 //   As of this writing, we don't separate IPO and the Post-IPO SOPT. They
0025 // are intermingled together, and are driven by a single pass manager (see
0026 // PassManagerBuilder::populateLTOPassManager()).
0027 //   FIXME: populateLTOPassManager no longer exists.
0028 //
0029 //   The "LTOCodeGenerator" is the driver for the IPO and Post-IPO stages.
0030 // The "CodeGenerator" here is bit confusing. Don't confuse the "CodeGenerator"
0031 // with the machine specific code generator.
0032 //
0033 //===----------------------------------------------------------------------===//
0034 
0035 #ifndef LLVM_LTO_LEGACY_LTOCODEGENERATOR_H
0036 #define LLVM_LTO_LEGACY_LTOCODEGENERATOR_H
0037 
0038 #include "llvm-c/lto.h"
0039 #include "llvm/ADT/ArrayRef.h"
0040 #include "llvm/ADT/StringMap.h"
0041 #include "llvm/ADT/StringSet.h"
0042 #include "llvm/IR/GlobalValue.h"
0043 #include "llvm/IR/Module.h"
0044 #include "llvm/LTO/Config.h"
0045 #include "llvm/LTO/LTO.h"
0046 #include "llvm/Support/CommandLine.h"
0047 #include "llvm/Support/Error.h"
0048 #include "llvm/Support/ToolOutputFile.h"
0049 #include "llvm/Target/TargetMachine.h"
0050 #include "llvm/Target/TargetOptions.h"
0051 #include <string>
0052 #include <vector>
0053 
0054 namespace llvm {
0055 template <typename T> class ArrayRef;
0056   class LLVMContext;
0057   class DiagnosticInfo;
0058   class Linker;
0059   class Mangler;
0060   class MemoryBuffer;
0061   class TargetLibraryInfo;
0062   class TargetMachine;
0063   class raw_ostream;
0064   class raw_pwrite_stream;
0065 
0066 /// Enable global value internalization in LTO.
0067 extern cl::opt<bool> EnableLTOInternalization;
0068 
0069 //===----------------------------------------------------------------------===//
0070 /// C++ class which implements the opaque lto_code_gen_t type.
0071 ///
0072 struct LTOCodeGenerator {
0073   static const char *getVersionString();
0074 
0075   LTOCodeGenerator(LLVMContext &Context);
0076   ~LTOCodeGenerator();
0077 
0078   /// Merge given module.  Return true on success.
0079   ///
0080   /// Resets \a HasVerifiedInput.
0081   bool addModule(struct LTOModule *);
0082 
0083   /// Set the destination module.
0084   ///
0085   /// Resets \a HasVerifiedInput.
0086   void setModule(std::unique_ptr<LTOModule> M);
0087 
0088   void setAsmUndefinedRefs(struct LTOModule *);
0089   void setTargetOptions(const TargetOptions &Options);
0090   void setDebugInfo(lto_debug_model);
0091   void setCodePICModel(std::optional<Reloc::Model> Model) {
0092     Config.RelocModel = Model;
0093   }
0094 
0095   /// Set the file type to be emitted (assembly or object code).
0096   /// The default is CodeGenFileType::ObjectFile.
0097   void setFileType(CodeGenFileType FT) { Config.CGFileType = FT; }
0098 
0099   void setCpu(StringRef MCpu) { Config.CPU = std::string(MCpu); }
0100   void setAttrs(std::vector<std::string> MAttrs) {
0101     Config.MAttrs = std::move(MAttrs);
0102   }
0103   void setOptLevel(unsigned OptLevel);
0104 
0105   void setShouldInternalize(bool Value) { ShouldInternalize = Value; }
0106   void setShouldEmbedUselists(bool Value) { ShouldEmbedUselists = Value; }
0107   void setSaveIRBeforeOptPath(std::string Value) {
0108     SaveIRBeforeOptPath = std::move(Value);
0109   }
0110 
0111   /// Restore linkage of globals
0112   ///
0113   /// When set, the linkage of globals will be restored prior to code
0114   /// generation. That is, a global symbol that had external linkage prior to
0115   /// LTO will be emitted with external linkage again; and a local will remain
0116   /// local. Note that this option only affects the end result - globals may
0117   /// still be internalized in the process of LTO and may be modified and/or
0118   /// deleted where legal.
0119   ///
0120   /// The default behavior will internalize globals (unless on the preserve
0121   /// list) and, if parallel code generation is enabled, will externalize
0122   /// all locals.
0123   void setShouldRestoreGlobalsLinkage(bool Value) {
0124     ShouldRestoreGlobalsLinkage = Value;
0125   }
0126 
0127   void addMustPreserveSymbol(StringRef Sym) { MustPreserveSymbols.insert(Sym); }
0128 
0129   /// Pass options to the driver and optimization passes.
0130   ///
0131   /// These options are not necessarily for debugging purpose (the function
0132   /// name is misleading).  This function should be called before
0133   /// LTOCodeGenerator::compilexxx(), and
0134   /// LTOCodeGenerator::writeMergedModules().
0135   void setCodeGenDebugOptions(ArrayRef<StringRef> Opts);
0136 
0137   /// Parse the options set in setCodeGenDebugOptions.
0138   ///
0139   /// Like \a setCodeGenDebugOptions(), this must be called before
0140   /// LTOCodeGenerator::compilexxx() and
0141   /// LTOCodeGenerator::writeMergedModules().
0142   void parseCodeGenDebugOptions();
0143 
0144   /// Write the merged module to the file specified by the given path.  Return
0145   /// true on success.
0146   ///
0147   /// Calls \a verifyMergedModuleOnce().
0148   bool writeMergedModules(StringRef Path);
0149 
0150   /// Compile the merged module into a *single* output file; the path to output
0151   /// file is returned to the caller via argument "name". Return true on
0152   /// success.
0153   ///
0154   /// \note It is up to the linker to remove the intermediate output file.  Do
0155   /// not try to remove the object file in LTOCodeGenerator's destructor as we
0156   /// don't who (LTOCodeGenerator or the output file) will last longer.
0157   bool compile_to_file(const char **Name);
0158 
0159   /// As with compile_to_file(), this function compiles the merged module into
0160   /// single output file. Instead of returning the output file path to the
0161   /// caller (linker), it brings the output to a buffer, and returns the buffer
0162   /// to the caller. This function should delete the intermediate file once
0163   /// its content is brought to memory. Return NULL if the compilation was not
0164   /// successful.
0165   std::unique_ptr<MemoryBuffer> compile();
0166 
0167   /// Optimizes the merged module.  Returns true on success.
0168   ///
0169   /// Calls \a verifyMergedModuleOnce().
0170   bool optimize();
0171 
0172   /// Compiles the merged optimized module into a single output file. It brings
0173   /// the output to a buffer, and returns the buffer to the caller. Return NULL
0174   /// if the compilation was not successful.
0175   std::unique_ptr<MemoryBuffer> compileOptimized();
0176 
0177   /// Compile the merged optimized module \p ParallelismLevel output files each
0178   /// representing a linkable partition of the module. If out contains more
0179   /// than one element, code generation is done in parallel with \p
0180   /// ParallelismLevel threads.  Output files will be written to the streams
0181   /// created using the \p AddStream callback. Returns true on success.
0182   ///
0183   /// Calls \a verifyMergedModuleOnce().
0184   bool compileOptimized(AddStreamFn AddStream, unsigned ParallelismLevel);
0185 
0186   /// Enable the Freestanding mode: indicate that the optimizer should not
0187   /// assume builtins are present on the target.
0188   void setFreestanding(bool Enabled) { Config.Freestanding = Enabled; }
0189 
0190   void setDisableVerify(bool Value) { Config.DisableVerify = Value; }
0191 
0192   void setDebugPassManager(bool Enabled) { Config.DebugPassManager = Enabled; }
0193 
0194   void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
0195 
0196   LLVMContext &getContext() { return Context; }
0197 
0198   void resetMergedModule() { MergedModule.reset(); }
0199   void DiagnosticHandler(const DiagnosticInfo &DI);
0200 
0201 private:
0202   /// Verify the merged module on first call.
0203   ///
0204   /// Sets \a HasVerifiedInput on first call and doesn't run again on the same
0205   /// input.
0206   void verifyMergedModuleOnce();
0207 
0208   bool compileOptimizedToFile(const char **Name);
0209   void restoreLinkageForExternals();
0210   void applyScopeRestrictions();
0211   void preserveDiscardableGVs(
0212       Module &TheModule,
0213       llvm::function_ref<bool(const GlobalValue &)> mustPreserveGV);
0214 
0215   bool determineTarget();
0216   std::unique_ptr<TargetMachine> createTargetMachine();
0217 
0218   bool useAIXSystemAssembler();
0219   bool runAIXSystemAssembler(SmallString<128> &AssemblyFile);
0220 
0221   void emitError(const std::string &ErrMsg);
0222   void emitWarning(const std::string &ErrMsg);
0223 
0224   void finishOptimizationRemarks();
0225 
0226   LLVMContext &Context;
0227   std::unique_ptr<Module> MergedModule;
0228   std::unique_ptr<Linker> TheLinker;
0229   std::unique_ptr<TargetMachine> TargetMach;
0230   bool EmitDwarfDebugInfo = false;
0231   bool ScopeRestrictionsDone = false;
0232   bool HasVerifiedInput = false;
0233   StringSet<> MustPreserveSymbols;
0234   StringSet<> AsmUndefinedRefs;
0235   StringMap<GlobalValue::LinkageTypes> ExternalSymbols;
0236   std::vector<std::string> CodegenOptions;
0237   std::string FeatureStr;
0238   std::string NativeObjectPath;
0239   const Target *MArch = nullptr;
0240   std::string TripleStr;
0241   lto_diagnostic_handler_t DiagHandler = nullptr;
0242   void *DiagContext = nullptr;
0243   bool ShouldInternalize = EnableLTOInternalization;
0244   bool ShouldEmbedUselists = false;
0245   bool ShouldRestoreGlobalsLinkage = false;
0246   std::unique_ptr<ToolOutputFile> DiagnosticOutputFile;
0247   std::unique_ptr<ToolOutputFile> StatsFile = nullptr;
0248   std::string SaveIRBeforeOptPath;
0249 
0250   lto::Config Config;
0251 };
0252 
0253 /// A convenience function that calls cl::ParseCommandLineOptions on the given
0254 /// set of options.
0255 void parseCommandLineOptions(std::vector<std::string> &Options);
0256 }
0257 #endif