#include "mlir/Dialect/Affine/Passes.h"
#include "mlir/Dialect/Affine/Analysis/Utils.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Affine/Utils.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/IR/IntegerSet.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_SIMPLIFYAFFINESTRUCTURES
#include "mlir/Dialect/Affine/Passes.h.inc"
}
}
#define DEBUG_TYPE "simplify-affine-structure"
using namespace mlir;
using namespace mlir::affine;
namespace {
struct SimplifyAffineStructures
: public affine::impl::SimplifyAffineStructuresBase<
SimplifyAffineStructures> {
void runOnOperation() override;
template <typename AttributeT>
void simplifyAndUpdateAttribute(Operation *op, StringAttr name,
AttributeT attr) {
auto &simplified = simplifiedAttributes[attr];
if (simplified == attr)
return;
if (!simplified) {
auto value = attr.getValue();
auto simplifiedValue = simplify(value);
if (simplifiedValue == value) {
simplified = attr;
return;
}
simplified = AttributeT::get(simplifiedValue);
}
op->setAttr(name, simplified);
}
IntegerSet simplify(IntegerSet set) { return simplifyIntegerSet(set); }
AffineMap simplify(AffineMap map) {
MutableAffineMap mMap(map);
mMap.simplify();
return mMap.getAffineMap();
}
DenseMap<Attribute, Attribute> simplifiedAttributes;
};
}
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::affine::createSimplifyAffineStructuresPass() {
return std::make_unique<SimplifyAffineStructures>();
}
void SimplifyAffineStructures::runOnOperation() {
auto func = getOperation();
simplifiedAttributes.clear();
RewritePatternSet patterns(func.getContext());
AffineApplyOp::getCanonicalizationPatterns(patterns, func.getContext());
AffineForOp::getCanonicalizationPatterns(patterns, func.getContext());
AffineIfOp::getCanonicalizationPatterns(patterns, func.getContext());
FrozenRewritePatternSet frozenPatterns(std::move(patterns));
SmallVector<Operation *> opsToSimplify;
func.walk([&](Operation *op) {
for (auto attr : op->getAttrs()) {
if (auto mapAttr = dyn_cast<AffineMapAttr>(attr.getValue()))
simplifyAndUpdateAttribute(op, attr.getName(), mapAttr);
else if (auto setAttr = dyn_cast<IntegerSetAttr>(attr.getValue()))
simplifyAndUpdateAttribute(op, attr.getName(), setAttr);
}
if (isa<AffineForOp, AffineIfOp, AffineApplyOp>(op))
opsToSimplify.push_back(op);
});
GreedyRewriteConfig config;
config.strictMode = GreedyRewriteStrictness::ExistingAndNewOps;
(void)applyOpPatternsAndFold(opsToSimplify, frozenPatterns, config);
}