The only benefit of FunctionPass is that it filters out function declarations. This isn't enough to justify carrying it around, as we can simplify filter out declarations when necessary within the pass. We can also explore with better scheduling primitives to filter out declarations at the pipeline level in the future. The definition of FunctionPass is left intact for now to allow time for downstream users to migrate. Differential Revision: https://reviews.llvm.org/D117182
87 lines
2.7 KiB
C++
87 lines
2.7 KiB
C++
//===- TestMatchReduction.cpp - Test the match reduction utility ----------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file contains a test pass for the match reduction utility.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "mlir/Analysis/SliceAnalysis.h"
|
|
#include "mlir/Pass/Pass.h"
|
|
|
|
using namespace mlir;
|
|
|
|
namespace {
|
|
|
|
void printReductionResult(Operation *redRegionOp, unsigned numOutput,
|
|
Value reducedValue,
|
|
ArrayRef<Operation *> combinerOps) {
|
|
if (reducedValue) {
|
|
redRegionOp->emitRemark("Reduction found in output #") << numOutput << "!";
|
|
redRegionOp->emitRemark("Reduced Value: ") << reducedValue;
|
|
for (Operation *combOp : combinerOps)
|
|
redRegionOp->emitRemark("Combiner Op: ") << *combOp;
|
|
|
|
return;
|
|
}
|
|
|
|
redRegionOp->emitRemark("Reduction NOT found in output #")
|
|
<< numOutput << "!";
|
|
}
|
|
|
|
struct TestMatchReductionPass
|
|
: public PassWrapper<TestMatchReductionPass, OperationPass<FuncOp>> {
|
|
StringRef getArgument() const final { return "test-match-reduction"; }
|
|
StringRef getDescription() const final {
|
|
return "Test the match reduction utility.";
|
|
}
|
|
|
|
void runOnOperation() override {
|
|
FuncOp func = getOperation();
|
|
func->emitRemark("Testing function");
|
|
|
|
func.walk<WalkOrder::PreOrder>([](Operation *op) {
|
|
if (isa<FuncOp>(op))
|
|
return;
|
|
|
|
// Limit testing to ops with only one region.
|
|
if (op->getNumRegions() != 1)
|
|
return;
|
|
|
|
Region ®ion = op->getRegion(0);
|
|
if (!region.hasOneBlock())
|
|
return;
|
|
|
|
// We expect all the tested region ops to have 1 input by default. The
|
|
// remaining arguments are assumed to be outputs/reductions and there must
|
|
// be at least one.
|
|
// TODO: Extend it to support more generic cases.
|
|
Block ®ionEntry = region.front();
|
|
auto args = regionEntry.getArguments();
|
|
if (args.size() < 2)
|
|
return;
|
|
|
|
auto outputs = args.drop_front();
|
|
for (int i = 0, size = outputs.size(); i < size; ++i) {
|
|
SmallVector<Operation *, 4> combinerOps;
|
|
Value reducedValue = matchReduction(outputs, i, combinerOps);
|
|
printReductionResult(op, i, reducedValue, combinerOps);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
} // namespace
|
|
|
|
namespace mlir {
|
|
namespace test {
|
|
void registerTestMatchReductionPass() {
|
|
PassRegistration<TestMatchReductionPass>();
|
|
}
|
|
} // namespace test
|
|
} // namespace mlir
|