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