18#include "mlir/Analysis/DataFlow/ConstantPropagationAnalysis.h"
19#include "mlir/Analysis/DataFlow/IntegerRangeAnalysis.h"
20#include "mlir/Analysis/DataFlow/Utils.h"
21#include "mlir/Analysis/DataFlowFramework.h"
22#include "mlir/Dialect/Arith/IR/Arith.h"
23#include "mlir/Dialect/Arith/Transforms/Passes.h"
24#include "mlir/Dialect/Func/IR/FuncOps.h"
25#include "mlir/Pass/Pass.h"
26#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
27#include "mlir/Transforms/RegionUtils.h"
30#define GEN_PASS_DEF_AIECOREINTRANGENARROWING
31#include "aie/Dialect/AIE/Transforms/AIEPasses.h.inc"
34#define DEBUG_TYPE "aie-core-int-range-narrowing"
45class DataFlowListener :
public RewriterBase::Listener {
47 DataFlowListener(DataFlowSolver &s) : s(s) {}
50 void notifyOperationErased(Operation *op)
override {
51 s.eraseState(s.getProgramPointAfter(op));
52 for (Value res : op->getResults())
59struct AIECoreIntRangeNarrowingPass
60 : xilinx::AIE::impl::AIECoreIntRangeNarrowingBase<
61 AIECoreIntRangeNarrowingPass> {
62 using AIECoreIntRangeNarrowingBase::AIECoreIntRangeNarrowingBase;
64 void runOnOperation()
override {
65 SmallVector<unsigned> bitwidths(bitwidthsSupported.begin(),
66 bitwidthsSupported.end());
67 if (bitwidths.empty())
68 bitwidths.push_back(32);
70 SmallVector<Operation *> bodies;
71 getOperation().walk([&](Operation *op) {
74 else if (
auto func = dyn_cast<func::FuncOp>(op);
79 for (Operation *body : bodies)
80 if (failed(narrow(body, bitwidths)))
81 return signalPassFailure();
84 LogicalResult narrow(Operation *body, ArrayRef<unsigned> bitwidths) {
85 MLIRContext *ctx = body->getContext();
86 DataFlowSolver solver;
87 dataflow::loadBaselineAnalyses(solver);
88 solver.load<dataflow::IntegerRangeAnalysis>();
93 SetVector<Value> captured;
94 getUsedValuesDefinedAbove(body->getRegions(), captured);
95 for (Value v : captured) {
97 .getOrCreateState<dataflow::Lattice<dataflow::ConstantValue>>(v)
98 ->join(dataflow::ConstantValue::getUnknownConstant());
99 (void)solver.getOrCreateState<dataflow::IntegerValueRangeLattice>(v)
100 ->join(IntegerValueRange::getMaxRange(v));
102 if (failed(solver.initializeAndRun(body)))
105 DataFlowListener listener(solver);
106 RewritePatternSet patterns(ctx);
107 arith::populateIntRangeNarrowingPatterns(patterns, solver, bitwidths);
108 arith::populateControlFlowValuesNarrowingPatterns(patterns, solver,
114 SmallVector<Operation *> ops;
115 body->getRegion(0).walk([&](Operation *op) { ops.push_back(op); });
116 return applyOpPatternsGreedily(ops, std::move(patterns),
117 GreedyRewriteConfig()
118 .setScope(&body->getRegion(0))
119 .setListener(&listener));
125std::unique_ptr<OperationPass<DeviceOp>>
127 return std::make_unique<AIECoreIntRangeNarrowingPass>();
std::unique_ptr< mlir::OperationPass< DeviceOp > > createAIECoreIntRangeNarrowingPass()