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