[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:
Maksim Panchenko
2016-06-09 17:45:15 -07:00
parent 980a06265a
commit 88ac5d9d0e

View File

@@ -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();