LTOCodeGenerator.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-LTOCodeGenerator.h - LLVM Link Time Optimizer -----------------------===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file declares the LTOCodeGenerator class.
  15. //
  16. // LTO compilation consists of three phases: Pre-IPO, IPO and Post-IPO.
  17. //
  18. // The Pre-IPO phase compiles source code into bitcode file. The resulting
  19. // bitcode files, along with object files and libraries, will be fed to the
  20. // linker to through the IPO and Post-IPO phases. By using obj-file extension,
  21. // the resulting bitcode file disguises itself as an object file, and therefore
  22. // obviates the need of writing a special set of the make-rules only for LTO
  23. // compilation.
  24. //
  25. // The IPO phase perform inter-procedural analyses and optimizations, and
  26. // the Post-IPO consists two sub-phases: intra-procedural scalar optimizations
  27. // (SOPT), and intra-procedural target-dependent code generator (CG).
  28. //
  29. // As of this writing, we don't separate IPO and the Post-IPO SOPT. They
  30. // are intermingled together, and are driven by a single pass manager (see
  31. // PassManagerBuilder::populateLTOPassManager()).
  32. // FIXME: populateLTOPassManager no longer exists.
  33. //
  34. // The "LTOCodeGenerator" is the driver for the IPO and Post-IPO stages.
  35. // The "CodeGenerator" here is bit confusing. Don't confuse the "CodeGenerator"
  36. // with the machine specific code generator.
  37. //
  38. //===----------------------------------------------------------------------===//
  39. #ifndef LLVM_LTO_LEGACY_LTOCODEGENERATOR_H
  40. #define LLVM_LTO_LEGACY_LTOCODEGENERATOR_H
  41. #include "llvm-c/lto.h"
  42. #include "llvm/ADT/ArrayRef.h"
  43. #include "llvm/ADT/SmallPtrSet.h"
  44. #include "llvm/ADT/StringMap.h"
  45. #include "llvm/ADT/StringSet.h"
  46. #include "llvm/IR/GlobalValue.h"
  47. #include "llvm/IR/Module.h"
  48. #include "llvm/LTO/Config.h"
  49. #include "llvm/LTO/LTO.h"
  50. #include "llvm/Support/CommandLine.h"
  51. #include "llvm/Support/Error.h"
  52. #include "llvm/Support/ToolOutputFile.h"
  53. #include "llvm/Target/TargetMachine.h"
  54. #include "llvm/Target/TargetOptions.h"
  55. #include <string>
  56. #include <vector>
  57. namespace llvm {
  58. template <typename T> class ArrayRef;
  59. class LLVMContext;
  60. class DiagnosticInfo;
  61. class Linker;
  62. class Mangler;
  63. class MemoryBuffer;
  64. class TargetLibraryInfo;
  65. class TargetMachine;
  66. class raw_ostream;
  67. class raw_pwrite_stream;
  68. /// Enable global value internalization in LTO.
  69. extern cl::opt<bool> EnableLTOInternalization;
  70. //===----------------------------------------------------------------------===//
  71. /// C++ class which implements the opaque lto_code_gen_t type.
  72. ///
  73. struct LTOCodeGenerator {
  74. static const char *getVersionString();
  75. LTOCodeGenerator(LLVMContext &Context);
  76. ~LTOCodeGenerator();
  77. /// Merge given module. Return true on success.
  78. ///
  79. /// Resets \a HasVerifiedInput.
  80. bool addModule(struct LTOModule *);
  81. /// Set the destination module.
  82. ///
  83. /// Resets \a HasVerifiedInput.
  84. void setModule(std::unique_ptr<LTOModule> M);
  85. void setAsmUndefinedRefs(struct LTOModule *);
  86. void setTargetOptions(const TargetOptions &Options);
  87. void setDebugInfo(lto_debug_model);
  88. void setCodePICModel(std::optional<Reloc::Model> Model) {
  89. Config.RelocModel = Model;
  90. }
  91. /// Set the file type to be emitted (assembly or object code).
  92. /// The default is CGFT_ObjectFile.
  93. void setFileType(CodeGenFileType FT) { Config.CGFileType = FT; }
  94. void setCpu(StringRef MCpu) { Config.CPU = std::string(MCpu); }
  95. void setAttrs(std::vector<std::string> MAttrs) { Config.MAttrs = MAttrs; }
  96. void setOptLevel(unsigned OptLevel);
  97. void setShouldInternalize(bool Value) { ShouldInternalize = Value; }
  98. void setShouldEmbedUselists(bool Value) { ShouldEmbedUselists = Value; }
  99. void setSaveIRBeforeOptPath(std::string Value) {
  100. SaveIRBeforeOptPath = Value;
  101. }
  102. /// Restore linkage of globals
  103. ///
  104. /// When set, the linkage of globals will be restored prior to code
  105. /// generation. That is, a global symbol that had external linkage prior to
  106. /// LTO will be emitted with external linkage again; and a local will remain
  107. /// local. Note that this option only affects the end result - globals may
  108. /// still be internalized in the process of LTO and may be modified and/or
  109. /// deleted where legal.
  110. ///
  111. /// The default behavior will internalize globals (unless on the preserve
  112. /// list) and, if parallel code generation is enabled, will externalize
  113. /// all locals.
  114. void setShouldRestoreGlobalsLinkage(bool Value) {
  115. ShouldRestoreGlobalsLinkage = Value;
  116. }
  117. void addMustPreserveSymbol(StringRef Sym) { MustPreserveSymbols.insert(Sym); }
  118. /// Pass options to the driver and optimization passes.
  119. ///
  120. /// These options are not necessarily for debugging purpose (the function
  121. /// name is misleading). This function should be called before
  122. /// LTOCodeGenerator::compilexxx(), and
  123. /// LTOCodeGenerator::writeMergedModules().
  124. void setCodeGenDebugOptions(ArrayRef<StringRef> Opts);
  125. /// Parse the options set in setCodeGenDebugOptions.
  126. ///
  127. /// Like \a setCodeGenDebugOptions(), this must be called before
  128. /// LTOCodeGenerator::compilexxx() and
  129. /// LTOCodeGenerator::writeMergedModules().
  130. void parseCodeGenDebugOptions();
  131. /// Write the merged module to the file specified by the given path. Return
  132. /// true on success.
  133. ///
  134. /// Calls \a verifyMergedModuleOnce().
  135. bool writeMergedModules(StringRef Path);
  136. /// Compile the merged module into a *single* output file; the path to output
  137. /// file is returned to the caller via argument "name". Return true on
  138. /// success.
  139. ///
  140. /// \note It is up to the linker to remove the intermediate output file. Do
  141. /// not try to remove the object file in LTOCodeGenerator's destructor as we
  142. /// don't who (LTOCodeGenerator or the output file) will last longer.
  143. bool compile_to_file(const char **Name);
  144. /// As with compile_to_file(), this function compiles the merged module into
  145. /// single output file. Instead of returning the output file path to the
  146. /// caller (linker), it brings the output to a buffer, and returns the buffer
  147. /// to the caller. This function should delete the intermediate file once
  148. /// its content is brought to memory. Return NULL if the compilation was not
  149. /// successful.
  150. std::unique_ptr<MemoryBuffer> compile();
  151. /// Optimizes the merged module. Returns true on success.
  152. ///
  153. /// Calls \a verifyMergedModuleOnce().
  154. bool optimize();
  155. /// Compiles the merged optimized module into a single output file. It brings
  156. /// the output to a buffer, and returns the buffer to the caller. Return NULL
  157. /// if the compilation was not successful.
  158. std::unique_ptr<MemoryBuffer> compileOptimized();
  159. /// Compile the merged optimized module \p ParallelismLevel output files each
  160. /// representing a linkable partition of the module. If out contains more
  161. /// than one element, code generation is done in parallel with \p
  162. /// ParallelismLevel threads. Output files will be written to the streams
  163. /// created using the \p AddStream callback. Returns true on success.
  164. ///
  165. /// Calls \a verifyMergedModuleOnce().
  166. bool compileOptimized(AddStreamFn AddStream, unsigned ParallelismLevel);
  167. /// Enable the Freestanding mode: indicate that the optimizer should not
  168. /// assume builtins are present on the target.
  169. void setFreestanding(bool Enabled) { Config.Freestanding = Enabled; }
  170. void setDisableVerify(bool Value) { Config.DisableVerify = Value; }
  171. void setDebugPassManager(bool Enabled) { Config.DebugPassManager = Enabled; }
  172. void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
  173. LLVMContext &getContext() { return Context; }
  174. void resetMergedModule() { MergedModule.reset(); }
  175. void DiagnosticHandler(const DiagnosticInfo &DI);
  176. private:
  177. /// Verify the merged module on first call.
  178. ///
  179. /// Sets \a HasVerifiedInput on first call and doesn't run again on the same
  180. /// input.
  181. void verifyMergedModuleOnce();
  182. bool compileOptimizedToFile(const char **Name);
  183. void restoreLinkageForExternals();
  184. void applyScopeRestrictions();
  185. void preserveDiscardableGVs(
  186. Module &TheModule,
  187. llvm::function_ref<bool(const GlobalValue &)> mustPreserveGV);
  188. bool determineTarget();
  189. std::unique_ptr<TargetMachine> createTargetMachine();
  190. bool useAIXSystemAssembler();
  191. bool runAIXSystemAssembler(SmallString<128> &AssemblyFile);
  192. void emitError(const std::string &ErrMsg);
  193. void emitWarning(const std::string &ErrMsg);
  194. void finishOptimizationRemarks();
  195. LLVMContext &Context;
  196. std::unique_ptr<Module> MergedModule;
  197. std::unique_ptr<Linker> TheLinker;
  198. std::unique_ptr<TargetMachine> TargetMach;
  199. bool EmitDwarfDebugInfo = false;
  200. bool ScopeRestrictionsDone = false;
  201. bool HasVerifiedInput = false;
  202. StringSet<> MustPreserveSymbols;
  203. StringSet<> AsmUndefinedRefs;
  204. StringMap<GlobalValue::LinkageTypes> ExternalSymbols;
  205. std::vector<std::string> CodegenOptions;
  206. std::string FeatureStr;
  207. std::string NativeObjectPath;
  208. const Target *MArch = nullptr;
  209. std::string TripleStr;
  210. lto_diagnostic_handler_t DiagHandler = nullptr;
  211. void *DiagContext = nullptr;
  212. bool ShouldInternalize = EnableLTOInternalization;
  213. bool ShouldEmbedUselists = false;
  214. bool ShouldRestoreGlobalsLinkage = false;
  215. std::unique_ptr<ToolOutputFile> DiagnosticOutputFile;
  216. std::unique_ptr<ToolOutputFile> StatsFile = nullptr;
  217. std::string SaveIRBeforeOptPath;
  218. lto::Config Config;
  219. };
  220. /// A convenience function that calls cl::ParseCommandLineOptions on the given
  221. /// set of options.
  222. void parseCommandLineOptions(std::vector<std::string> &Options);
  223. }
  224. #endif
  225. #ifdef __GNUC__
  226. #pragma GCC diagnostic pop
  227. #endif