Skip to content

Commit 5e6d5c0

Browse files
[mlir] Add --list-passes option to mlir-opt (#100420)
Currently, the only way to see the passes that were registered is by calling “mlir-opt --help”. However, for compilers with 500+ passes, the help message becomes too long and sometimes hard to understand. In this PR I add a new "--list-passes" option to mlir-opt, which can be used for printing only the registered passes, a feature that would be extremely useful.
1 parent 07b29fc commit 5e6d5c0

File tree

4 files changed

+55
-0
lines changed

4 files changed

+55
-0
lines changed

mlir/include/mlir/Pass/PassRegistry.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ using PassAllocatorFunction = std::function<std::unique_ptr<Pass>()>;
4444
// PassRegistry
4545
//===----------------------------------------------------------------------===//
4646

47+
/// Prints the passes that were previously registered and stored in passRegistry
48+
void printRegisteredPasses();
49+
4750
/// Structure to group information about a passes and pass pipelines (argument
4851
/// to invoke via mlir-opt, description, pass pipeline builder).
4952
class PassRegistryEntry {

mlir/include/mlir/Tools/mlir-opt/MlirOptMain.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,13 @@ class MlirOptMainConfig {
119119
return success();
120120
}
121121

122+
/// List the registered passes and return.
123+
MlirOptMainConfig &listPasses(bool list) {
124+
listPassesFlag = list;
125+
return *this;
126+
}
127+
bool shouldListPasses() const { return listPassesFlag; }
128+
122129
/// Enable running the reproducer information stored in resources (if
123130
/// present).
124131
MlirOptMainConfig &runReproducer(bool enableReproducer) {
@@ -219,6 +226,9 @@ class MlirOptMainConfig {
219226
/// The callback to populate the pass manager.
220227
std::function<LogicalResult(PassManager &)> passPipelineCallback;
221228

229+
/// List the registered passes and return.
230+
bool listPassesFlag = false;
231+
222232
/// Enable running the reproducer.
223233
bool runReproducerFlag = false;
224234

mlir/lib/Pass/PassRegistry.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,32 @@ static void printOptionHelp(StringRef arg, StringRef desc, size_t indent,
6868
// PassRegistry
6969
//===----------------------------------------------------------------------===//
7070

71+
/// Prints the passes that were previously registered and stored in passRegistry
72+
void mlir::printRegisteredPasses() {
73+
size_t maxWidth = 0;
74+
for (auto &entry : *passRegistry)
75+
maxWidth = std::max(maxWidth, entry.second.getOptionWidth() + 4);
76+
77+
// Functor used to print the ordered entries of a registration map.
78+
auto printOrderedEntries = [&](StringRef header, auto &map) {
79+
llvm::SmallVector<PassRegistryEntry *, 32> orderedEntries;
80+
for (auto &kv : map)
81+
orderedEntries.push_back(&kv.second);
82+
llvm::array_pod_sort(
83+
orderedEntries.begin(), orderedEntries.end(),
84+
[](PassRegistryEntry *const *lhs, PassRegistryEntry *const *rhs) {
85+
return (*lhs)->getPassArgument().compare((*rhs)->getPassArgument());
86+
});
87+
88+
llvm::outs().indent(0) << header << ":\n";
89+
for (PassRegistryEntry *entry : orderedEntries)
90+
entry->printHelpStr(/*indent=*/2, maxWidth);
91+
};
92+
93+
// Print the available passes.
94+
printOrderedEntries("Passes", *passRegistry);
95+
}
96+
7197
/// Print the help information for this pass. This includes the argument,
7298
/// description, and any pass options. `descIndent` is the indent that the
7399
/// descriptions should be aligned.

mlir/lib/Tools/mlir-opt/MlirOptMain.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "mlir/Parser/Parser.h"
3131
#include "mlir/Pass/Pass.h"
3232
#include "mlir/Pass/PassManager.h"
33+
#include "mlir/Pass/PassRegistry.h"
3334
#include "mlir/Support/FileUtilities.h"
3435
#include "mlir/Support/Timing.h"
3536
#include "mlir/Support/ToolUtilities.h"
@@ -118,6 +119,10 @@ struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
118119
"parsing"),
119120
cl::location(useExplicitModuleFlag), cl::init(false));
120121

122+
static cl::opt<bool, /*ExternalStorage=*/true> listPasses(
123+
"list-passes", cl::desc("Print the list of registered passes and exit"),
124+
cl::location(listPassesFlag), cl::init(false));
125+
121126
static cl::opt<bool, /*ExternalStorage=*/true> runReproducer(
122127
"run-reproducer", cl::desc("Run the pipeline stored in the reproducer"),
123128
cl::location(runReproducerFlag), cl::init(false));
@@ -522,13 +527,21 @@ static LogicalResult printRegisteredDialects(DialectRegistry &registry) {
522527
return success();
523528
}
524529

530+
static LogicalResult printRegisteredPassesAndReturn() {
531+
mlir::printRegisteredPasses();
532+
return success();
533+
}
534+
525535
LogicalResult mlir::MlirOptMain(llvm::raw_ostream &outputStream,
526536
std::unique_ptr<llvm::MemoryBuffer> buffer,
527537
DialectRegistry &registry,
528538
const MlirOptMainConfig &config) {
529539
if (config.shouldShowDialects())
530540
return printRegisteredDialects(registry);
531541

542+
if (config.shouldListPasses())
543+
return printRegisteredPassesAndReturn();
544+
532545
// The split-input-file mode is a very specific mode that slices the file
533546
// up into small pieces and checks each independently.
534547
// We use an explicit threadpool to avoid creating and joining/destroying
@@ -565,6 +578,9 @@ LogicalResult mlir::MlirOptMain(int argc, char **argv,
565578
if (config.shouldShowDialects())
566579
return printRegisteredDialects(registry);
567580

581+
if (config.shouldListPasses())
582+
return printRegisteredPassesAndReturn();
583+
568584
// When reading from stdin and the input is a tty, it is often a user mistake
569585
// and the process "appears to be stuck". Print a message to let the user know
570586
// about it!

0 commit comments

Comments
 (0)