forked from OSchip/llvm-project
[BOLT] Organize options in categories for pretty printing (near NFC).
Summary: Each BOLT-specific option now belongs to BoltCategory or BoltOptCategory. Use alphabetical order for options in source code (does not affect output). The result is a cleaner output of "llvm-bolt -help" which does not include any unrelated llvm options and is close to the following: ..... BOLT generic options: -data=<string> - <data file> -dyno-stats - print execution info based on profile -hot-text - hot text symbols support (relocation mode) -o=<string> - <output file> -relocs - relocation mode - use relocations to move functions in the binary -update-debug-sections - update DWARF debug sections of the executable -use-gnu-stack - use GNU_STACK program header for new segment (workaround for issues with strip/objcopy) -use-old-text - re-use space in old .text if possible (relocation mode) -v=<uint> - set verbosity level for diagnostic output BOLT optimization options: -align-blocks - try to align BBs inserting nops -align-functions=<uint> - align functions at a given value (relocation mode) -align-functions-max-bytes=<uint> - maximum number of bytes to use to align functions -boost-macroops - try to boost macro-op fusions by avoiding the cache-line boundary -eliminate-unreachable - eliminate unreachable code -frame-opt - optimize stack frame accesses ...... (cherry picked from FBD4793684)
This commit is contained in:
parent
d5a0264a9e
commit
0bde796e50
|
@ -24,12 +24,15 @@ using namespace bolt;
|
|||
|
||||
namespace opts {
|
||||
|
||||
extern cl::OptionCategory BoltCategory;
|
||||
|
||||
extern cl::opt<bool> Relocs;
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintDebugInfo("print-debug-info",
|
||||
cl::desc("print debug info when printing functions"),
|
||||
cl::Hidden);
|
||||
cl::desc("print debug info when printing functions"),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
} // namespace opts
|
||||
|
||||
|
|
|
@ -42,6 +42,10 @@ using namespace bolt;
|
|||
|
||||
namespace opts {
|
||||
|
||||
extern cl::OptionCategory BoltCategory;
|
||||
extern cl::OptionCategory BoltOptCategory;
|
||||
extern cl::OptionCategory BoltRelocCategory;
|
||||
|
||||
extern bool shouldProcess(const BinaryFunction &);
|
||||
|
||||
extern cl::opt<bool> PrintDynoStats;
|
||||
|
@ -51,25 +55,30 @@ extern cl::opt<unsigned> Verbosity;
|
|||
|
||||
static cl::opt<bool>
|
||||
AggressiveSplitting("split-all-cold",
|
||||
cl::desc("outline as many cold basic blocks as possible"),
|
||||
cl::ZeroOrMore);
|
||||
cl::desc("outline as many cold basic blocks as possible"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
AlignBlocks("align-blocks",
|
||||
cl::desc("try to align BBs inserting nops"),
|
||||
cl::ZeroOrMore);
|
||||
cl::desc("try to align BBs inserting nops"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
DotToolTipCode("dot-tooltip-code",
|
||||
cl::desc("add basic block instructions as tool tips on nodes"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
cl::desc("add basic block instructions as tool tips on nodes"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<uint32_t>
|
||||
DynoStatsScale("dyno-stats-scale",
|
||||
cl::desc("scale to be applied while reporting dyno stats"),
|
||||
cl::Optional,
|
||||
cl::init(1));
|
||||
cl::desc("scale to be applied while reporting dyno stats"),
|
||||
cl::Optional,
|
||||
cl::init(1),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<JumpTableSupportLevel>
|
||||
JumpTables("jump-tables",
|
||||
|
@ -89,26 +98,30 @@ JumpTables("jump-tables",
|
|||
"aggressively split jump tables section based on usage "
|
||||
"of the tables"),
|
||||
clEnumValEnd),
|
||||
cl::ZeroOrMore);
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintJumpTables("print-jump-tables",
|
||||
cl::desc("print jump tables"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
cl::desc("print jump tables"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::list<std::string>
|
||||
PrintOnly("print-only",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to print"),
|
||||
cl::value_desc("func1,func2,func3,..."),
|
||||
cl::Hidden);
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
SplitEH("split-eh",
|
||||
cl::desc("split C++ exception handling code (experimental)"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
cl::desc("split C++ exception handling code (experimental)"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
bool shouldPrint(const BinaryFunction &Function) {
|
||||
if (PrintOnly.empty())
|
||||
|
|
|
@ -19,160 +19,186 @@ using namespace llvm;
|
|||
|
||||
namespace opts {
|
||||
|
||||
extern cl::OptionCategory BoltOptCategory;
|
||||
|
||||
extern cl::opt<bool> PrintAll;
|
||||
extern cl::opt<bool> DumpDotAll;
|
||||
extern cl::opt<bool> DynoStatsAll;
|
||||
|
||||
llvm::cl::opt<bool> TimeOpts("time-opts",
|
||||
cl::desc("print time spent in each optimization"),
|
||||
cl::init(false), cl::ZeroOrMore);
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
VerifyCFG("verify-cfg",
|
||||
cl::desc("verify the CFG after every pass"),
|
||||
cl::init(false),
|
||||
cl::Hidden,
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
EliminateUnreachable("eliminate-unreachable",
|
||||
cl::desc("eliminate unreachable code"),
|
||||
cl::init(true),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
OptimizeBodylessFunctions(
|
||||
"optimize-bodyless-functions",
|
||||
cl::desc("optimize functions that just do a tail call"),
|
||||
cl::ZeroOrMore);
|
||||
cl::desc("eliminate unreachable code"),
|
||||
cl::init(true),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
IndirectCallPromotion("indirect-call-promotion",
|
||||
cl::desc("indirect call promotion"),
|
||||
cl::ZeroOrMore);
|
||||
cl::desc("indirect call promotion"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
InlineSmallFunctions(
|
||||
"inline-small-functions",
|
||||
cl::desc("inline functions with a single basic block"),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
SimplifyConditionalTailCalls("simplify-conditional-tail-calls",
|
||||
cl::desc("simplify conditional tail calls "
|
||||
"by removing unnecessary jumps"),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
Peepholes("peepholes",
|
||||
cl::desc("run peephole optimizations"),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
SimplifyRODataLoads("simplify-rodata-loads",
|
||||
cl::desc("simplify loads from read-only sections by "
|
||||
"replacing the memory operand with the "
|
||||
"constant found in the corresponding "
|
||||
"section"),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
StripRepRet("strip-rep-ret",
|
||||
cl::desc("strip 'repz' prefix from 'repz retq' sequence (on by default)"),
|
||||
cl::init(true),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool> OptimizeFrameAccesses(
|
||||
"frame-opt", cl::desc("optimize stack frame accesses"), cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintReordered("print-reordered",
|
||||
cl::desc("print functions after layout optimization"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintReorderedFunctions("print-reordered-functions",
|
||||
cl::desc("print functions after clustering"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintOptimizeBodyless("print-optimize-bodyless",
|
||||
cl::desc("print functions after bodyless optimization"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintAfterBranchFixup("print-after-branch-fixup",
|
||||
cl::desc("print function after fixing local branches"),
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintFinalized("print-finalized",
|
||||
cl::desc("print function after CFG is finalized"),
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintAfterLowering("print-after-lowering",
|
||||
cl::desc("print function after instruction lowering"),
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintUCE("print-uce",
|
||||
cl::desc("print functions after unreachable code elimination"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintSCTC("print-sctc",
|
||||
cl::desc("print functions after conditional tail call simplification"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintPeepholes("print-peepholes",
|
||||
cl::desc("print functions after peephole optimization"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintSimplifyROLoads("print-simplify-rodata-loads",
|
||||
cl::desc("print functions after simplification of RO data"
|
||||
" loads"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintICF("print-icf",
|
||||
cl::desc("print functions after ICF optimization"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintICP("print-icp",
|
||||
cl::desc("print functions after indirect call promotion"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintInline("print-inline",
|
||||
cl::desc("print functions after inlining optimization"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintFOP("print-fop",
|
||||
cl::desc("print functions after frame optimizer pass"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
InlineSmallFunctions("inline-small-functions",
|
||||
cl::desc("inline functions with a single basic block"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
NeverPrint("never-print",
|
||||
cl::desc("never print"),
|
||||
cl::init(false),
|
||||
cl::ZeroOrMore,
|
||||
cl::ReallyHidden);
|
||||
cl::desc("never print"),
|
||||
cl::init(false),
|
||||
cl::ZeroOrMore,
|
||||
cl::ReallyHidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
OptimizeBodylessFunctions("optimize-bodyless-functions",
|
||||
cl::desc("optimize functions that just do a tail call"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
OptimizeFrameAccesses("frame-opt",
|
||||
cl::desc("optimize stack frame accesses"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
Peepholes("peepholes",
|
||||
cl::desc("run peephole optimizations"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintAfterBranchFixup("print-after-branch-fixup",
|
||||
cl::desc("print function after fixing local branches"),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintAfterLowering("print-after-lowering",
|
||||
cl::desc("print function after instruction lowering"),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintFOP("print-fop",
|
||||
cl::desc("print functions after frame optimizer pass"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintFinalized("print-finalized",
|
||||
cl::desc("print function after CFG is finalized"),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintICF("print-icf",
|
||||
cl::desc("print functions after ICF optimization"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintICP("print-icp",
|
||||
cl::desc("print functions after indirect call promotion"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintInline("print-inline",
|
||||
cl::desc("print functions after inlining optimization"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintOptimizeBodyless("print-optimize-bodyless",
|
||||
cl::desc("print functions after bodyless optimization"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintPeepholes("print-peepholes",
|
||||
cl::desc("print functions after peephole optimization"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintReordered("print-reordered",
|
||||
cl::desc("print functions after layout optimization"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintReorderedFunctions("print-reordered-functions",
|
||||
cl::desc("print functions after clustering"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintSCTC("print-sctc",
|
||||
cl::desc("print functions after conditional tail call simplification"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintSimplifyROLoads("print-simplify-rodata-loads",
|
||||
cl::desc("print functions after simplification of RO data loads"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintUCE("print-uce",
|
||||
cl::desc("print functions after unreachable code elimination"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
SimplifyConditionalTailCalls("simplify-conditional-tail-calls",
|
||||
cl::desc("simplify conditional tail calls by removing unnecessary jumps"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
SimplifyRODataLoads("simplify-rodata-loads",
|
||||
cl::desc("simplify loads from read-only sections by replacing the memory "
|
||||
"operand with the constant found in the corresponding section"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
StripRepRet("strip-rep-ret",
|
||||
cl::desc("strip 'repz' prefix from 'repz retq' sequence (on by default)"),
|
||||
cl::init(true),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
TimeOpts("time-opts",
|
||||
cl::desc("print time spent in each optimization"),
|
||||
cl::init(false),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
VerifyCFG("verify-cfg",
|
||||
cl::desc("verify the CFG after every pass"),
|
||||
cl::init(false),
|
||||
cl::Hidden,
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
} // namespace opts
|
||||
|
||||
|
|
|
@ -37,13 +37,16 @@ using namespace llvm::dwarf;
|
|||
|
||||
namespace opts {
|
||||
|
||||
extern llvm::cl::OptionCategory BoltCategory;
|
||||
|
||||
extern llvm::cl::opt<unsigned> Verbosity;
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
PrintExceptions("print-exceptions",
|
||||
llvm::cl::desc("print exception handling data"),
|
||||
llvm::cl::ZeroOrMore,
|
||||
llvm::cl::Hidden);
|
||||
llvm::cl::desc("print exception handling data"),
|
||||
llvm::cl::ZeroOrMore,
|
||||
llvm::cl::Hidden,
|
||||
llvm::cl::cat(BoltCategory));
|
||||
|
||||
} // namespace opts
|
||||
|
||||
|
|
|
@ -49,6 +49,8 @@ const char* dynoStatsOptDesc(const bolt::DynoStats::Category C) {
|
|||
|
||||
namespace opts {
|
||||
|
||||
extern cl::OptionCategory BoltOptCategory;
|
||||
|
||||
extern cl::opt<unsigned> Verbosity;
|
||||
extern cl::opt<uint32_t> RandomSeed;
|
||||
extern cl::opt<bool> Relocs;
|
||||
|
@ -56,117 +58,174 @@ extern cl::opt<bolt::BinaryFunction::SplittingType> SplitFunctions;
|
|||
extern bool shouldProcess(const bolt::BinaryFunction &Function);
|
||||
extern size_t padFunction(const bolt::BinaryFunction &Function);
|
||||
|
||||
static cl::opt<unsigned>
|
||||
IndirectCallPromotionThreshold(
|
||||
"indirect-call-promotion-threshold",
|
||||
cl::desc("threshold for optimizing a frequently taken indirect call"),
|
||||
cl::init(90),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<unsigned>
|
||||
IndirectCallPromotionMispredictThreshold(
|
||||
"indirect-call-promotion-mispredict-threshold",
|
||||
cl::desc("misprediction threshold for skipping ICP on an "
|
||||
"indirect call"),
|
||||
cl::init(2),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
IndirectCallPromotionUseMispredicts(
|
||||
"indirect-call-promotion-use-mispredicts",
|
||||
cl::desc("use misprediction frequency for determining whether or not ICP "
|
||||
"should be applied at a callsite. The "
|
||||
"-indirect-call-promotion-mispredict-threshold value will be used "
|
||||
"by this heuristic"),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<unsigned>
|
||||
IndirectCallPromotionTopN(
|
||||
"indirect-call-promotion-topn",
|
||||
cl::desc("number of targets to consider when doing indirect "
|
||||
"call promotion"),
|
||||
cl::init(1),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::list<std::string>
|
||||
ICPFuncsList("icp-funcs",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to enable ICP for"),
|
||||
cl::value_desc("func1,func2,func3,..."),
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
ICPOldCodeSequence(
|
||||
"icp-old-code-sequence",
|
||||
cl::desc("use old code sequence for promoted calls"),
|
||||
cl::init(false),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bolt::BinaryFunction::LayoutType>
|
||||
ReorderBlocks(
|
||||
"reorder-blocks",
|
||||
cl::desc("change layout of basic blocks in a function"),
|
||||
cl::init(bolt::BinaryFunction::LT_NONE),
|
||||
cl::values(clEnumValN(bolt::BinaryFunction::LT_NONE,
|
||||
"none",
|
||||
"do not reorder basic blocks"),
|
||||
clEnumValN(bolt::BinaryFunction::LT_REVERSE,
|
||||
"reverse",
|
||||
"layout blocks in reverse order"),
|
||||
clEnumValN(bolt::BinaryFunction::LT_OPTIMIZE,
|
||||
"normal",
|
||||
"perform optimal layout based on profile"),
|
||||
clEnumValN(bolt::BinaryFunction::LT_OPTIMIZE_BRANCH,
|
||||
"branch-predictor",
|
||||
"perform optimal layout prioritizing branch "
|
||||
"predictions"),
|
||||
clEnumValN(bolt::BinaryFunction::LT_OPTIMIZE_CACHE,
|
||||
"cache",
|
||||
"perform optimal layout prioritizing I-cache "
|
||||
"behavior"),
|
||||
clEnumValN(bolt::BinaryFunction::LT_OPTIMIZE_SHUFFLE,
|
||||
"cluster-shuffle",
|
||||
"perform random layout of clusters"),
|
||||
clEnumValEnd),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
MinBranchClusters(
|
||||
"min-branch-clusters",
|
||||
cl::desc("use a modified clustering algorithm geared towards "
|
||||
"minimizing branches"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::list<bolt::DynoStats::Category>
|
||||
PrintSortedBy(
|
||||
"print-sorted-by",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("print functions sorted by order of dyno stats"),
|
||||
cl::value_desc("key1,key2,key3,..."),
|
||||
cl::values(
|
||||
#define D(name, ...) \
|
||||
clEnumValN(bolt::DynoStats::name, \
|
||||
dynoStatsOptName(bolt::DynoStats::name), \
|
||||
dynoStatsOptDesc(bolt::DynoStats::name)),
|
||||
DYNO_STATS
|
||||
#undef D
|
||||
clEnumValEnd),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
enum DynoStatsSortOrder : char {
|
||||
Ascending,
|
||||
Descending
|
||||
};
|
||||
|
||||
static cl::opt<DynoStatsSortOrder>
|
||||
DynoStatsSortOrderOpt(
|
||||
"print-sorted-by-order",
|
||||
cl::desc("use ascending or descending order when printing "
|
||||
"functions ordered by dyno stats"),
|
||||
cl::ZeroOrMore,
|
||||
cl::init(DynoStatsSortOrder::Descending));
|
||||
DynoStatsSortOrderOpt("print-sorted-by-order",
|
||||
cl::desc("use ascending or descending order when printing functions "
|
||||
"ordered by dyno stats"),
|
||||
cl::ZeroOrMore,
|
||||
cl::init(DynoStatsSortOrder::Descending),
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<std::string>
|
||||
FunctionOrderFile("function-order",
|
||||
cl::desc("file containing an ordered list of functions to use for function "
|
||||
"reordering"),
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
ICF("icf",
|
||||
cl::desc("fold functions with identical code"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
ICFUseDFS("icf-dfs",
|
||||
cl::desc("use DFS ordering when using -icf option"),
|
||||
cl::ReallyHidden,
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::list<std::string>
|
||||
ICPFuncsList("icp-funcs",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to enable ICP for"),
|
||||
cl::value_desc("func1,func2,func3,..."),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
ICPOldCodeSequence("icp-old-code-sequence",
|
||||
cl::desc("use old code sequence for promoted calls"),
|
||||
cl::init(false),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<unsigned>
|
||||
IndirectCallPromotionMispredictThreshold(
|
||||
"indirect-call-promotion-mispredict-threshold",
|
||||
cl::desc("misprediction threshold for skipping ICP on an "
|
||||
"indirect call"),
|
||||
cl::init(2),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<unsigned>
|
||||
IndirectCallPromotionThreshold("indirect-call-promotion-threshold",
|
||||
cl::desc("threshold for optimizing a frequently taken indirect call"),
|
||||
cl::init(90),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<unsigned>
|
||||
IndirectCallPromotionTopN("indirect-call-promotion-topn",
|
||||
cl::desc("number of targets to consider when doing indirect "
|
||||
"call promotion"),
|
||||
cl::init(1),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
IndirectCallPromotionUseMispredicts("indirect-call-promotion-use-mispredicts",
|
||||
cl::desc("use misprediction frequency for determining whether or not ICP "
|
||||
"should be applied at a callsite. The "
|
||||
"-indirect-call-promotion-mispredict-threshold value will be used "
|
||||
"by this heuristic"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
MinBranchClusters("min-branch-clusters",
|
||||
cl::desc("use a modified clustering algorithm geared towards minimizing "
|
||||
"branches"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::list<bolt::DynoStats::Category>
|
||||
PrintSortedBy("print-sorted-by",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("print functions sorted by order of dyno stats"),
|
||||
cl::value_desc("key1,key2,key3,..."),
|
||||
cl::values(
|
||||
#define D(name, ...) \
|
||||
clEnumValN(bolt::DynoStats::name, \
|
||||
dynoStatsOptName(bolt::DynoStats::name), \
|
||||
dynoStatsOptDesc(bolt::DynoStats::name)),
|
||||
DYNO_STATS
|
||||
#undef D
|
||||
clEnumValEnd),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bolt::BinaryFunction::LayoutType>
|
||||
ReorderBlocks("reorder-blocks",
|
||||
cl::desc("change layout of basic blocks in a function"),
|
||||
cl::init(bolt::BinaryFunction::LT_NONE),
|
||||
cl::values(
|
||||
clEnumValN(bolt::BinaryFunction::LT_NONE,
|
||||
"none",
|
||||
"do not reorder basic blocks"),
|
||||
clEnumValN(bolt::BinaryFunction::LT_REVERSE,
|
||||
"reverse",
|
||||
"layout blocks in reverse order"),
|
||||
clEnumValN(bolt::BinaryFunction::LT_OPTIMIZE,
|
||||
"normal",
|
||||
"perform optimal layout based on profile"),
|
||||
clEnumValN(bolt::BinaryFunction::LT_OPTIMIZE_BRANCH,
|
||||
"branch-predictor",
|
||||
"perform optimal layout prioritizing branch "
|
||||
"predictions"),
|
||||
clEnumValN(bolt::BinaryFunction::LT_OPTIMIZE_CACHE,
|
||||
"cache",
|
||||
"perform optimal layout prioritizing I-cache "
|
||||
"behavior"),
|
||||
clEnumValN(bolt::BinaryFunction::LT_OPTIMIZE_SHUFFLE,
|
||||
"cluster-shuffle",
|
||||
"perform random layout of clusters"),
|
||||
clEnumValEnd),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
cl::opt<bolt::BinaryFunction::ReorderType>
|
||||
ReorderFunctions("reorder-functions",
|
||||
cl::desc("reorder and cluster functions (works only with relocations)"),
|
||||
cl::init(bolt::BinaryFunction::RT_NONE),
|
||||
cl::values(clEnumValN(bolt::BinaryFunction::RT_NONE,
|
||||
"none",
|
||||
"do not reorder functions"),
|
||||
clEnumValN(bolt::BinaryFunction::RT_EXEC_COUNT,
|
||||
"exec-count",
|
||||
"order by execution count"),
|
||||
clEnumValN(bolt::BinaryFunction::RT_HFSORT,
|
||||
"hfsort",
|
||||
"use hfsort algorithm"),
|
||||
clEnumValN(bolt::BinaryFunction::RT_HFSORT_PLUS,
|
||||
"hfsort+",
|
||||
"use hfsort+ algorithm"),
|
||||
clEnumValN(bolt::BinaryFunction::RT_PETTIS_HANSEN,
|
||||
"pettis-hansen",
|
||||
"use Pettis-Hansen algorithm"),
|
||||
clEnumValN(bolt::BinaryFunction::RT_RANDOM,
|
||||
"random",
|
||||
"reorder functions randomly"),
|
||||
clEnumValN(bolt::BinaryFunction::RT_USER,
|
||||
"user",
|
||||
"use function order specified by -function-order"),
|
||||
clEnumValEnd),
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
ReorderFunctionsUseHotSize("reorder-functions-use-hot-size",
|
||||
cl::desc("use a function's hot size when doing clustering"),
|
||||
cl::init(true),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
enum SctcModes : char {
|
||||
SctcAlways,
|
||||
|
@ -175,80 +234,27 @@ enum SctcModes : char {
|
|||
};
|
||||
|
||||
static cl::opt<SctcModes>
|
||||
SctcMode(
|
||||
"sctc-mode",
|
||||
cl::desc("mode for simplify conditional tail calls"),
|
||||
cl::init(SctcHeuristic),
|
||||
cl::values(clEnumValN(SctcAlways, "always", "always perform sctc"),
|
||||
clEnumValN(SctcPreserveDirection,
|
||||
"preserve",
|
||||
"only perform sctc when branch direction is "
|
||||
"preserved"),
|
||||
clEnumValN(SctcHeuristic,
|
||||
"heuristic",
|
||||
"use branch prediction data to control sctc"),
|
||||
clEnumValEnd),
|
||||
cl::ZeroOrMore);
|
||||
SctcMode("sctc-mode",
|
||||
cl::desc("mode for simplify conditional tail calls"),
|
||||
cl::init(SctcHeuristic),
|
||||
cl::values(clEnumValN(SctcAlways, "always", "always perform sctc"),
|
||||
clEnumValN(SctcPreserveDirection,
|
||||
"preserve",
|
||||
"only perform sctc when branch direction is "
|
||||
"preserved"),
|
||||
clEnumValN(SctcHeuristic,
|
||||
"heuristic",
|
||||
"use branch prediction data to control sctc"),
|
||||
clEnumValEnd),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
IdenticalCodeFolding(
|
||||
"icf",
|
||||
cl::desc("fold functions with identical code"),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
UseDFSForICF(
|
||||
"icf-dfs",
|
||||
cl::desc("use DFS ordering when using -icf option"),
|
||||
cl::ReallyHidden,
|
||||
cl::ZeroOrMore);
|
||||
|
||||
cl::opt<bolt::BinaryFunction::ReorderType>
|
||||
ReorderFunctions(
|
||||
"reorder-functions",
|
||||
cl::desc("reorder and cluster functions (works only with relocations)"),
|
||||
cl::init(bolt::BinaryFunction::RT_NONE),
|
||||
cl::values(clEnumValN(bolt::BinaryFunction::RT_NONE,
|
||||
"none",
|
||||
"do not reorder functions"),
|
||||
clEnumValN(bolt::BinaryFunction::RT_EXEC_COUNT,
|
||||
"exec-count",
|
||||
"order by execution count"),
|
||||
clEnumValN(bolt::BinaryFunction::RT_HFSORT,
|
||||
"hfsort",
|
||||
"use hfsort algorithm"),
|
||||
clEnumValN(bolt::BinaryFunction::RT_HFSORT_PLUS,
|
||||
"hfsort+",
|
||||
"use hfsort+ algorithm"),
|
||||
clEnumValN(bolt::BinaryFunction::RT_PETTIS_HANSEN,
|
||||
"pettis-hansen",
|
||||
"use Pettis-Hansen algorithm"),
|
||||
clEnumValN(bolt::BinaryFunction::RT_RANDOM,
|
||||
"random",
|
||||
"reorder functions randomly"),
|
||||
clEnumValN(bolt::BinaryFunction::RT_USER,
|
||||
"user",
|
||||
"use function order specified by -function-order"),
|
||||
clEnumValEnd));
|
||||
|
||||
static cl::opt<std::string>
|
||||
FunctionOrderFile("function-order",
|
||||
cl::desc("file containing an ordered list of functions to use"
|
||||
" for function reordering"));
|
||||
|
||||
static cl::opt<bool>
|
||||
ReorderFunctionsUseHotSize(
|
||||
"reorder-functions-use-hot-size",
|
||||
cl::desc("use a function's hot size when doing clustering"),
|
||||
cl::init(true),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
UseEdgeCounts(
|
||||
"use-edge-counts",
|
||||
cl::desc("use edge count data when doing clustering"),
|
||||
cl::init(true),
|
||||
cl::ZeroOrMore);
|
||||
UseEdgeCounts("use-edge-counts",
|
||||
cl::desc("use edge count data when doing clustering"),
|
||||
cl::init(true),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
} // namespace opts
|
||||
|
||||
|
@ -848,7 +854,7 @@ void SimplifyRODataLoads::runOnFunctions(
|
|||
void IdenticalCodeFolding::runOnFunctions(BinaryContext &BC,
|
||||
std::map<uint64_t, BinaryFunction> &BFs,
|
||||
std::set<uint64_t> &) {
|
||||
if (!opts::IdenticalCodeFolding)
|
||||
if (!opts::ICF)
|
||||
return;
|
||||
|
||||
const auto OriginalFunctionCount = BFs.size();
|
||||
|
@ -856,7 +862,7 @@ void IdenticalCodeFolding::runOnFunctions(BinaryContext &BC,
|
|||
uint64_t NumJTFunctionsFolded = 0;
|
||||
uint64_t BytesSavedEstimate = 0;
|
||||
uint64_t CallsSavedEstimate = 0;
|
||||
static bool UseDFS = opts::UseDFSForICF;
|
||||
static bool UseDFS = opts::ICFUseDFS;
|
||||
|
||||
// This hash table is used to identify identical functions. It maps
|
||||
// a function to a bucket of functions identical to it.
|
||||
|
|
|
@ -17,19 +17,23 @@
|
|||
using namespace llvm;
|
||||
|
||||
namespace opts {
|
||||
static cl::list<std::string>
|
||||
ForceInlineFunctions("force-inline",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to always consider "
|
||||
"for inlining"),
|
||||
cl::value_desc("func1,func2,func3,..."),
|
||||
cl::Hidden);
|
||||
|
||||
extern cl::OptionCategory BoltOptCategory;
|
||||
|
||||
static cl::opt<bool>
|
||||
AggressiveInlining("aggressive-inlining",
|
||||
cl::desc("perform aggressive inlining"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
cl::desc("perform aggressive inlining"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::list<std::string>
|
||||
ForceInlineFunctions("force-inline",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to always consider for inlining"),
|
||||
cl::value_desc("func1,func2,func3,..."),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -26,14 +26,22 @@ using namespace bolt;
|
|||
|
||||
namespace opts {
|
||||
|
||||
extern cl::OptionCategory BoltOptCategory;
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintClusters("print-clusters", cl::desc("print clusters"), cl::ZeroOrMore);
|
||||
PrintClusters("print-clusters",
|
||||
cl::desc("print clusters"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
cl::opt<uint32_t>
|
||||
RandomSeed("bolt-seed",
|
||||
cl::desc("seed for randomization"),
|
||||
cl::init(42),
|
||||
cl::ZeroOrMore);
|
||||
cl::desc("seed for randomization"),
|
||||
cl::init(42),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
} // namespace opts
|
||||
|
||||
|
|
|
@ -66,11 +66,232 @@ using namespace bolt;
|
|||
|
||||
namespace opts {
|
||||
|
||||
extern cl::OptionCategory BoltCategory;
|
||||
extern cl::OptionCategory BoltOptCategory;
|
||||
|
||||
extern cl::opt<JumpTableSupportLevel> JumpTables;
|
||||
extern cl::opt<BinaryFunction::ReorderType> ReorderFunctions;
|
||||
|
||||
static cl::opt<std::string>
|
||||
OutputFilename("o", cl::desc("<output file>"), cl::Required);
|
||||
OutputFilename("o",
|
||||
cl::desc("<output file>"),
|
||||
cl::Required,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<unsigned>
|
||||
AlignFunctions("align-functions",
|
||||
cl::desc("align functions at a given value (relocation mode)"),
|
||||
cl::init(64),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<unsigned>
|
||||
AlignFunctionsMaxBytes("align-functions-max-bytes",
|
||||
cl::desc("maximum number of bytes to use to align functions"),
|
||||
cl::init(7),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
AllowStripped("allow-stripped",
|
||||
cl::desc("allow processing of stripped binaries"),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
BoostMacroops("boost-macroops",
|
||||
cl::desc("try to boost macro-op fusions by avoiding the cache-line boundary"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::list<std::string>
|
||||
BreakFunctionNames("break-funcs",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to core dump on (debugging)"),
|
||||
cl::value_desc("func1,func2,func3,..."),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
DumpDotAll("dump-dot-all",
|
||||
cl::desc("dump function CFGs to graphviz format after each stage"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
DumpEHFrame("dump-eh-frame",
|
||||
cl::desc("dump parsed .eh_frame (debugging)"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
DynoStatsAll("dyno-stats-all",
|
||||
cl::desc("print dyno stats after each stage"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
FixDebugInfoLargeFunctions("fix-debuginfo-large-functions",
|
||||
cl::init(true),
|
||||
cl::desc("do another pass if we encounter large functions, to correct their "
|
||||
"debug info."),
|
||||
cl::ZeroOrMore,
|
||||
cl::ReallyHidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::list<std::string>
|
||||
FunctionNames("funcs",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to optimize"),
|
||||
cl::value_desc("func1,func2,func3,..."),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<std::string>
|
||||
FunctionNamesFile("funcs-file",
|
||||
cl::desc("file with list of functions to optimize"),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::list<std::string>
|
||||
FunctionPadSpec("pad-funcs",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to pad with amount of bytes"),
|
||||
cl::value_desc("func1:pad1,func2:pad2,func3:pad3,..."),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
HotText("hot-text",
|
||||
cl::desc("hot text symbols support (relocation mode)"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
KeepTmp("keep-tmp",
|
||||
cl::desc("preserve intermediate .o file"),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
MarkFuncs("mark-funcs",
|
||||
cl::desc("mark function boundaries with break instruction to make "
|
||||
"sure we accidentally don't cross them"),
|
||||
cl::ReallyHidden,
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<unsigned>
|
||||
MaxFunctions("max-funcs",
|
||||
cl::desc("maximum number of functions to overwrite"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
PrintAll("print-all",
|
||||
cl::desc("print functions after each stage"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintCFG("print-cfg",
|
||||
cl::desc("print functions after CFG construction"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintDisasm("print-disasm",
|
||||
cl::desc("print function after disassembly"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
PrintDynoStats("dyno-stats",
|
||||
cl::desc("print execution info based on profile"),
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintLoopInfo("print-loops",
|
||||
cl::desc("print loop related information"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
Relocs("relocs",
|
||||
cl::desc("relocation mode - use relocations to move functions in the binary"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::list<std::string>
|
||||
SkipFunctionNames("skip-funcs",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to skip"),
|
||||
cl::value_desc("func1,func2,func3,..."),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<std::string>
|
||||
SkipFunctionNamesFile("skip-funcs-file",
|
||||
cl::desc("file with list of functions to skip"),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<BinaryFunction::SplittingType>
|
||||
SplitFunctions("split-functions",
|
||||
cl::desc("split functions into hot and cold regions"),
|
||||
cl::init(BinaryFunction::ST_NONE),
|
||||
cl::values(clEnumValN(BinaryFunction::ST_NONE, "0",
|
||||
"do not split any function"),
|
||||
clEnumValN(BinaryFunction::ST_EH, "1",
|
||||
"split all landing pads"),
|
||||
clEnumValN(BinaryFunction::ST_LARGE, "2",
|
||||
"also split if function too large to fit"),
|
||||
clEnumValN(BinaryFunction::ST_ALL, "3",
|
||||
"split all functions"),
|
||||
clEnumValEnd),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltOptCategory));
|
||||
|
||||
static cl::opt<unsigned>
|
||||
TopCalledLimit("top-called-limit",
|
||||
cl::desc("maximum number of functions to print in top called "
|
||||
"functions section"),
|
||||
cl::init(100),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
TrapOldCode("trap-old-code",
|
||||
cl::desc("insert traps in old function bodies (relocation mode)"),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
UpdateDebugSections("update-debug-sections",
|
||||
cl::desc("update DWARF debug sections of the executable"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
UseGnuStack("use-gnu-stack",
|
||||
cl::desc("use GNU_STACK program header for new segment (workaround for "
|
||||
"issues with strip/objcopy)"),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
cl::opt<bool>
|
||||
UseOldText("use-old-text",
|
||||
cl::desc("re-use space in old .text if possible (relocation mode)"),
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
// The default verbosity level (0) is pretty terse, level 1 is fairly
|
||||
// verbose and usually prints some informational message for every
|
||||
|
@ -85,181 +306,10 @@ OutputFilename("o", cl::desc("<output file>"), cl::Required);
|
|||
// dbgs() for output within DEBUG().
|
||||
cl::opt<unsigned>
|
||||
Verbosity("v",
|
||||
cl::desc("set verbosity level for diagnostic output"),
|
||||
cl::init(0),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<unsigned>
|
||||
AlignFunctions("align-functions",
|
||||
cl::desc("align functions at a given value"),
|
||||
cl::init(64),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<unsigned>
|
||||
AlignFunctionsMaxBytes("align-functions-max-bytes",
|
||||
cl::desc("maximum number of bytes to use to align functions"),
|
||||
cl::init(7),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::list<std::string>
|
||||
BreakFunctionNames("break-funcs",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to core dump on (debugging)"),
|
||||
cl::value_desc("func1,func2,func3,..."),
|
||||
cl::Hidden);
|
||||
|
||||
cl::opt<bool>
|
||||
UseOldText("use-old-text",
|
||||
cl::desc("re-use space in old .text if possible"),
|
||||
cl::Hidden);
|
||||
|
||||
cl::opt<bool>
|
||||
TrapOldCode("trap-old-code",
|
||||
cl::desc("insert traps in old function bodies"),
|
||||
cl::Hidden);
|
||||
|
||||
cl::opt<bool>
|
||||
PrintDynoStats("dyno-stats",
|
||||
cl::desc("print execution info based on profile"));
|
||||
|
||||
cl::opt<bool>
|
||||
DynoStatsAll("dyno-stats-all", cl::desc("print dyno stats after each stage"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<unsigned>
|
||||
TopCalledLimit("top-called-limit",
|
||||
cl::desc("maximum number of functions to print in top called "
|
||||
"functions section"),
|
||||
cl::init(100),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
cl::opt<bool>
|
||||
HotText("hot-text",
|
||||
cl::desc("hot text symbols support"),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::list<std::string>
|
||||
FunctionNames("funcs",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to optimize"),
|
||||
cl::value_desc("func1,func2,func3,..."));
|
||||
|
||||
static cl::opt<std::string>
|
||||
FunctionNamesFile("funcs-file",
|
||||
cl::desc("file with list of functions to optimize"));
|
||||
|
||||
cl::opt<bool>
|
||||
Relocs("relocs",
|
||||
cl::desc("relocation support (experimental)"),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::list<std::string>
|
||||
FunctionPadSpec("pad-funcs",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to pad with amount of bytes"),
|
||||
cl::value_desc("func1:pad1,func2:pad2,func3:pad3,..."));
|
||||
|
||||
static cl::list<std::string>
|
||||
SkipFunctionNames("skip-funcs",
|
||||
cl::CommaSeparated,
|
||||
cl::desc("list of functions to skip"),
|
||||
cl::value_desc("func1,func2,func3,..."));
|
||||
|
||||
static cl::opt<std::string>
|
||||
SkipFunctionNamesFile("skip-funcs-file",
|
||||
cl::desc("file with list of functions to skip"));
|
||||
static cl::opt<bool>
|
||||
MarkFuncs("mark-funcs",
|
||||
cl::desc("mark function boundaries with break instruction to make "
|
||||
"sure we accidentally don't cross them"),
|
||||
cl::ReallyHidden,
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<unsigned>
|
||||
MaxFunctions("max-funcs",
|
||||
cl::desc("maximum # of functions to overwrite"),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
cl::opt<BinaryFunction::SplittingType>
|
||||
SplitFunctions("split-functions",
|
||||
cl::desc("split functions into hot and cold regions"),
|
||||
cl::init(BinaryFunction::ST_NONE),
|
||||
cl::values(clEnumValN(BinaryFunction::ST_NONE, "0",
|
||||
"do not split any function"),
|
||||
clEnumValN(BinaryFunction::ST_EH, "1",
|
||||
"split all landing pads"),
|
||||
clEnumValN(BinaryFunction::ST_LARGE, "2",
|
||||
"also split if function too large to fit"),
|
||||
clEnumValN(BinaryFunction::ST_ALL, "3",
|
||||
"split all functions"),
|
||||
clEnumValEnd),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
cl::opt<bool>
|
||||
UpdateDebugSections("update-debug-sections",
|
||||
cl::desc("update DWARF debug sections of the executable"),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
FixDebugInfoLargeFunctions("fix-debuginfo-large-functions",
|
||||
cl::init(true),
|
||||
cl::desc("do another pass if we encounter large "
|
||||
"functions, to correct their debug info."),
|
||||
cl::ZeroOrMore,
|
||||
cl::ReallyHidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
AlignBlocks("align-blocks",
|
||||
cl::desc("try to align BBs inserting nops"),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
UseGnuStack("use-gnu-stack",
|
||||
cl::desc("use GNU_STACK program header for new segment"),
|
||||
cl::ZeroOrMore);
|
||||
|
||||
static cl::opt<bool>
|
||||
DumpEHFrame("dump-eh-frame", cl::desc("dump parsed .eh_frame (debugging)"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
cl::opt<bool>
|
||||
PrintAll("print-all", cl::desc("print functions after each stage"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
cl::opt<bool>
|
||||
DumpDotAll("dump-dot-all",
|
||||
cl::desc("dump function CFGs to graphviz format after each stage"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintCFG("print-cfg", cl::desc("print functions after CFG construction"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintLoopInfo("print-loops", cl::desc("print loop related information"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
PrintDisasm("print-disasm", cl::desc("print function after disassembly"),
|
||||
cl::ZeroOrMore,
|
||||
cl::Hidden);
|
||||
|
||||
static cl::opt<bool>
|
||||
KeepTmp("keep-tmp",
|
||||
cl::desc("preserve intermediate .o file"),
|
||||
cl::Hidden);
|
||||
|
||||
cl::opt<bool>
|
||||
AllowStripped("allow-stripped",
|
||||
cl::desc("allow processing of stripped binaries"),
|
||||
cl::Hidden);
|
||||
cl::desc("set verbosity level for diagnostic output"),
|
||||
cl::init(0),
|
||||
cl::ZeroOrMore,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
// Check against lists of functions from options if we should
|
||||
// optimize the function with a given name.
|
||||
|
|
|
@ -32,15 +32,32 @@ using namespace bolt;
|
|||
|
||||
namespace opts {
|
||||
|
||||
static cl::opt<std::string>
|
||||
InputFilename(cl::Positional, cl::desc("<executable>"), cl::Required);
|
||||
cl::OptionCategory BoltCategory("BOLT generic options");
|
||||
cl::OptionCategory BoltOptCategory("BOLT optimization options");
|
||||
cl::OptionCategory BoltRelocCategory("BOLT options in relocation mode");
|
||||
|
||||
static cl::opt<std::string>
|
||||
InputDataFilename("data", cl::desc("<data file>"), cl::Optional);
|
||||
static cl::OptionCategory *BoltCategories[] = {&BoltCategory,
|
||||
&BoltOptCategory,
|
||||
&BoltRelocCategory};
|
||||
|
||||
static cl::opt<bool>
|
||||
DumpData("dump-data", cl::desc("dump parsed bolt data and exit (debugging)"),
|
||||
cl::Hidden);
|
||||
DumpData("dump-data",
|
||||
cl::desc("dump parsed bolt data and exit (debugging)"),
|
||||
cl::Hidden,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<std::string>
|
||||
InputDataFilename("data",
|
||||
cl::desc("<data file>"),
|
||||
cl::Optional,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
static cl::opt<std::string>
|
||||
InputFilename(
|
||||
cl::Positional,
|
||||
cl::desc("<executable>"),
|
||||
cl::Required,
|
||||
cl::cat(BoltCategory));
|
||||
|
||||
} // namespace opts
|
||||
|
||||
|
@ -68,6 +85,8 @@ int main(int argc, char **argv) {
|
|||
llvm::InitializeAllTargets();
|
||||
llvm::InitializeAllAsmPrinters();
|
||||
|
||||
cl::HideUnrelatedOptions(makeArrayRef(opts::BoltCategories));
|
||||
|
||||
// Register the target printer for --version.
|
||||
cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@ using namespace bolt;
|
|||
|
||||
namespace opts {
|
||||
|
||||
cl::OptionCategory MergeFdataCategory("merge-fdata options");
|
||||
|
||||
enum SortType : char {
|
||||
ST_NONE,
|
||||
ST_EXEC_COUNT, /// Sort based on function execution count.
|
||||
|
@ -34,32 +36,35 @@ enum SortType : char {
|
|||
};
|
||||
|
||||
static cl::list<std::string>
|
||||
InputDataFilenames(cl::Positional,
|
||||
cl::CommaSeparated,
|
||||
cl::desc("<fdata1> [<fdata2>]..."),
|
||||
cl::OneOrMore);
|
||||
InputDataFilenames(
|
||||
cl::Positional,
|
||||
cl::CommaSeparated,
|
||||
cl::desc("<fdata1> [<fdata2>]..."),
|
||||
cl::OneOrMore,
|
||||
cl::cat(MergeFdataCategory));
|
||||
|
||||
static cl::opt<SortType>
|
||||
PrintFunctionList("print",
|
||||
cl::desc("print the list of objects with count to stderr"),
|
||||
cl::init(ST_NONE),
|
||||
cl::values(clEnumValN(ST_NONE,
|
||||
"none",
|
||||
"do not print objects/functions"),
|
||||
clEnumValN(ST_EXEC_COUNT,
|
||||
"exec",
|
||||
"print functions sorted by execution count"),
|
||||
clEnumValN(ST_TOTAL_BRANCHES,
|
||||
"branches",
|
||||
"print functions sorted by total branch count"),
|
||||
clEnumValEnd),
|
||||
cl::cat(MergeFdataCategory));
|
||||
|
||||
static cl::opt<bool>
|
||||
SuppressMergedDataOutput("q",
|
||||
cl::desc("do not print merged data to stdout"),
|
||||
cl::init(false),
|
||||
cl::Optional);
|
||||
|
||||
static cl::opt<SortType>
|
||||
PrintFunctionList(
|
||||
"print",
|
||||
cl::desc("print the list of objects with count to stderr"),
|
||||
cl::init(ST_NONE),
|
||||
cl::values(clEnumValN(ST_NONE,
|
||||
"none",
|
||||
"do not print objects/functions"),
|
||||
clEnumValN(ST_EXEC_COUNT,
|
||||
"exec",
|
||||
"print functions sorted by execution count"),
|
||||
clEnumValN(ST_TOTAL_BRANCHES,
|
||||
"branches",
|
||||
"print functions sorted by total branch count"),
|
||||
clEnumValEnd));
|
||||
cl::desc("do not print merged data to stdout"),
|
||||
cl::init(false),
|
||||
cl::Optional,
|
||||
cl::cat(MergeFdataCategory));
|
||||
|
||||
} // namespace opts
|
||||
|
||||
|
@ -78,6 +83,8 @@ int main(int argc, char **argv) {
|
|||
|
||||
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
|
||||
|
||||
cl::HideUnrelatedOptions(opts::MergeFdataCategory);
|
||||
|
||||
cl::ParseCommandLineOptions(argc, argv,
|
||||
"merge fdata into a single file");
|
||||
|
||||
|
|
Loading…
Reference in New Issue