xref: /llvm-project/mlir/test/lib/Pass/TestDynamicPipeline.cpp (revision 36d3efea15e6202edd64b05de38d8379e2baddb2)
13fef2d26SRiver Riddle //===------ TestDynamicPipeline.cpp --- dynamic pipeline test pass --------===//
23fef2d26SRiver Riddle //
33fef2d26SRiver Riddle // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43fef2d26SRiver Riddle // See https://llvm.org/LICENSE.txt for license information.
53fef2d26SRiver Riddle // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63fef2d26SRiver Riddle //
73fef2d26SRiver Riddle //===----------------------------------------------------------------------===//
83fef2d26SRiver Riddle //
93fef2d26SRiver Riddle // This file implements a pass to test the dynamic pipeline feature.
103fef2d26SRiver Riddle //
113fef2d26SRiver Riddle //===----------------------------------------------------------------------===//
123fef2d26SRiver Riddle 
13*36d3efeaSRiver Riddle #include "mlir/IR/BuiltinOps.h"
143fef2d26SRiver Riddle #include "mlir/Pass/Pass.h"
153fef2d26SRiver Riddle #include "mlir/Pass/PassManager.h"
163fef2d26SRiver Riddle 
173fef2d26SRiver Riddle using namespace mlir;
183fef2d26SRiver Riddle 
193fef2d26SRiver Riddle namespace {
203fef2d26SRiver Riddle 
213fef2d26SRiver Riddle class TestDynamicPipelinePass
223fef2d26SRiver Riddle     : public PassWrapper<TestDynamicPipelinePass, OperationPass<>> {
233fef2d26SRiver Riddle public:
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestDynamicPipelinePass)245e50dd04SRiver Riddle   MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestDynamicPipelinePass)
255e50dd04SRiver Riddle 
26b5e22e6dSMehdi Amini   StringRef getArgument() const final { return "test-dynamic-pipeline"; }
getDescription() const27b5e22e6dSMehdi Amini   StringRef getDescription() const final {
28b5e22e6dSMehdi Amini     return "Tests the dynamic pipeline feature by applying "
29b5e22e6dSMehdi Amini            "a pipeline on a selected set of functions";
30b5e22e6dSMehdi Amini   }
getDependentDialects(DialectRegistry & registry) const313fef2d26SRiver Riddle   void getDependentDialects(DialectRegistry &registry) const override {
323fef2d26SRiver Riddle     OpPassManager pm(ModuleOp::getOperationName(),
333fef2d26SRiver Riddle                      OpPassManager::Nesting::Implicit);
343fef2d26SRiver Riddle     (void)parsePassPipeline(pipeline, pm, llvm::errs());
353fef2d26SRiver Riddle     pm.getDependentDialects(registry);
363fef2d26SRiver Riddle   }
373fef2d26SRiver Riddle 
38e5639b3fSMehdi Amini   TestDynamicPipelinePass() = default;
TestDynamicPipelinePass(const TestDynamicPipelinePass &)393fef2d26SRiver Riddle   TestDynamicPipelinePass(const TestDynamicPipelinePass &) {}
403fef2d26SRiver Riddle 
runOnOperation()413fef2d26SRiver Riddle   void runOnOperation() override {
423fef2d26SRiver Riddle     Operation *currentOp = getOperation();
433fef2d26SRiver Riddle 
443fef2d26SRiver Riddle     llvm::errs() << "Dynamic execute '" << pipeline << "' on "
453fef2d26SRiver Riddle                  << currentOp->getName() << "\n";
463fef2d26SRiver Riddle     if (pipeline.empty()) {
473fef2d26SRiver Riddle       llvm::errs() << "Empty pipeline\n";
483fef2d26SRiver Riddle       return;
493fef2d26SRiver Riddle     }
503fef2d26SRiver Riddle     auto symbolOp = dyn_cast<SymbolOpInterface>(currentOp);
513fef2d26SRiver Riddle     if (!symbolOp) {
523fef2d26SRiver Riddle       currentOp->emitWarning()
533fef2d26SRiver Riddle           << "Ignoring because not implementing SymbolOpInterface\n";
543fef2d26SRiver Riddle       return;
553fef2d26SRiver Riddle     }
563fef2d26SRiver Riddle 
573fef2d26SRiver Riddle     auto opName = symbolOp.getName();
583fef2d26SRiver Riddle     if (!opNames.empty() && !llvm::is_contained(opNames, opName)) {
593fef2d26SRiver Riddle       llvm::errs() << "dynamic-pipeline skip op name: " << opName << "\n";
603fef2d26SRiver Riddle       return;
613fef2d26SRiver Riddle     }
62b8ffcb12SRiver Riddle     OpPassManager pm(currentOp->getName().getIdentifier(),
633fef2d26SRiver Riddle                      OpPassManager::Nesting::Implicit);
64b8ffcb12SRiver Riddle     (void)parsePassPipeline(pipeline, pm, llvm::errs());
653fef2d26SRiver Riddle 
663fef2d26SRiver Riddle     // Check that running on the parent operation always immediately fails.
673fef2d26SRiver Riddle     if (runOnParent) {
683fef2d26SRiver Riddle       if (currentOp->getParentOp())
69b8ffcb12SRiver Riddle         if (!failed(runPipeline(pm, currentOp->getParentOp())))
703fef2d26SRiver Riddle           signalPassFailure();
713fef2d26SRiver Riddle       return;
723fef2d26SRiver Riddle     }
733fef2d26SRiver Riddle 
743fef2d26SRiver Riddle     if (runOnNestedOp) {
753fef2d26SRiver Riddle       llvm::errs() << "Run on nested op\n";
763fef2d26SRiver Riddle       currentOp->walk([&](Operation *op) {
773fef2d26SRiver Riddle         if (op == currentOp || !op->hasTrait<OpTrait::IsIsolatedFromAbove>() ||
783fef2d26SRiver Riddle             op->getName() != currentOp->getName())
793fef2d26SRiver Riddle           return;
803fef2d26SRiver Riddle         llvm::errs() << "Run on " << *op << "\n";
813fef2d26SRiver Riddle         // Run on the current operation
82b8ffcb12SRiver Riddle         if (failed(runPipeline(pm, op)))
833fef2d26SRiver Riddle           signalPassFailure();
843fef2d26SRiver Riddle       });
853fef2d26SRiver Riddle     } else {
863fef2d26SRiver Riddle       // Run on the current operation
87b8ffcb12SRiver Riddle       if (failed(runPipeline(pm, currentOp)))
883fef2d26SRiver Riddle         signalPassFailure();
893fef2d26SRiver Riddle     }
903fef2d26SRiver Riddle   }
913fef2d26SRiver Riddle 
923fef2d26SRiver Riddle   Option<bool> runOnNestedOp{
933fef2d26SRiver Riddle       *this, "run-on-nested-operations",
943fef2d26SRiver Riddle       llvm::cl::desc("This will apply the pipeline on nested operations under "
953fef2d26SRiver Riddle                      "the visited operation.")};
963fef2d26SRiver Riddle   Option<bool> runOnParent{
973fef2d26SRiver Riddle       *this, "run-on-parent",
983fef2d26SRiver Riddle       llvm::cl::desc("This will apply the pipeline on the parent operation if "
993fef2d26SRiver Riddle                      "it exist, this is expected to fail.")};
1003fef2d26SRiver Riddle   Option<std::string> pipeline{
1013fef2d26SRiver Riddle       *this, "dynamic-pipeline",
1023fef2d26SRiver Riddle       llvm::cl::desc("The pipeline description that "
1033fef2d26SRiver Riddle                      "will run on the filtered function.")};
1043fef2d26SRiver Riddle   ListOption<std::string> opNames{
1056edef135SRiver Riddle       *this, "op-name",
1063fef2d26SRiver Riddle       llvm::cl::desc("List of function name to apply the pipeline to")};
1073fef2d26SRiver Riddle };
1083fef2d26SRiver Riddle } // namespace
1093fef2d26SRiver Riddle 
1103fef2d26SRiver Riddle namespace mlir {
1113fef2d26SRiver Riddle namespace test {
registerTestDynamicPipelinePass()1123fef2d26SRiver Riddle void registerTestDynamicPipelinePass() {
113b5e22e6dSMehdi Amini   PassRegistration<TestDynamicPipelinePass>();
1143fef2d26SRiver Riddle }
1153fef2d26SRiver Riddle } // namespace test
1163fef2d26SRiver Riddle } // namespace mlir
117