brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.5 KiB · b7eb209 Raw
322 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// BOLT CLI options10//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_REVISION23    BOLT_REVISION;24#else25    "<unknown>";26#endif27}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(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(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(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(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(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(0),103  cl::ZeroOrMore,104  cl::Hidden,105  cl::cat(BoltOptCategory));106 107cl::opt<SplitFunctionsStrategy> SplitStrategy(108    "split-strategy", cl::init(SplitFunctionsStrategy::Profile2),109    cl::values(clEnumValN(SplitFunctionsStrategy::Profile2, "profile2",110                          "split each function into a hot and cold fragment "111                          "using profiling information")),112    cl::values(clEnumValN(SplitFunctionsStrategy::CDSplit, "cdsplit",113                          "split each function into a hot, warm, and cold "114                          "fragment using profiling information")),115    cl::values(clEnumValN(116        SplitFunctionsStrategy::Random2, "random2",117        "split each function into a hot and cold fragment at a randomly chosen "118        "split point (ignoring any available profiling information)")),119    cl::values(clEnumValN(120        SplitFunctionsStrategy::RandomN, "randomN",121        "split each function into N fragments at a randomly chosen split "122        "points (ignoring any available profiling information)")),123    cl::values(clEnumValN(124        SplitFunctionsStrategy::All, "all",125        "split all basic blocks of each function into fragments such that each "126        "fragment contains exactly a single basic block")),127    cl::desc("strategy used to partition blocks into fragments"),128    cl::cat(BoltOptCategory));129 130bool HeatmapBlockSpecParser::parse(cl::Option &O, StringRef ArgName,131                                   StringRef Arg, HeatmapBlockSizes &Val) {132  // Parses a human-readable suffix into a shift amount or nullopt on error.133  auto parseSuffix = [](StringRef Suffix) -> std::optional<unsigned> {134    if (Suffix.empty())135      return 0;136    if (!Regex{"^[kKmMgG]i?[bB]?$"}.match(Suffix))137      return std::nullopt;138    // clang-format off139    switch (Suffix.front()) {140      case 'k': case 'K': return 10;141      case 'm': case 'M': return 20;142      case 'g': case 'G': return 30;143    }144    // clang-format on145    llvm_unreachable("Unexpected suffix");146  };147 148  SmallVector<StringRef> Sizes;149  Arg.split(Sizes, ',');150  unsigned PreviousSize = 0;151  for (StringRef Size : Sizes) {152    StringRef OrigSize = Size;153    unsigned &SizeVal = Val.emplace_back(0);154    if (Size.consumeInteger(10, SizeVal)) {155      O.error("'" + OrigSize + "' value can't be parsed as an integer");156      return true;157    }158    if (std::optional<unsigned> ShiftAmt = parseSuffix(Size)) {159      SizeVal <<= *ShiftAmt;160    } else {161      O.error("'" + Size + "' value can't be parsed as a suffix");162      return true;163    }164    if (SizeVal <= PreviousSize || (PreviousSize && SizeVal % PreviousSize)) {165      O.error("'" + OrigSize + "' must be a multiple of previous value");166      return true;167    }168    PreviousSize = SizeVal;169  }170  return false;171}172 173cl::opt<opts::HeatmapBlockSizes, false, opts::HeatmapBlockSpecParser>174    HeatmapBlock(175        "block-size", cl::value_desc("initial_size{,zoom-out_size,...}"),176        cl::desc("heatmap bucket size, optionally followed by zoom-out sizes "177                 "for coarse-grained heatmaps (default 64B, 4K, 256K)."),178        cl::init(HeatmapBlockSizes{/*Initial*/ 64, /*Zoom-out*/ 4096, 262144}),179        cl::cat(HeatmapCategory));180 181cl::opt<unsigned long long> HeatmapMaxAddress(182    "max-address", cl::init(0xffffffff),183    cl::desc("maximum address considered valid for heatmap (default 4GB)"),184    cl::Optional, cl::cat(HeatmapCategory));185 186cl::opt<unsigned long long> HeatmapMinAddress(187    "min-address", cl::init(0x0),188    cl::desc("minimum address considered valid for heatmap (default 0)"),189    cl::Optional, cl::cat(HeatmapCategory));190 191cl::opt<bool> HeatmapPrintMappings(192    "print-mappings", cl::init(false),193    cl::desc("print mappings in the legend, between characters/blocks and text "194             "sections (default false)"),195    cl::Optional, cl::cat(HeatmapCategory));196 197cl::opt<std::string> HeatmapOutput("heatmap",198                                   cl::desc("print heatmap to a given file"),199                                   cl::Optional, cl::cat(HeatmapCategory));200 201cl::opt<bool> HotData("hot-data",202                      cl::desc("hot data symbols support (relocation mode)"),203                      cl::cat(BoltCategory));204 205cl::opt<bool> HotFunctionsAtEnd(206    "hot-functions-at-end",207    cl::desc(208        "if reorder-functions is used, order functions putting hottest last"),209    cl::cat(BoltCategory));210 211cl::opt<bool> HotText(212    "hot-text",213    cl::desc(214        "Generate hot text symbols. Apply this option to a precompiled binary "215        "that manually calls into hugify, such that at runtime hugify call "216        "will put hot code into 2M pages. This requires relocation."),217    cl::ZeroOrMore, cl::cat(BoltCategory));218 219cl::opt<bool>220    Instrument("instrument",221               cl::desc("instrument code to generate accurate profile data"),222               cl::cat(BoltOptCategory));223 224cl::opt<bool> Lite("lite", cl::desc("skip processing of cold functions"),225                   cl::cat(BoltCategory));226 227cl::opt<std::string>228OutputFilename("o",229  cl::desc("<output file>"),230  cl::Optional,231  cl::cat(BoltOutputCategory));232 233cl::opt<std::string> PerfData("perfdata", cl::desc("<data file>"), cl::Optional,234                              cl::cat(AggregatorCategory),235                              cl::sub(cl::SubCommand::getAll()));236 237static cl::alias238PerfDataA("p",239  cl::desc("alias for -perfdata"),240  cl::aliasopt(PerfData),241  cl::cat(AggregatorCategory));242 243cl::opt<bool> PrintCacheMetrics(244    "print-cache-metrics",245    cl::desc("calculate and print various metrics for instruction cache"),246    cl::cat(BoltOptCategory));247 248cl::list<std::string> PrintOnly("print-only", cl::CommaSeparated,249                                cl::desc("list of functions to print"),250                                cl::value_desc("func1,func2,func3,..."),251                                cl::Hidden, cl::cat(BoltCategory));252 253cl::opt<std::string>254    PrintOnlyFile("print-only-file",255                  cl::desc("file with list of functions to print"), cl::Hidden,256                  cl::cat(BoltCategory));257 258cl::opt<bool> PrintSections("print-sections",259                            cl::desc("print all registered sections"),260                            cl::Hidden, cl::cat(BoltCategory));261 262cl::opt<ProfileFormatKind> ProfileFormat(263    "profile-format",264    cl::desc(265        "format to dump profile output in aggregation mode, default is fdata"),266    cl::init(PF_Fdata),267    cl::values(clEnumValN(PF_Fdata, "fdata", "offset-based plaintext format"),268               clEnumValN(PF_YAML, "yaml", "dense YAML representation")),269    cl::ZeroOrMore, cl::Hidden, cl::cat(BoltCategory));270 271cl::opt<std::string> SaveProfile("w",272                                 cl::desc("save recorded profile to a file"),273                                 cl::cat(BoltOutputCategory));274 275cl::opt<bool> ShowDensity("show-density",276                          cl::desc("show profile density details"),277                          cl::Optional, cl::cat(AggregatorCategory));278 279cl::opt<bool> SplitEH("split-eh", cl::desc("split C++ exception handling code"),280                      cl::Hidden, cl::cat(BoltOptCategory));281 282cl::opt<bool>283    StrictMode("strict",284               cl::desc("trust the input to be from a well-formed source"),285 286               cl::cat(BoltCategory));287 288cl::opt<bool> TimeOpts("time-opts",289                       cl::desc("print time spent in each optimization"),290                       cl::cat(BoltOptCategory));291 292cl::opt<bool> TimeRewrite("time-rewrite",293                          cl::desc("print time spent in rewriting passes"),294                          cl::Hidden, cl::cat(BoltCategory));295 296cl::opt<bool> UseOldText(297    "use-old-text",298    cl::desc("reuse space in old .text if possible (relocation mode)"),299    cl::cat(BoltCategory));300 301cl::opt<bool> UpdateDebugSections(302    "update-debug-sections",303    cl::desc("update DWARF debug sections of the executable"),304    cl::cat(BoltCategory));305 306cl::opt<unsigned>307    Verbosity("v", cl::desc("set verbosity level for diagnostic output"),308              cl::init(0), cl::ZeroOrMore, cl::cat(BoltCategory),309              cl::sub(cl::SubCommand::getAll()));310 311bool processAllFunctions() {312  if (opts::AggregateOnly)313    return false;314 315  if (UseOldText || StrictMode)316    return true;317 318  return false;319}320 321} // namespace opts322