mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
[mlir-reduce] Improve diagnostic message and clean build dependency
Reviewed By: rriddle Differential Revision: https://reviews.llvm.org/D104443
This commit is contained in:
@@ -18,31 +18,33 @@ include "mlir/Pass/PassBase.td"
|
||||
def CommonReductionPassOptions {
|
||||
list<Option> options = [
|
||||
Option<"testerName", "test", "std::string", /* default */"",
|
||||
"The filename of the tester">,
|
||||
"The location of the tester which tests the file interestingness">,
|
||||
ListOption<"testerArgs", "test-arg", "std::string",
|
||||
"arguments of the tester",
|
||||
"llvm::cl::ZeroOrMore, llvm::cl::MiscFlags::CommaSeparated">,
|
||||
];
|
||||
}
|
||||
|
||||
def ReductionTree : Pass<"reduction-tree"> {
|
||||
let summary = "A general reduction tree pass for the MLIR Reduce Tool";
|
||||
let summary = "Reduce the input with reduction-tree algorithm";
|
||||
|
||||
let constructor = "mlir::createReductionTreePass()";
|
||||
|
||||
let options = [
|
||||
Option<"traversalModeId", "traversal-mode", "unsigned",
|
||||
/* default */"0", "The graph traversal mode">,
|
||||
/* default */"0",
|
||||
"The graph traversal mode, the default is single-path mode">,
|
||||
] # CommonReductionPassOptions.options;
|
||||
}
|
||||
|
||||
def OptReduction : Pass<"opt-reduction-pass", "ModuleOp"> {
|
||||
let summary = "A reduction pass wrapper for optimization passes";
|
||||
let summary = "A wrapper pass that reduces the file with optimization passes";
|
||||
|
||||
let constructor = "mlir::createOptReductionPass()";
|
||||
|
||||
let options = [
|
||||
Option<"optPass", "opt-pass", "std::string", /* default */"",
|
||||
"The optimization pass will be run dynamically in OptReductionPass">,
|
||||
"The optimization passes used for reduction, e.g., symbol-dce">,
|
||||
] # CommonReductionPassOptions.options;
|
||||
}
|
||||
|
||||
|
||||
@@ -44,19 +44,19 @@ void OptReductionPass::runOnOperation() {
|
||||
|
||||
PassManager passManager(module.getContext());
|
||||
if (failed(parsePassPipeline(optPass, passManager))) {
|
||||
LLVM_DEBUG(llvm::dbgs() << "\nFailed to parse pass pipeline");
|
||||
return;
|
||||
module.emitError() << "\nfailed to parse pass pipeline";
|
||||
return signalPassFailure();
|
||||
}
|
||||
|
||||
std::pair<Tester::Interestingness, int> original = test.isInteresting(module);
|
||||
if (original.first != Tester::Interestingness::True) {
|
||||
LLVM_DEBUG(llvm::dbgs() << "\nThe original input is not interested");
|
||||
return;
|
||||
module.emitError() << "\nthe original input is not interested";
|
||||
return signalPassFailure();
|
||||
}
|
||||
|
||||
if (failed(passManager.run(moduleVariant))) {
|
||||
LLVM_DEBUG(llvm::dbgs() << "\nFailed to run pass pipeline");
|
||||
return;
|
||||
module.emitError() << "\nfailed to run pass pipeline";
|
||||
return signalPassFailure();
|
||||
}
|
||||
|
||||
std::pair<Tester::Interestingness, int> reduced =
|
||||
|
||||
@@ -76,15 +76,15 @@ static void applyPatterns(Region ®ion,
|
||||
/// alternative way to remove operations, which is using `eraseOpNotInRange` to
|
||||
/// erase the operations not in the range specified by ReductionNode.
|
||||
template <typename IteratorType>
|
||||
static void findOptimal(ModuleOp module, Region ®ion,
|
||||
const FrozenRewritePatternSet &patterns,
|
||||
const Tester &test, bool eraseOpNotInRange) {
|
||||
static LogicalResult findOptimal(ModuleOp module, Region ®ion,
|
||||
const FrozenRewritePatternSet &patterns,
|
||||
const Tester &test, bool eraseOpNotInRange) {
|
||||
std::pair<Tester::Interestingness, size_t> initStatus =
|
||||
test.isInteresting(module);
|
||||
// While exploring the reduction tree, we always branch from an interesting
|
||||
// node. Thus the root node must be interesting.
|
||||
if (initStatus.first != Tester::Interestingness::True)
|
||||
return;
|
||||
return module.emitWarning() << "uninterested module will not be reduced";
|
||||
|
||||
llvm::SpecificBumpPtrAllocator<ReductionNode> allocator;
|
||||
|
||||
@@ -137,23 +137,25 @@ static void findOptimal(ModuleOp module, Region ®ion,
|
||||
if (test.isInteresting(module).second != smallestNode->getSize())
|
||||
llvm::report_fatal_error(
|
||||
"Reduced module doesn't have consistent size with smallestNode");
|
||||
return success();
|
||||
}
|
||||
|
||||
template <typename IteratorType>
|
||||
static void findOptimal(ModuleOp module, Region ®ion,
|
||||
const FrozenRewritePatternSet &patterns,
|
||||
const Tester &test) {
|
||||
static LogicalResult findOptimal(ModuleOp module, Region ®ion,
|
||||
const FrozenRewritePatternSet &patterns,
|
||||
const Tester &test) {
|
||||
// We separate the reduction process into 2 steps, the first one is to erase
|
||||
// redundant operations and the second one is to apply the reducer patterns.
|
||||
|
||||
// In the first phase, we don't apply any patterns so that we only select the
|
||||
// range of operations to keep to the module stay interesting.
|
||||
findOptimal<IteratorType>(module, region, /*patterns=*/{}, test,
|
||||
/*eraseOpNotInRange=*/true);
|
||||
if (failed(findOptimal<IteratorType>(module, region, /*patterns=*/{}, test,
|
||||
/*eraseOpNotInRange=*/true)))
|
||||
return failure();
|
||||
// In the second phase, we suppose that no operation is redundant, so we try
|
||||
// to rewrite the operation into simpler form.
|
||||
findOptimal<IteratorType>(module, region, patterns, test,
|
||||
/*eraseOpNotInRange=*/false);
|
||||
return findOptimal<IteratorType>(module, region, patterns, test,
|
||||
/*eraseOpNotInRange=*/false);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -192,7 +194,7 @@ public:
|
||||
void runOnOperation() override;
|
||||
|
||||
private:
|
||||
void reduceOp(ModuleOp module, Region ®ion);
|
||||
LogicalResult reduceOp(ModuleOp module, Region ®ion);
|
||||
|
||||
FrozenRewritePatternSet reducerPatterns;
|
||||
};
|
||||
@@ -221,7 +223,8 @@ void ReductionTreePass::runOnOperation() {
|
||||
|
||||
for (Region ®ion : op->getRegions())
|
||||
if (!region.empty())
|
||||
reduceOp(module, region);
|
||||
if (failed(reduceOp(module, region)))
|
||||
return signalPassFailure();
|
||||
|
||||
for (Region ®ion : op->getRegions())
|
||||
for (Operation &op : region.getOps())
|
||||
@@ -230,15 +233,14 @@ void ReductionTreePass::runOnOperation() {
|
||||
} while (!workList.empty());
|
||||
}
|
||||
|
||||
void ReductionTreePass::reduceOp(ModuleOp module, Region ®ion) {
|
||||
LogicalResult ReductionTreePass::reduceOp(ModuleOp module, Region ®ion) {
|
||||
Tester test(testerName, testerArgs);
|
||||
switch (traversalModeId) {
|
||||
case TraversalMode::SinglePath:
|
||||
findOptimal<ReductionNode::iterator<TraversalMode::SinglePath>>(
|
||||
return findOptimal<ReductionNode::iterator<TraversalMode::SinglePath>>(
|
||||
module, region, reducerPatterns, test);
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unsupported mode");
|
||||
return module.emitError() << "unsupported traversal mode detected";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
set(LLVM_OPTIONAL_SOURCES
|
||||
MlirReduceMain.cpp
|
||||
)
|
||||
|
||||
set(LLVM_LINK_COMPONENTS
|
||||
Support
|
||||
)
|
||||
|
||||
add_mlir_library(MLIRReduceLib
|
||||
MlirReduceMain.cpp
|
||||
|
||||
|
||||
@@ -39,23 +39,36 @@ static LogicalResult loadModule(MLIRContext &context, OwningModuleRef &module,
|
||||
|
||||
LogicalResult mlir::mlirReduceMain(int argc, char **argv,
|
||||
MLIRContext &context) {
|
||||
// Override the default '-h' and use the default PrintHelpMessage() which
|
||||
// won't print options in categories.
|
||||
static llvm::cl::opt<bool> Help("h", llvm::cl::desc("Alias for -help"),
|
||||
llvm::cl::Hidden);
|
||||
|
||||
static llvm::cl::OptionCategory MLIRReduceCategory("mlir-reduce options");
|
||||
|
||||
static llvm::cl::opt<std::string> inputFilename(
|
||||
llvm::cl::Positional, llvm::cl::Required, llvm::cl::desc("<input file>"));
|
||||
llvm::cl::Positional, llvm::cl::desc("<input file>"),
|
||||
llvm::cl::cat(MLIRReduceCategory));
|
||||
|
||||
static llvm::cl::opt<std::string> outputFilename(
|
||||
"o", llvm::cl::desc("Output filename for the reduced test case"),
|
||||
llvm::cl::init("-"));
|
||||
llvm::cl::init("-"), llvm::cl::cat(MLIRReduceCategory));
|
||||
|
||||
llvm::cl::HideUnrelatedOptions(MLIRReduceCategory);
|
||||
|
||||
llvm::InitLLVM y(argc, argv);
|
||||
|
||||
registerReducerPasses();
|
||||
registerMLIRContextCLOptions();
|
||||
registerPassManagerCLOptions();
|
||||
|
||||
PassPipelineCLParser parser("", "Reduction Passes to Run");
|
||||
llvm::cl::ParseCommandLineOptions(argc, argv,
|
||||
"MLIR test case reduction tool.\n");
|
||||
|
||||
if (Help) {
|
||||
llvm::cl::PrintHelpMessage();
|
||||
return success();
|
||||
}
|
||||
|
||||
std::string errorMessage;
|
||||
|
||||
auto output = openOutputFile(outputFilename, &errorMessage);
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
|
||||
get_property(conversion_libs GLOBAL PROPERTY MLIR_CONVERSION_LIBS)
|
||||
|
||||
if(MLIR_INCLUDE_TESTS)
|
||||
set(test_libs
|
||||
MLIRTestDialect
|
||||
)
|
||||
endif()
|
||||
get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS)
|
||||
|
||||
set(LIBS
|
||||
${dialect_libs}
|
||||
${conversion_libs}
|
||||
${test_libs}
|
||||
${dialect_libs}
|
||||
MLIRDialect
|
||||
MLIRIR
|
||||
MLIRPass
|
||||
MLIRReduceLib
|
||||
MLIRTestDialect
|
||||
)
|
||||
|
||||
add_llvm_tool(mlir-reduce
|
||||
|
||||
Reference in New Issue
Block a user