11#include "llvm/ADT/StringExtras.h"
12#include "llvm/Support/Format.h"
18 "... Pass statistics report ...";
23 const char *name, *desc;
31 os.indent(indent) << pass <<
"\n";
37 stats.begin(), stats.end(), [](
const auto *lhs,
const auto *rhs) {
38 return StringRef{lhs->name}.compare(StringRef{rhs->name});
42 size_t largestName = 0, largestValue = 0;
43 for (
auto &stat : stats) {
44 largestName = std::max(largestName, (
size_t)strlen(stat.name));
46 std::max(largestValue, (
size_t)llvm::utostr(stat.value).size());
50 for (
auto &stat : stats) {
51 os.indent(indent + 2) << llvm::format(
"(S) %*u %-*s - %s\n", largestValue,
52 stat.value, largestName, stat.name,
60 llvm::StringMap<std::vector<Statistic>> mergedStats;
62 auto *adaptor = dyn_cast<OpToOpPassAdaptor>(pass);
67 auto statistics = pass->getStatistics();
68 if (statistics.empty())
71 auto &passEntry = mergedStats[pass->getName()];
72 if (passEntry.empty()) {
74 passEntry.push_back({it->getName(), it->getDesc(), it->getValue()});
76 for (
auto [idx, statistic] : llvm::enumerate(pass->getStatistics()))
77 passEntry[idx].value += statistic->getValue();
84 for (
auto &mgr : adaptor->getPassManagers())
85 for (
Pass &pass : mgr.getPasses())
92 auto passAndStatistics =
93 llvm::to_vector<16>(llvm::make_pointer_range(mergedStats));
94 llvm::array_pod_sort(passAndStatistics.begin(), passAndStatistics.end(),
95 [](
const decltype(passAndStatistics)::value_type *lhs,
96 const decltype(passAndStatistics)::value_type *rhs) {
97 return (*lhs)->getKey().compare((*rhs)->getKey());
101 for (
auto &statData : passAndStatistics)
109 std::function<
void(
unsigned,
Pass *)> printPass = [&](
unsigned indent,
111 if (
auto *adaptor = dyn_cast<OpToOpPassAdaptor>(pass)) {
114 auto mgrs = adaptor->getPassManagers();
115 if (mgrs.size() > 1) {
122 auto name = (
"'" + mgr.getOpAnchorName() +
"' Pipeline").str();
124 for (
Pass &pass : mgr.getPasses())
125 printPass(indent + 2, &pass);
131 std::vector<Statistic> stats;
133 stats.push_back({stat->getName(), stat->getDesc(), stat->getValue()});
142 auto os = llvm::CreateInfoOutputFile();
145 *os <<
"===" << std::string(73,
'-') <<
"===\n";
149 *os <<
"===" << std::string(73,
'-') <<
"===\n";
152 switch (displayMode) {
169 const char *description)
181 owner->statistics.push_back(
this);
185 llvm::Statistic::operator=(value);
197 for (
auto passPair : llvm::zip(passes, otherPasses)) {
198 Pass &pass = std::get<0>(passPair), &otherPass = std::get<1>(passPair);
201 if (
auto *adaptorPass = dyn_cast<OpToOpPassAdaptor>(&pass)) {
202 auto *otherAdaptorPass = cast<OpToOpPassAdaptor>(&otherPass);
203 for (
auto mgrs : llvm::zip(adaptorPass->getPassManagers(),
204 otherAdaptorPass->getPassManagers()))
205 std::get<0>(mgrs).mergeStatisticsInto(std::get<1>(mgrs));
209 assert(pass.statistics.size() == otherPass.statistics.size());
210 for (
unsigned i = 0, e = pass.statistics.size(); i != e; ++i) {
211 assert(pass.statistics[i]->getName() ==
212 StringRef(otherPass.statistics[i]->getName()));
213 *otherPass.statistics[i] += *pass.statistics[i];
214 *pass.statistics[i] = 0;
223 llvm::make_isa_range<OpToOpPassAdaptor>(pm.
getPasses())) {
228 for (
auto &asyncPM : adaptor.getParallelPassManagers()) {
229 for (
unsigned i = 0, e = asyncPM.size(); i != e; ++i) {
231 asyncPM[i].mergeStatisticsInto(nestedPms[i]);
242void PassManager::dumpStatistics() {
249 passStatisticsMode = displayMode;
static void printResultsAsList(raw_ostream &os, OpPassManager &pm)
Print the statistics results in a list form, where each pass is sorted by name.
static void printResultsAsPipeline(raw_ostream &os, OpPassManager &pm)
Print the results in pipeline mode that mirrors the internal pass manager structure.
static void printStatistics(OpPassManager &pm, PassDisplayMode displayMode)
static void printPassEntry(raw_ostream &os, unsigned indent, StringRef pass, MutableArrayRef< Statistic > stats={})
Utility to print a pass entry in the statistics output.
static void prepareStatistics(OpPassManager &pm)
Prepare the statistics of passes within the given pass manager for consumption(e.g.
constexpr StringLiteral kPassStatsDescription
This class represents a pass manager that runs passes on either a specific operation type,...
void mergeStatisticsInto(OpPassManager &other)
Merge the pass statistics of this class into 'other'.
OpPassManager(Nesting nesting=Nesting::Explicit)
Construct a new op-agnostic ("any") pass manager with the given operation type and nesting behavior.
iterator_range< pass_iterator > getPasses()
void enableStatistics(PassDisplayMode displayMode=PassDisplayMode::Pipeline)
Prompts the pass manager to print the statistics collected for each of the held passes after each cal...
This class represents a single pass statistic.
Statistic(Pass *owner, const char *name, const char *description)
The statistic is initialized by the pass owner, a name, and a description.
Statistic & operator=(unsigned value)
Assign the statistic to the given value.
The abstract base pass class.
Pass(TypeID passID, std::optional< StringRef > opName=std::nullopt)
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Include the generated interface declarations.
PassDisplayMode
An enum describing the different display modes for the information within the pass manager.