Expose a convenient registerCLOptions() for MlirOptMainConfig
This allows for downstream *-opt tools to stay always aligned with the options exposed by mlir-opt. It aligns the "generic" options with the more "components" ones like the pass manager options or the context options. Differential Revision: https://reviews.llvm.org/D144782
This commit is contained in:
@@ -34,8 +34,21 @@ class PassManager;
|
||||
/// This is intended to help building tools like mlir-opt by collecting the
|
||||
/// supported options.
|
||||
/// The API is fluent, and the options are sorted in alphabetical order below.
|
||||
/// The options can be exposed to the LLVM command line by registering them
|
||||
/// with `MlirOptMainConfig::registerCLOptions();` and creating a config using
|
||||
/// `auto config = MlirOptMainConfig::createFromCLOptions();`.
|
||||
class MlirOptMainConfig {
|
||||
public:
|
||||
/// Register the options as global LLVM command line options.
|
||||
static void registerCLOptions();
|
||||
|
||||
/// Create a new config with the default set from the CL options.
|
||||
static MlirOptMainConfig createFromCLOptions();
|
||||
|
||||
///
|
||||
/// Options.
|
||||
///
|
||||
|
||||
/// Allow operation with no registered dialects.
|
||||
/// This option is for convenience during testing only and discouraged in
|
||||
/// general.
|
||||
@@ -124,7 +137,7 @@ public:
|
||||
}
|
||||
bool shouldVerifyPasses() const { return verifyPassesFlag; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
/// Allow operation with no registered dialects.
|
||||
/// This option is for convenience during testing only and discouraged in
|
||||
/// general.
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FileUtilities.h"
|
||||
#include "llvm/Support/InitLLVM.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/Regex.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/StringSaver.h"
|
||||
@@ -40,6 +41,71 @@
|
||||
using namespace mlir;
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
/// This class is intended to manage the handling of command line options for
|
||||
/// creating a *-opt config. This is a singleton.
|
||||
struct MlirOptMainConfigCLOptions : public MlirOptMainConfig {
|
||||
MlirOptMainConfigCLOptions() {
|
||||
// These options are static but all uses ExternalStorage to initialize the
|
||||
// members of the parent class. This is unusual but since this class is a
|
||||
// singleton it basically attaches command line option to the singleton
|
||||
// members.
|
||||
|
||||
static cl::opt<bool, /*ExternalStorage=*/true> allowUnregisteredDialects(
|
||||
"allow-unregistered-dialect",
|
||||
cl::desc("Allow operation with no registered dialects"),
|
||||
cl::location(allowUnregisteredDialectsFlag), cl::init(false));
|
||||
|
||||
static cl::opt<bool, /*ExternalStorage=*/true> dumpPassPipeline(
|
||||
"dump-pass-pipeline", cl::desc("Print the pipeline that will be run"),
|
||||
cl::location(dumpPassPipelineFlag), cl::init(false));
|
||||
|
||||
static cl::opt<bool, /*ExternalStorage=*/true> emitBytecode(
|
||||
"emit-bytecode", cl::desc("Emit bytecode when generating output"),
|
||||
cl::location(emitBytecodeFlag), cl::init(false));
|
||||
|
||||
static cl::opt<bool, /*ExternalStorage=*/true> explicitModule(
|
||||
"no-implicit-module",
|
||||
cl::desc("Disable implicit addition of a top-level module op during "
|
||||
"parsing"),
|
||||
cl::location(useExplicitModuleFlag), cl::init(false));
|
||||
|
||||
static cl::opt<bool, /*ExternalStorage=*/true> showDialects(
|
||||
"show-dialects",
|
||||
cl::desc("Print the list of registered dialects and exit"),
|
||||
cl::location(showDialectsFlag), cl::init(false));
|
||||
|
||||
static cl::opt<bool, /*ExternalStorage=*/true> splitInputFile(
|
||||
"split-input-file",
|
||||
cl::desc("Split the input file into pieces and process each "
|
||||
"chunk independently"),
|
||||
cl::location(splitInputFileFlag), cl::init(false));
|
||||
|
||||
static cl::opt<bool, /*ExternalStorage=*/true> verifyDiagnostics(
|
||||
"verify-diagnostics",
|
||||
cl::desc("Check that emitted diagnostics match "
|
||||
"expected-* lines on the corresponding line"),
|
||||
cl::location(verifyDiagnosticsFlag), cl::init(false));
|
||||
|
||||
static cl::opt<bool, /*ExternalStorage=*/true> verifyPasses(
|
||||
"verify-each",
|
||||
cl::desc("Run the verifier after each transformation pass"),
|
||||
cl::location(verifyPassesFlag), cl::init(true));
|
||||
|
||||
static PassPipelineCLParser passPipeline("", "Compiler passes to run", "p");
|
||||
setPassPipelineParser(passPipeline);
|
||||
}
|
||||
};
|
||||
} // namespace
|
||||
|
||||
ManagedStatic<MlirOptMainConfigCLOptions> clOptionsConfig;
|
||||
|
||||
void MlirOptMainConfig::registerCLOptions() { *clOptionsConfig; }
|
||||
|
||||
MlirOptMainConfig MlirOptMainConfig::createFromCLOptions() {
|
||||
return *clOptionsConfig;
|
||||
}
|
||||
|
||||
MlirOptMainConfig &MlirOptMainConfig::setPassPipelineParser(
|
||||
const PassPipelineCLParser &passPipeline) {
|
||||
passPipelineCallback = [&](PassManager &pm) {
|
||||
@@ -171,6 +237,12 @@ LogicalResult mlir::MlirOptMain(llvm::raw_ostream &outputStream,
|
||||
std::unique_ptr<llvm::MemoryBuffer> buffer,
|
||||
DialectRegistry ®istry,
|
||||
const MlirOptMainConfig &config) {
|
||||
if (config.shouldShowDialects()) {
|
||||
llvm::outs() << "Available Dialects:\n";
|
||||
interleave(registry.getDialectNames(), llvm::outs(), "\n");
|
||||
llvm::outs() << "\n";
|
||||
}
|
||||
|
||||
// The split-input-file mode is a very specific mode that slices the file
|
||||
// up into small pieces and checks each independently.
|
||||
// We use an explicit threadpool to avoid creating and joining/destroying
|
||||
@@ -244,54 +316,15 @@ LogicalResult mlir::MlirOptMain(int argc, char **argv, llvm::StringRef toolName,
|
||||
cl::value_desc("filename"),
|
||||
cl::init("-"));
|
||||
|
||||
static cl::opt<bool> splitInputFile(
|
||||
"split-input-file",
|
||||
cl::desc("Split the input file into pieces and process each "
|
||||
"chunk independently"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> verifyDiagnostics(
|
||||
"verify-diagnostics",
|
||||
cl::desc("Check that emitted diagnostics match "
|
||||
"expected-* lines on the corresponding line"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> verifyPasses(
|
||||
"verify-each",
|
||||
cl::desc("Run the verifier after each transformation pass"),
|
||||
cl::init(true));
|
||||
|
||||
static cl::opt<bool> allowUnregisteredDialects(
|
||||
"allow-unregistered-dialect",
|
||||
cl::desc("Allow operation with no registered dialects (discouraged: testing only!)"), cl::init(false));
|
||||
|
||||
static cl::opt<bool> showDialects(
|
||||
"show-dialects", cl::desc("Print the list of registered dialects"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> emitBytecode(
|
||||
"emit-bytecode", cl::desc("Emit bytecode when generating output"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> explicitModule{
|
||||
"no-implicit-module",
|
||||
cl::desc(
|
||||
"Disable implicit addition of a top-level module op during parsing"),
|
||||
cl::init(false)};
|
||||
|
||||
static cl::opt<bool> dumpPassPipeline{
|
||||
"dump-pass-pipeline", cl::desc("Print the pipeline that will be run"),
|
||||
cl::init(false)};
|
||||
|
||||
InitLLVM y(argc, argv);
|
||||
|
||||
// Register any command line options.
|
||||
MlirOptMainConfig::registerCLOptions();
|
||||
registerAsmPrinterCLOptions();
|
||||
registerMLIRContextCLOptions();
|
||||
registerPassManagerCLOptions();
|
||||
registerDefaultTimingManagerCLOptions();
|
||||
DebugCounter::registerCLOptions();
|
||||
PassPipelineCLParser passPipeline("", "Compiler passes to run", "p");
|
||||
|
||||
// Build the list of dialects as a header for the --help message.
|
||||
std::string helpHeader = (toolName + "\nAvailable Dialects: ").str();
|
||||
@@ -302,14 +335,7 @@ LogicalResult mlir::MlirOptMain(int argc, char **argv, llvm::StringRef toolName,
|
||||
}
|
||||
// Parse pass names in main to ensure static initialization completed.
|
||||
cl::ParseCommandLineOptions(argc, argv, helpHeader);
|
||||
|
||||
if (showDialects) {
|
||||
llvm::outs() << "Available Dialects:\n";
|
||||
interleave(
|
||||
registry.getDialectNames(), llvm::outs(),
|
||||
[](auto name) { llvm::outs() << name; }, "\n");
|
||||
return success();
|
||||
}
|
||||
MlirOptMainConfig config = MlirOptMainConfig::createFromCLOptions();
|
||||
|
||||
// Set up the input file.
|
||||
std::string errorMessage;
|
||||
@@ -324,18 +350,6 @@ LogicalResult mlir::MlirOptMain(int argc, char **argv, llvm::StringRef toolName,
|
||||
llvm::errs() << errorMessage << "\n";
|
||||
return failure();
|
||||
}
|
||||
// Setup the configuration for the main function.
|
||||
MlirOptMainConfig config;
|
||||
config.setPassPipelineParser(passPipeline)
|
||||
.splitInputFile(splitInputFile)
|
||||
.verifyDiagnostics(verifyDiagnostics)
|
||||
.verifyPasses(verifyPasses)
|
||||
.allowUnregisteredDialects(allowUnregisteredDialects)
|
||||
.preloadDialectsInContext(preloadDialectsInContext)
|
||||
.emitBytecode(emitBytecode)
|
||||
.useExplicitModule(explicitModule)
|
||||
.dumpPassPipeline(dumpPassPipeline);
|
||||
|
||||
if (failed(MlirOptMain(output->os(), std::move(file), registry, config)))
|
||||
return failure();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user