1//===- bolt/Utils/CommandLineOpts.cpp - BOLT CLI options ------------------===//
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// BOLT CLI options
10//
11//===----------------------------------------------------------------------===//
12
13#include "bolt/Utils/CommandLineOpts.h"
14#include "VCSVersion.inc"
15#include "llvm/Support/Regex.h"
16
17using namespace llvm;
18
19namespace llvm {
20namespace bolt {
21const char *BoltRevision =
22#ifdef BOLT_REVISION
23 BOLT_REVISION;
24#else
25 "<unknown>";
26#endif
27}
28}
29
30namespace opts {
31
32HeatmapModeKind HeatmapMode = HM_None;
33bool BinaryAnalysisMode = false;
34
35cl::OptionCategory BoltCategory("BOLT generic options");
36cl::OptionCategory BoltDiffCategory("BOLTDIFF generic options");
37cl::OptionCategory BoltOptCategory("BOLT optimization options");
38cl::OptionCategory BoltRelocCategory("BOLT options in relocation mode");
39cl::OptionCategory BoltOutputCategory("Output options");
40cl::OptionCategory AggregatorCategory("Data aggregation options");
41cl::OptionCategory BoltInstrCategory("BOLT instrumentation options");
42cl::OptionCategory HeatmapCategory("Heatmap options");
43cl::OptionCategory BinaryAnalysisCategory("BinaryAnalysis options");
44
45cl::opt<unsigned> AlignText("align-text",
46 cl::desc("alignment of .text section"), cl::Hidden,
47 cl::cat(BoltCategory));
48
49cl::opt<unsigned> AlignFunctions(
50 "align-functions",
51 cl::desc("align functions at a given value (relocation mode)"),
52 cl::init(Val: 64), cl::cat(BoltOptCategory));
53
54cl::opt<bool>
55AggregateOnly("aggregate-only",
56 cl::desc("exit after writing aggregated data file"),
57 cl::Hidden,
58 cl::cat(AggregatorCategory));
59
60cl::opt<unsigned>
61 BucketsPerLine("line-size",
62 cl::desc("number of entries per line (default 256)"),
63 cl::init(Val: 256), cl::Optional, cl::cat(HeatmapCategory));
64
65cl::opt<bool>
66 CompactCodeModel("compact-code-model",
67 cl::desc("generate code for binaries <128MB on AArch64"),
68 cl::init(Val: false), cl::cat(BoltCategory));
69
70cl::opt<bool>
71DiffOnly("diff-only",
72 cl::desc("stop processing once we have enough to compare two binaries"),
73 cl::Hidden,
74 cl::cat(BoltDiffCategory));
75
76cl::opt<bool>
77EnableBAT("enable-bat",
78 cl::desc("write BOLT Address Translation tables"),
79 cl::init(Val: false),
80 cl::ZeroOrMore,
81 cl::cat(BoltCategory));
82
83cl::opt<bool> EqualizeBBCounts(
84 "equalize-bb-counts",
85 cl::desc("use same count for BBs that should have equivalent count (used "
86 "in non-LBR and shrink wrapping)"),
87 cl::ZeroOrMore, cl::init(Val: false), cl::Hidden, cl::cat(BoltOptCategory));
88
89llvm::cl::opt<bool> ForcePatch(
90 "force-patch",
91 llvm::cl::desc("force patching of original entry points to ensure "
92 "execution follows only the new/optimized code."),
93 llvm::cl::Hidden, llvm::cl::cat(BoltCategory));
94
95cl::opt<bool> RemoveSymtab("remove-symtab", cl::desc("Remove .symtab section"),
96 cl::cat(BoltCategory));
97
98cl::opt<unsigned>
99ExecutionCountThreshold("execution-count-threshold",
100 cl::desc("perform profiling accuracy-sensitive optimizations only if "
101 "function execution count >= the threshold (default: 0)"),
102 cl::init(Val: 0),
103 cl::ZeroOrMore,
104 cl::Hidden,
105 cl::cat(BoltOptCategory));
106
107bool HeatmapBlockSpecParser::parse(cl::Option &O, StringRef ArgName,
108 StringRef Arg, HeatmapBlockSizes &Val) {
109 // Parses a human-readable suffix into a shift amount or nullopt on error.
110 auto parseSuffix = [](StringRef Suffix) -> std::optional<unsigned> {
111 if (Suffix.empty())
112 return 0;
113 if (!Regex{"^[kKmMgG]i?[bB]?$"}.match(String: Suffix))
114 return std::nullopt;
115 // clang-format off
116 switch (Suffix.front()) {
117 case 'k': case 'K': return 10;
118 case 'm': case 'M': return 20;
119 case 'g': case 'G': return 30;
120 }
121 // clang-format on
122 llvm_unreachable("Unexpected suffix");
123 };
124
125 SmallVector<StringRef> Sizes;
126 Arg.split(A&: Sizes, Separator: ',');
127 unsigned PreviousSize = 0;
128 for (StringRef Size : Sizes) {
129 StringRef OrigSize = Size;
130 unsigned &SizeVal = Val.emplace_back(args: 0);
131 if (Size.consumeInteger(Radix: 10, Result&: SizeVal)) {
132 O.error(Message: "'" + OrigSize + "' value can't be parsed as an integer");
133 return true;
134 }
135 if (std::optional<unsigned> ShiftAmt = parseSuffix(Size)) {
136 SizeVal <<= *ShiftAmt;
137 } else {
138 O.error(Message: "'" + Size + "' value can't be parsed as a suffix");
139 return true;
140 }
141 if (SizeVal <= PreviousSize || (PreviousSize && SizeVal % PreviousSize)) {
142 O.error(Message: "'" + OrigSize + "' must be a multiple of previous value");
143 return true;
144 }
145 PreviousSize = SizeVal;
146 }
147 return false;
148}
149
150cl::opt<opts::HeatmapBlockSizes, false, opts::HeatmapBlockSpecParser>
151 HeatmapBlock(
152 "block-size", cl::value_desc("initial_size{,zoom-out_size,...}"),
153 cl::desc("heatmap bucket size, optionally followed by zoom-out sizes "
154 "for coarse-grained heatmaps (default 64B, 4K, 256K)."),
155 cl::init(Val: HeatmapBlockSizes{/*Initial*/ 64, /*Zoom-out*/ 4096, 262144}),
156 cl::cat(HeatmapCategory));
157
158cl::opt<unsigned long long> HeatmapMaxAddress(
159 "max-address", cl::init(Val: 0xffffffff),
160 cl::desc("maximum address considered valid for heatmap (default 4GB)"),
161 cl::Optional, cl::cat(HeatmapCategory));
162
163cl::opt<unsigned long long> HeatmapMinAddress(
164 "min-address", cl::init(Val: 0x0),
165 cl::desc("minimum address considered valid for heatmap (default 0)"),
166 cl::Optional, cl::cat(HeatmapCategory));
167
168cl::opt<bool> HeatmapPrintMappings(
169 "print-mappings", cl::init(Val: false),
170 cl::desc("print mappings in the legend, between characters/blocks and text "
171 "sections (default false)"),
172 cl::Optional, cl::cat(HeatmapCategory));
173
174cl::opt<std::string> HeatmapOutput("heatmap",
175 cl::desc("print heatmap to a given file"),
176 cl::Optional, cl::cat(HeatmapCategory));
177
178cl::opt<bool> HotData("hot-data",
179 cl::desc("hot data symbols support (relocation mode)"),
180 cl::cat(BoltCategory));
181
182cl::opt<bool> HotFunctionsAtEnd(
183 "hot-functions-at-end",
184 cl::desc(
185 "if reorder-functions is used, order functions putting hottest last"),
186 cl::cat(BoltCategory));
187
188cl::opt<bool> HotText(
189 "hot-text",
190 cl::desc(
191 "Generate hot text symbols. Apply this option to a precompiled binary "
192 "that manually calls into hugify, such that at runtime hugify call "
193 "will put hot code into 2M pages. This requires relocation."),
194 cl::ZeroOrMore, cl::cat(BoltCategory));
195
196cl::opt<bool>
197 Instrument("instrument",
198 cl::desc("instrument code to generate accurate profile data"),
199 cl::cat(BoltOptCategory));
200
201cl::opt<bool> Lite("lite", cl::desc("skip processing of cold functions"),
202 cl::cat(BoltCategory));
203
204cl::opt<std::string>
205OutputFilename("o",
206 cl::desc("<output file>"),
207 cl::Optional,
208 cl::cat(BoltOutputCategory));
209
210cl::opt<std::string> PerfData("perfdata", cl::desc("<data file>"), cl::Optional,
211 cl::cat(AggregatorCategory),
212 cl::sub(cl::SubCommand::getAll()));
213
214static cl::alias
215PerfDataA("p",
216 cl::desc("alias for -perfdata"),
217 cl::aliasopt(PerfData),
218 cl::cat(AggregatorCategory));
219
220cl::opt<bool> PrintCacheMetrics(
221 "print-cache-metrics",
222 cl::desc("calculate and print various metrics for instruction cache"),
223 cl::cat(BoltOptCategory));
224
225cl::opt<bool> PrintSections("print-sections",
226 cl::desc("print all registered sections"),
227 cl::Hidden, cl::cat(BoltCategory));
228
229cl::opt<ProfileFormatKind> ProfileFormat(
230 "profile-format",
231 cl::desc(
232 "format to dump profile output in aggregation mode, default is fdata"),
233 cl::init(Val: PF_Fdata),
234 cl::values(clEnumValN(PF_Fdata, "fdata", "offset-based plaintext format"),
235 clEnumValN(PF_YAML, "yaml", "dense YAML representation")),
236 cl::ZeroOrMore, cl::Hidden, cl::cat(BoltCategory));
237
238cl::opt<std::string> SaveProfile("w",
239 cl::desc("save recorded profile to a file"),
240 cl::cat(BoltOutputCategory));
241
242cl::opt<bool> ShowDensity("show-density",
243 cl::desc("show profile density details"),
244 cl::Optional, cl::cat(AggregatorCategory));
245
246cl::opt<bool> SplitEH("split-eh", cl::desc("split C++ exception handling code"),
247 cl::Hidden, cl::cat(BoltOptCategory));
248
249cl::opt<bool>
250 StrictMode("strict",
251 cl::desc("trust the input to be from a well-formed source"),
252
253 cl::cat(BoltCategory));
254
255cl::opt<bool> TimeOpts("time-opts",
256 cl::desc("print time spent in each optimization"),
257 cl::cat(BoltOptCategory));
258
259cl::opt<bool> TimeRewrite("time-rewrite",
260 cl::desc("print time spent in rewriting passes"),
261 cl::Hidden, cl::cat(BoltCategory));
262
263cl::opt<bool> UseOldText(
264 "use-old-text",
265 cl::desc("re-use space in old .text if possible (relocation mode)"),
266 cl::cat(BoltCategory));
267
268cl::opt<bool> UpdateDebugSections(
269 "update-debug-sections",
270 cl::desc("update DWARF debug sections of the executable"),
271 cl::cat(BoltCategory));
272
273cl::opt<unsigned>
274 Verbosity("v", cl::desc("set verbosity level for diagnostic output"),
275 cl::init(Val: 0), cl::ZeroOrMore, cl::cat(BoltCategory),
276 cl::sub(cl::SubCommand::getAll()));
277
278bool processAllFunctions() {
279 if (opts::AggregateOnly)
280 return false;
281
282 if (UseOldText || StrictMode)
283 return true;
284
285 return false;
286}
287
288} // namespace opts
289

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of bolt/lib/Utils/CommandLineOpts.cpp