1 //===-Config.h - LLVM Link Time Optimizer Configuration ---------*- C++ -*-===// 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 defines the lto::Config data structure, which allows clients to 10 // configure LTO. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LTO_CONFIG_H 15 #define LLVM_LTO_CONFIG_H 16 17 #include "llvm/ADT/DenseSet.h" 18 #include "llvm/Config/llvm-config.h" 19 #include "llvm/IR/DiagnosticInfo.h" 20 #include "llvm/IR/GlobalValue.h" 21 #include "llvm/IR/LLVMContext.h" 22 #include "llvm/IR/LegacyPassManager.h" 23 #include "llvm/Passes/PassBuilder.h" 24 #include "llvm/Support/CodeGen.h" 25 #include "llvm/Support/Compiler.h" 26 #include "llvm/Target/TargetOptions.h" 27 28 #include <functional> 29 #include <optional> 30 31 namespace llvm { 32 33 class Error; 34 class Module; 35 class ModuleSummaryIndex; 36 class raw_pwrite_stream; 37 38 namespace lto { 39 40 /// LTO configuration. A linker can configure LTO by setting fields in this data 41 /// structure and passing it to the lto::LTO constructor. 42 struct Config { 43 enum VisScheme { 44 FromPrevailing, 45 ELF, 46 }; 47 // Note: when adding fields here, consider whether they need to be added to 48 // computeLTOCacheKey in LTO.cpp. 49 std::string CPU; 50 TargetOptions Options; 51 std::vector<std::string> MAttrs; 52 std::vector<std::string> MllvmArgs; 53 std::vector<std::string> PassPlugins; 54 /// For adding passes that run right before codegen. 55 std::function<void(legacy::PassManager &)> PreCodeGenPassesHook; 56 std::optional<Reloc::Model> RelocModel = Reloc::PIC_; 57 std::optional<CodeModel::Model> CodeModel; 58 CodeGenOptLevel CGOptLevel = CodeGenOptLevel::Default; 59 CodeGenFileType CGFileType = CodeGenFileType::ObjectFile; 60 unsigned OptLevel = 2; 61 bool VerifyEach = false; 62 bool DisableVerify = false; 63 64 /// Flag to indicate that the optimizer should not assume builtins are present 65 /// on the target. 66 bool Freestanding = false; 67 68 /// Disable entirely the optimizer, including importing for ThinLTO 69 bool CodeGenOnly = false; 70 71 /// Run PGO context sensitive IR instrumentation. 72 bool RunCSIRInstr = false; 73 74 /// Turn on/off the warning about a hash mismatch in the PGO profile data. 75 bool PGOWarnMismatch = true; 76 77 /// Asserts whether we can assume whole program visibility during the LTO 78 /// link. 79 bool HasWholeProgramVisibility = false; 80 81 /// We're validating that all native vtables have corresponding type infos. 82 bool ValidateAllVtablesHaveTypeInfos = false; 83 /// If all native vtables have corresponding type infos, allow 84 /// usage of RTTI to block devirtualization on types used in native files. 85 bool AllVtablesHaveTypeInfos = false; 86 87 /// Always emit a Regular LTO object even when it is empty because no Regular 88 /// LTO modules were linked. This option is useful for some build system which 89 /// want to know a priori all possible output files. 90 bool AlwaysEmitRegularLTOObj = false; 91 92 /// If true, the LTO instance creates copies of the symbol names for LTO::run. 93 /// The lld linker uses string saver to keep symbol names alive and doesn't 94 /// need to create copies, so it can set this field to false. 95 bool KeepSymbolNameCopies = true; 96 97 /// Allows non-imported definitions to get the potentially more constraining 98 /// visibility from the prevailing definition. FromPrevailing is the default 99 /// because it works for many binary formats. ELF can use the more optimized 100 /// 'ELF' scheme. 101 VisScheme VisibilityScheme = FromPrevailing; 102 103 /// If this field is set, the set of passes run in the middle-end optimizer 104 /// will be the one specified by the string. Only works with the new pass 105 /// manager as the old one doesn't have this ability. 106 std::string OptPipeline; 107 108 // If this field is set, it has the same effect of specifying an AA pipeline 109 // identified by the string. Only works with the new pass manager, in 110 // conjunction OptPipeline. 111 std::string AAPipeline; 112 113 /// Setting this field will replace target triples in input files with this 114 /// triple. 115 std::string OverrideTriple; 116 117 /// Setting this field will replace unspecified target triples in input files 118 /// with this triple. 119 std::string DefaultTriple; 120 121 /// Context Sensitive PGO profile path. 122 std::string CSIRProfile; 123 124 /// Sample PGO profile path. 125 std::string SampleProfile; 126 127 /// Name remapping file for profile data. 128 std::string ProfileRemapping; 129 130 /// The directory to store .dwo files. 131 std::string DwoDir; 132 133 /// The name for the split debug info file used for the DW_AT_[GNU_]dwo_name 134 /// attribute in the skeleton CU. This should generally only be used when 135 /// running an individual backend directly via thinBackend(), as otherwise 136 /// all objects would use the same .dwo file. Not used as output path. 137 std::string SplitDwarfFile; 138 139 /// The path to write a .dwo file to. This should generally only be used when 140 /// running an individual backend directly via thinBackend(), as otherwise 141 /// all .dwo files will be written to the same path. Not used in skeleton CU. 142 std::string SplitDwarfOutput; 143 144 /// Optimization remarks file path. 145 std::string RemarksFilename; 146 147 /// Optimization remarks pass filter. 148 std::string RemarksPasses; 149 150 /// Whether to emit optimization remarks with hotness informations. 151 bool RemarksWithHotness = false; 152 153 /// The minimum hotness value a diagnostic needs in order to be included in 154 /// optimization diagnostics. 155 /// 156 /// The threshold is an Optional value, which maps to one of the 3 states: 157 /// 1. 0 => threshold disabled. All emarks will be printed. 158 /// 2. positive int => manual threshold by user. Remarks with hotness exceed 159 /// threshold will be printed. 160 /// 3. None => 'auto' threshold by user. The actual value is not 161 /// available at command line, but will be synced with 162 /// hotness threhold from profile summary during 163 /// compilation. 164 /// 165 /// If threshold option is not specified, it is disabled by default. 166 std::optional<uint64_t> RemarksHotnessThreshold = 0; 167 168 /// The format used for serializing remarks (default: YAML). 169 std::string RemarksFormat; 170 171 /// Whether to emit the pass manager debuggging informations. 172 bool DebugPassManager = false; 173 174 /// Statistics output file path. 175 std::string StatsFile; 176 177 /// Specific thinLTO modules to compile. 178 std::vector<std::string> ThinLTOModulesToCompile; 179 180 /// Time trace enabled. 181 bool TimeTraceEnabled = false; 182 183 /// Time trace granularity. 184 unsigned TimeTraceGranularity = 500; 185 186 bool ShouldDiscardValueNames = true; 187 DiagnosticHandlerFunction DiagHandler; 188 189 /// Add FSAFDO discriminators. 190 bool AddFSDiscriminator = false; 191 192 /// If this field is set, LTO will write input file paths and symbol 193 /// resolutions here in llvm-lto2 command line flag format. This can be 194 /// used for testing and for running the LTO pipeline outside of the linker 195 /// with llvm-lto2. 196 std::unique_ptr<raw_ostream> ResolutionFile; 197 198 /// Tunable parameters for passes in the default pipelines. 199 PipelineTuningOptions PTO; 200 201 /// The following callbacks deal with tasks, which normally represent the 202 /// entire optimization and code generation pipeline for what will become a 203 /// single native object file. Each task has a unique identifier between 0 and 204 /// getMaxTasks()-1, which is supplied to the callback via the Task parameter. 205 /// A task represents the entire pipeline for ThinLTO and regular 206 /// (non-parallel) LTO, but a parallel code generation task will be split into 207 /// N tasks before code generation, where N is the parallelism level. 208 /// 209 /// LTO may decide to stop processing a task at any time, for example if the 210 /// module is empty or if a module hook (see below) returns false. For this 211 /// reason, the client should not expect to receive exactly getMaxTasks() 212 /// native object files. 213 214 /// A module hook may be used by a linker to perform actions during the LTO 215 /// pipeline. For example, a linker may use this function to implement 216 /// -save-temps. If this function returns false, any further processing for 217 /// that task is aborted. 218 /// 219 /// Module hooks must be thread safe with respect to the linker's internal 220 /// data structures. A module hook will never be called concurrently from 221 /// multiple threads with the same task ID, or the same module. 222 /// 223 /// Note that in out-of-process backend scenarios, none of the hooks will be 224 /// called for ThinLTO tasks. 225 using ModuleHookFn = std::function<bool(unsigned Task, const Module &)>; 226 227 /// This module hook is called after linking (regular LTO) or loading 228 /// (ThinLTO) the module, before modifying it. 229 ModuleHookFn PreOptModuleHook; 230 231 /// This hook is called after promoting any internal functions 232 /// (ThinLTO-specific). 233 ModuleHookFn PostPromoteModuleHook; 234 235 /// This hook is called after internalizing the module. 236 ModuleHookFn PostInternalizeModuleHook; 237 238 /// This hook is called after importing from other modules (ThinLTO-specific). 239 ModuleHookFn PostImportModuleHook; 240 241 /// This module hook is called after optimization is complete. 242 ModuleHookFn PostOptModuleHook; 243 244 /// This module hook is called before code generation. It is similar to the 245 /// PostOptModuleHook, but for parallel code generation it is called after 246 /// splitting the module. 247 ModuleHookFn PreCodeGenModuleHook; 248 249 /// A combined index hook is called after all per-module indexes have been 250 /// combined (ThinLTO-specific). It can be used to implement -save-temps for 251 /// the combined index. 252 /// 253 /// If this function returns false, any further processing for ThinLTO tasks 254 /// is aborted. 255 /// 256 /// It is called regardless of whether the backend is in-process, although it 257 /// is not called from individual backend processes. 258 using CombinedIndexHookFn = std::function<bool( 259 const ModuleSummaryIndex &Index, 260 const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols)>; 261 CombinedIndexHookFn CombinedIndexHook; 262 263 /// This is a convenience function that configures this Config object to write 264 /// temporary files named after the given OutputFileName for each of the LTO 265 /// phases to disk. A client can use this function to implement -save-temps. 266 /// 267 /// FIXME: Temporary files derived from ThinLTO backends are currently named 268 /// after the input file name, rather than the output file name, when 269 /// UseInputModulePath is set to true. 270 /// 271 /// Specifically, it (1) sets each of the above module hooks and the combined 272 /// index hook to a function that calls the hook function (if any) that was 273 /// present in the appropriate field when the addSaveTemps function was 274 /// called, and writes the module to a bitcode file with a name prefixed by 275 /// the given output file name, and (2) creates a resolution file whose name 276 /// is prefixed by the given output file name and sets ResolutionFile to its 277 /// file handle. 278 /// 279 /// SaveTempsArgs can be specified to select which temps to save. 280 /// If SaveTempsArgs is not provided, all temps are saved. 281 LLVM_ABI Error addSaveTemps(std::string OutputFileName, 282 bool UseInputModulePath = false, 283 const DenseSet<StringRef> &SaveTempsArgs = {}); 284 }; 285 286 struct LTOLLVMDiagnosticHandler : public DiagnosticHandler { 287 DiagnosticHandlerFunction *Fn; LTOLLVMDiagnosticHandlerLTOLLVMDiagnosticHandler288 LTOLLVMDiagnosticHandler(DiagnosticHandlerFunction *DiagHandlerFn) 289 : Fn(DiagHandlerFn) {} handleDiagnosticsLTOLLVMDiagnosticHandler290 bool handleDiagnostics(const DiagnosticInfo &DI) override { 291 (*Fn)(DI); 292 return true; 293 } 294 }; 295 /// A derived class of LLVMContext that initializes itself according to a given 296 /// Config object. The purpose of this class is to tie ownership of the 297 /// diagnostic handler to the context, as opposed to the Config object (which 298 /// may be ephemeral). 299 // FIXME: This should not be required as diagnostic handler is not callback. 300 struct LTOLLVMContext : LLVMContext { 301 LTOLLVMContextLTOLLVMContext302 LTOLLVMContext(const Config &C) : DiagHandler(C.DiagHandler) { 303 setDiscardValueNames(C.ShouldDiscardValueNames); 304 enableDebugTypeODRUniquing(); 305 setDiagnosticHandler( 306 std::make_unique<LTOLLVMDiagnosticHandler>(&DiagHandler), true); 307 } 308 DiagnosticHandlerFunction DiagHandler; 309 }; 310 311 } 312 } 313 314 #endif 315