mirror of
https://github.com/intel/llvm.git
synced 2026-01-16 05:32:28 +08:00
[merge-fdata] Add option to print function list.
Summary:
Print total number of functions/objects that have profile
and add new options:
-print - print the list of objects with count to stderr
=none - do not print objects/functions
=exec - print functions sorted by execution count
=branches - print functions sorted by total branch count
-q - do not print merged data to stdout
(cherry picked from FBD3442288)
This commit is contained in:
@@ -27,12 +27,40 @@ using namespace bolt;
|
||||
|
||||
namespace opts {
|
||||
|
||||
enum SortType : char {
|
||||
ST_NONE,
|
||||
ST_EXEC_COUNT, /// Sort based on function execution count.
|
||||
ST_TOTAL_BRANCHES, /// Sort based on all branches in the function.
|
||||
};
|
||||
|
||||
static cl::list<std::string>
|
||||
InputDataFilenames(cl::Positional,
|
||||
cl::CommaSeparated,
|
||||
cl::desc("<fdata1> [<fdata2>]..."),
|
||||
cl::OneOrMore);
|
||||
|
||||
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));
|
||||
|
||||
} // namespace opts
|
||||
|
||||
static StringRef ToolName;
|
||||
@@ -98,6 +126,7 @@ int main(int argc, char **argv) {
|
||||
for (auto &FI : ReaderOrErr.get()->getAllFuncsData()) {
|
||||
auto MI = MergedFunctionsData.find(FI.second.Name);
|
||||
if (MI != MergedFunctionsData.end()) {
|
||||
MI->second.ExecutionCount += FI.second.ExecutionCount;
|
||||
std::vector<BranchInfo> TmpBI;
|
||||
for (auto &BI : FI.second.Data) {
|
||||
// Find and merge a corresponding entry or copy data.
|
||||
@@ -132,6 +161,7 @@ int main(int argc, char **argv) {
|
||||
std::make_pair(*NamePtr,
|
||||
FuncBranchData(*NamePtr,
|
||||
FuncBranchData::ContainerTy())));
|
||||
MI->second.ExecutionCount = FI.second.ExecutionCount;
|
||||
// Copy with string conversion while eliminating duplicates.
|
||||
std::sort(FI.second.Data.begin(), FI.second.Data.end());
|
||||
BranchInfo *PrevBI = nullptr;
|
||||
@@ -148,18 +178,59 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
|
||||
// Print all the data in the original format
|
||||
for (auto &FDI : MergedFunctionsData) {
|
||||
for (auto &BD : FDI.second.Data) {
|
||||
outs() << BD.From.IsSymbol << " " << FDI.first() << " "
|
||||
<< Twine::utohexstr(BD.From.Offset) << " "
|
||||
<< BD.To.IsSymbol << " " << BD.To.Name << " "
|
||||
<< Twine::utohexstr(BD.To.Offset) << " "
|
||||
<< BD.Mispreds << " " << BD.Branches << '\n';
|
||||
if (!opts::SuppressMergedDataOutput) {
|
||||
// Print all the data in the original format
|
||||
for (auto &FDI : MergedFunctionsData) {
|
||||
for (auto &BD : FDI.second.Data) {
|
||||
outs() << BD.From.IsSymbol << " " << FDI.first() << " "
|
||||
<< Twine::utohexstr(BD.From.Offset) << " "
|
||||
<< BD.To.IsSymbol << " " << BD.To.Name << " "
|
||||
<< Twine::utohexstr(BD.To.Offset) << " "
|
||||
<< BD.Mispreds << " " << BD.Branches << '\n';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
errs() << "All data merged successfully.\n";
|
||||
errs() << "Data for " << MergedFunctionsData.size()
|
||||
<< " unique objects successfully merged.\n";
|
||||
|
||||
if (opts::PrintFunctionList != opts::ST_NONE) {
|
||||
// List of function names with execution count.
|
||||
std::vector<std::pair<uint64_t, StringRef>>
|
||||
FunctionList(MergedFunctionsData.size());
|
||||
using CountFuncType =
|
||||
std::function<std::pair<uint64_t,StringRef>(
|
||||
const StringMapEntry<FuncBranchData>&)>;
|
||||
CountFuncType ExecCountFunc = [](const StringMapEntry<FuncBranchData> &v) {
|
||||
return std::make_pair(v.second.ExecutionCount,
|
||||
v.second.Name);
|
||||
};
|
||||
CountFuncType BranchCountFunc = [](const StringMapEntry<FuncBranchData> &v){
|
||||
// Return total branch count.
|
||||
uint64_t BranchCount = 0;
|
||||
for (const auto &BI : v.second.Data)
|
||||
BranchCount += BI.Branches;
|
||||
return std::make_pair(BranchCount,
|
||||
v.second.Name);
|
||||
};
|
||||
|
||||
CountFuncType CountFunc = (opts::PrintFunctionList == opts::ST_EXEC_COUNT)
|
||||
? ExecCountFunc
|
||||
: BranchCountFunc;
|
||||
std::transform(MergedFunctionsData.begin(),
|
||||
MergedFunctionsData.end(),
|
||||
FunctionList.begin(),
|
||||
CountFunc);
|
||||
std::stable_sort(FunctionList.rbegin(), FunctionList.rend());
|
||||
errs() << "Functions sorted by "
|
||||
<< (opts::PrintFunctionList == opts::ST_EXEC_COUNT
|
||||
? "execution"
|
||||
: "total branch")
|
||||
<< " count:\n";
|
||||
for (auto &FI : FunctionList) {
|
||||
errs() << FI.second << " : " << FI.first << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
AllStrings.clear();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user