Files
clang-p2996/mlir/test/lib/Analysis/TestMatchReduction.cpp
Diego Caballero 2a876a711d [mlir] Create a generic reduction detection utility
This patch introduces a generic reduction detection utility that works
across different dialecs. It is mostly a generalization of the reduction
detection algorithm in Affine. The reduction detection logic in Affine,
Linalg and SCFToOpenMP have been replaced with this new generic utility.

The utility takes some basic components of the potential reduction and
returns: 1) the reduced value, and 2) a list with the combiner operations.
The logic to match reductions involving multiple combiner operations disabled
until we can properly test it.

Reviewed By: ftynse, bondhugula, nicolasvasilache, pifon2a

Differential Revision: https://reviews.llvm.org/D110303
2021-09-24 20:45:59 +00:00

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/LoopAnalysis.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, FunctionPass> {
StringRef getArgument() const final { return "test-match-reduction"; }
StringRef getDescription() const final {
return "Test the match reduction utility.";
}
void runOnFunction() override {
FuncOp func = getFunction();
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 &region = 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 &regionEntry = 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);
}
});
}
};
} // end anonymous namespace
namespace mlir {
namespace test {
void registerTestMatchReductionPass() {
PassRegistration<TestMatchReductionPass>();
}
} // namespace test
} // namespace mlir