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