/home/arjun/llvm-project/mlir/include/mlir/IR/IntegerSet.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- IntegerSet.h - MLIR Integer Set Class --------------------*- 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 | | // Integer sets are sets of points from the integer lattice constrained by |
10 | | // affine equality/inequality constraints. This class is meant to represent |
11 | | // integer sets in the IR - for 'affine.if' operations and as attributes of |
12 | | // other operations. It is typically expected to contain only a handful of |
13 | | // affine constraints, and is immutable like an affine map. Integer sets are not |
14 | | // unique'd - although affine expressions that make up its equalities and |
15 | | // inequalities are themselves unique. |
16 | | |
17 | | // This class is not meant for affine analysis and operations like set |
18 | | // operations, emptiness checks, or other math operations for analysis and |
19 | | // transformation. For the latter, use FlatAffineConstraints. |
20 | | // |
21 | | //===----------------------------------------------------------------------===// |
22 | | |
23 | | #ifndef MLIR_IR_INTEGER_SET_H |
24 | | #define MLIR_IR_INTEGER_SET_H |
25 | | |
26 | | #include "mlir/IR/AffineExpr.h" |
27 | | #include "llvm/ADT/ArrayRef.h" |
28 | | |
29 | | namespace mlir { |
30 | | |
31 | | namespace detail { |
32 | | struct IntegerSetStorage; |
33 | | } |
34 | | |
35 | | class MLIRContext; |
36 | | |
37 | | /// An integer set representing a conjunction of one or more affine equalities |
38 | | /// and inequalities. An integer set in the IR is immutable like the affine map, |
39 | | /// but integer sets are not unique'd. The affine expressions that make up the |
40 | | /// equalities and inequalities of an integer set are themselves unique and are |
41 | | /// allocated by the bump pointer allocator. |
42 | | class IntegerSet { |
43 | | public: |
44 | | using ImplType = detail::IntegerSetStorage; |
45 | | |
46 | 0 | constexpr IntegerSet() : set(nullptr) {} |
47 | 0 | explicit IntegerSet(ImplType *set) : set(set) {} |
48 | | |
49 | | static IntegerSet get(unsigned dimCount, unsigned symbolCount, |
50 | | ArrayRef<AffineExpr> constraints, |
51 | | ArrayRef<bool> eqFlags); |
52 | | |
53 | | // Returns the canonical empty IntegerSet (i.e. a set with no integer points). |
54 | | static IntegerSet getEmptySet(unsigned numDims, unsigned numSymbols, |
55 | 0 | MLIRContext *context) { |
56 | 0 | auto one = getAffineConstantExpr(1, context); |
57 | 0 | /* 1 == 0 */ |
58 | 0 | return get(numDims, numSymbols, one, true); |
59 | 0 | } |
60 | | |
61 | | /// Returns true if this is the canonical integer set. |
62 | | bool isEmptyIntegerSet() const; |
63 | | |
64 | | /// This method substitutes any uses of dimensions and symbols (e.g. |
65 | | /// dim#0 with dimReplacements[0]) in subexpressions and returns the modified |
66 | | /// integer set. Because this can be used to eliminate dims and |
67 | | /// symbols, the client needs to specify the number of dims and symbols in |
68 | | /// the result. The returned map always has the same number of results. |
69 | | IntegerSet replaceDimsAndSymbols(ArrayRef<AffineExpr> dimReplacements, |
70 | | ArrayRef<AffineExpr> symReplacements, |
71 | | unsigned numResultDims, |
72 | | unsigned numResultSyms); |
73 | | |
74 | 0 | explicit operator bool() { return set; } |
75 | 0 | bool operator==(IntegerSet other) const { return set == other.set; } |
76 | | |
77 | | unsigned getNumDims() const; |
78 | | unsigned getNumSymbols() const; |
79 | | unsigned getNumInputs() const; |
80 | | unsigned getNumConstraints() const; |
81 | | unsigned getNumEqualities() const; |
82 | | unsigned getNumInequalities() const; |
83 | | |
84 | | ArrayRef<AffineExpr> getConstraints() const; |
85 | | |
86 | | AffineExpr getConstraint(unsigned idx) const; |
87 | | |
88 | | /// Returns the equality bits, which specify whether each of the constraints |
89 | | /// is an equality or inequality. |
90 | | ArrayRef<bool> getEqFlags() const; |
91 | | |
92 | | /// Returns true if the idx^th constraint is an equality, false if it is an |
93 | | /// inequality. |
94 | | bool isEq(unsigned idx) const; |
95 | | |
96 | | MLIRContext *getContext() const; |
97 | | |
98 | | /// Walk all of the AffineExpr's in this set's constraints. Each node in an |
99 | | /// expression tree is visited in postorder. |
100 | | void walkExprs(function_ref<void(AffineExpr)> callback) const; |
101 | | |
102 | | void print(raw_ostream &os) const; |
103 | | void dump() const; |
104 | | |
105 | | friend ::llvm::hash_code hash_value(IntegerSet arg); |
106 | | |
107 | | private: |
108 | | ImplType *set; |
109 | | /// Sets with constraints fewer than kUniquingThreshold are uniqued. |
110 | | constexpr static unsigned kUniquingThreshold = 4; |
111 | | }; |
112 | | |
113 | | // Make AffineExpr hashable. |
114 | 0 | inline ::llvm::hash_code hash_value(IntegerSet arg) { |
115 | 0 | return ::llvm::hash_value(arg.set); |
116 | 0 | } |
117 | | |
118 | | } // end namespace mlir |
119 | | namespace llvm { |
120 | | |
121 | | // IntegerSet hash just like pointers |
122 | | template <> struct DenseMapInfo<mlir::IntegerSet> { |
123 | 0 | static mlir::IntegerSet getEmptyKey() { |
124 | 0 | auto pointer = llvm::DenseMapInfo<void *>::getEmptyKey(); |
125 | 0 | return mlir::IntegerSet(static_cast<mlir::IntegerSet::ImplType *>(pointer)); |
126 | 0 | } |
127 | 0 | static mlir::IntegerSet getTombstoneKey() { |
128 | 0 | auto pointer = llvm::DenseMapInfo<void *>::getTombstoneKey(); |
129 | 0 | return mlir::IntegerSet(static_cast<mlir::IntegerSet::ImplType *>(pointer)); |
130 | 0 | } |
131 | 0 | static unsigned getHashValue(mlir::IntegerSet val) { |
132 | 0 | return mlir::hash_value(val); |
133 | 0 | } |
134 | 0 | static bool isEqual(mlir::IntegerSet LHS, mlir::IntegerSet RHS) { |
135 | 0 | return LHS == RHS; |
136 | 0 | } |
137 | | }; |
138 | | |
139 | | } // namespace llvm |
140 | | #endif // MLIR_IR_INTEGER_SET_H |