xref: /llvm-project/mlir/include/mlir/Analysis/DataFlow/IntegerRangeAnalysis.h (revision b6603e1bf11dee4761e49af6581c8b8f074b705d)
1 //===-IntegerRangeAnalysis.h - Integer range analysis -----------*- C++ -*-===//
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 //
9 // This file declares the dataflow analysis class for integer range inference
10 // so that it can be used in transformations over the `arith` dialect such as
11 // branch elimination or signed->unsigned rewriting.
12 //
13 // One can also implement InferIntRangeInterface on ops in custom dialects,
14 // and then use this analysis to propagate ranges with custom semantics.
15 //
16 //===----------------------------------------------------------------------===//
17 
18 #ifndef MLIR_ANALYSIS_DATAFLOW_INTEGERANGEANALYSIS_H
19 #define MLIR_ANALYSIS_DATAFLOW_INTEGERANGEANALYSIS_H
20 
21 #include "mlir/Analysis/DataFlow/SparseAnalysis.h"
22 #include "mlir/Interfaces/InferIntRangeInterface.h"
23 
24 namespace mlir {
25 namespace dataflow {
26 
27 /// This lattice element represents the integer value range of an SSA value.
28 /// When this lattice is updated, it automatically updates the constant value
29 /// of the SSA value (if the range can be narrowed to one).
30 class IntegerValueRangeLattice : public Lattice<IntegerValueRange> {
31 public:
32   using Lattice::Lattice;
33 
34   /// If the range can be narrowed to an integer constant, update the constant
35   /// value of the SSA value.
36   void onUpdate(DataFlowSolver *solver) const override;
37 };
38 
39 /// Integer range analysis determines the integer value range of SSA values
40 /// using operations that define `InferIntRangeInterface` and also sets the
41 /// range of iteration indices of loops with known bounds.
42 ///
43 /// This analysis depends on DeadCodeAnalysis, and will be a silent no-op
44 /// if DeadCodeAnalysis is not loaded in the same solver context.
45 class IntegerRangeAnalysis
46     : public SparseForwardDataFlowAnalysis<IntegerValueRangeLattice> {
47 public:
48   using SparseForwardDataFlowAnalysis::SparseForwardDataFlowAnalysis;
49 
50   /// At an entry point, we cannot reason about interger value ranges.
51   void setToEntryState(IntegerValueRangeLattice *lattice) override {
52     propagateIfChanged(lattice, lattice->join(IntegerValueRange::getMaxRange(
53                                     lattice->getAnchor())));
54   }
55 
56   /// Visit an operation. Invoke the transfer function on each operation that
57   /// implements `InferIntRangeInterface`.
58   LogicalResult
59   visitOperation(Operation *op,
60                  ArrayRef<const IntegerValueRangeLattice *> operands,
61                  ArrayRef<IntegerValueRangeLattice *> results) override;
62 
63   /// Visit block arguments or operation results of an operation with region
64   /// control-flow for which values are not defined by region control-flow. This
65   /// function calls `InferIntRangeInterface` to provide values for block
66   /// arguments or tries to reduce the range on loop induction variables with
67   /// known bounds.
68   void
69   visitNonControlFlowArguments(Operation *op, const RegionSuccessor &successor,
70                                ArrayRef<IntegerValueRangeLattice *> argLattices,
71                                unsigned firstIndex) override;
72 };
73 
74 } // end namespace dataflow
75 } // end namespace mlir
76 
77 #endif // MLIR_ANALYSIS_DATAFLOW_INTEGERANGEANALYSIS_H
78