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