CIRCT 22.0.0git
Loading...
Searching...
No Matches
IntRangeAnnotations.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
11#include "mlir/Analysis/DataFlow/DeadCodeAnalysis.h"
12#include "mlir/Analysis/DataFlow/IntegerRangeAnalysis.h"
13#include "mlir/Analysis/DataFlowFramework.h"
14#include "mlir/Transforms/WalkPatternRewriteDriver.h"
15
16using namespace circt;
17using namespace circt::comb;
18using namespace mlir;
19using namespace mlir::dataflow;
20
21namespace circt {
22namespace comb {
23#define GEN_PASS_DEF_COMBOVERFLOWANNOTATING
24#include "circt/Dialect/Comb/Passes.h.inc"
25} // namespace comb
26} // namespace circt
27
28/// Gather ranges for all the values in `values`. Appends to the existing
29/// vector.
30static LogicalResult collectRanges(DataFlowSolver &solver, ValueRange values,
31 SmallVectorImpl<ConstantIntRanges> &ranges) {
32 for (Value val : values) {
33 auto *maybeInferredRange =
34 solver.lookupState<IntegerValueRangeLattice>(val);
35 if (!maybeInferredRange || maybeInferredRange->getValue().isUninitialized())
36 return failure();
37
38 const ConstantIntRanges &inferredRange =
39 maybeInferredRange->getValue().getValue();
40 ranges.push_back(inferredRange);
41 }
42 return success();
43}
44
45namespace {
46template <typename CombOpTy>
47struct CombOpAnnotate : public OpRewritePattern<CombOpTy> {
48 CombOpAnnotate(MLIRContext *context, DataFlowSolver &s)
49 : OpRewritePattern<CombOpTy>(context), solver(s) {}
50
51 LogicalResult matchAndRewrite(CombOpTy op,
52 PatternRewriter &rewriter) const override {
53 // Use LLVM nuw attribute to avoid confusion with IEEE overflow flags
54 if (op->hasAttr("comb.nuw"))
55 return failure();
56
57 if (op->getNumOperands() != 2 || op->getNumResults() != 1)
58 return rewriter.notifyMatchFailure(
59 op, "Only support binary operations with one result");
60
61 assert(isa<comb::AddOp>(op) || isa<comb::MulOp>(op) ||
62 isa<comb::SubOp>(op));
63
64 SmallVector<ConstantIntRanges> ranges;
65 if (failed(collectRanges(solver, op->getOperands(), ranges)))
66 return rewriter.notifyMatchFailure(op, "input without specified range");
67
68 bool overflowed = false;
69 // overflowed = a.max op b.max > 2^(bitwidth)-1
70 auto a = ranges[0].umax();
71 auto b = ranges[1].umax();
72
73 // Only use the overflow flag - need to explicitly discard the result.
74 // Cannot use operators intervals since they will be truncated to the
75 // result's bitwidth.
76 if (isa<comb::AddOp>(op))
77 (void)a.uadd_ov(b, overflowed);
78
79 if (isa<comb::MulOp>(op))
80 (void)a.umul_ov(b, overflowed);
81
82 if (!overflowed)
83 op->setAttr("comb.nuw", UnitAttr::get(op->getContext()));
84
85 return success();
86 }
87
88private:
89 DataFlowSolver &solver;
90};
91
92struct CombOverflowAnnotatingPass
93 : comb::impl::CombOverflowAnnotatingBase<CombOverflowAnnotatingPass> {
94
95 using CombOverflowAnnotatingBase::CombOverflowAnnotatingBase;
96 void runOnOperation() override;
97};
98} // namespace
99
100void CombOverflowAnnotatingPass::runOnOperation() {
101 Operation *op = getOperation();
102 MLIRContext *ctx = op->getContext();
103 DataFlowSolver solver;
104 solver.load<DeadCodeAnalysis>();
105 solver.load<IntegerRangeAnalysis>();
106 if (failed(solver.initializeAndRun(op)))
107 return signalPassFailure();
108
109 RewritePatternSet patterns(ctx);
110 // TODO: determine how to support subtraction
111 patterns.add<CombOpAnnotate<comb::AddOp>, CombOpAnnotate<comb::MulOp>>(
112 patterns.getContext(), solver);
113
114 walkAndApplyPatterns(op, std::move(patterns));
115}
assert(baseType &&"element must be base type")
static LogicalResult collectRanges(DataFlowSolver &solver, ValueRange values, SmallVectorImpl< ConstantIntRanges > &ranges)
Gather ranges for all the values in values.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition comb.py:1