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