xref: /llvm-project/mlir/include/mlir/Dialect/Affine/IR/AffineValueMap.h (revision 1e9bfcd9a423765a86b2fc807c3bc3a097823deb)
1 //===- AffineValueMap.h - MLIR Affine Value Map 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 // An AffineValueMap is an affine map plus its ML value operands and results for
10 // analysis purposes.
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef MLIR_DIALECT_AFFINE_IR_AFFINEVALUEMAP_H
14 #define MLIR_DIALECT_AFFINE_IR_AFFINEVALUEMAP_H
15 
16 #include "mlir/IR/AffineMap.h"
17 #include "mlir/IR/OperationSupport.h"
18 #include "mlir/IR/Value.h"
19 
20 namespace mlir {
21 namespace affine {
22 
23 /// An AffineValueMap is an affine map plus its ML value operands and
24 /// results for analysis purposes. The structure is still a tree form that is
25 /// same as that of an affine map or an AffineApplyOp. However, its operands,
26 /// results, and its map can themselves change  as a result of
27 /// substitutions, simplifications, and other analysis.
28 // An affine value map can readily be constructed from an AffineApplyOp, or an
29 // AffineBound of a AffineForOp. It can be further transformed, substituted
30 // into, or simplified. Unlike AffineMap's, AffineValueMap's are created and
31 // destroyed during analysis. Only the AffineMap expressions that are pointed by
32 // them are unique'd. An affine value map, and the operations on it, maintain
33 // the invariant that operands are always positionally aligned with the
34 // AffineDimExpr and AffineSymbolExpr in the underlying AffineMap.
35 class AffineValueMap {
36 public:
37   // Creates an empty AffineValueMap (users should call 'reset' to reset map
38   // and operands).
39   AffineValueMap() = default;
40   AffineValueMap(AffineMap map, ValueRange operands, ValueRange results = {});
41 
42   ~AffineValueMap();
43 
44   // Resets this AffineValueMap with 'map', 'operands', and 'results'.
45   void reset(AffineMap map, ValueRange operands, ValueRange results = {});
46 
47   /// Composes all incoming affine.apply ops and then simplifies and
48   /// canonicalizes the map and operands. This can change the number of
49   /// operands, but the result count remains the same.
50   void composeSimplifyAndCanonicalize();
51 
52   /// Return the value map that is the difference of value maps 'a' and 'b',
53   /// represented as an affine map and its operands. The output map + operands
54   /// are canonicalized and simplified.
55   static void difference(const AffineValueMap &a, const AffineValueMap &b,
56                          AffineValueMap *res);
57 
58   /// Return true if the idx^th result can be proved to be a multiple of
59   /// 'factor', false otherwise.
60   inline bool isMultipleOf(unsigned idx, int64_t factor) const;
61 
62   /// Return true if the idx^th result depends on 'value', false otherwise.
63   bool isFunctionOf(unsigned idx, Value value) const;
64 
65   /// Return true if the result at 'idx' is a constant, false
66   /// otherwise.
67   bool isConstant(unsigned idx) const;
68 
69   /// Return true if this is an identity map.
70   bool isIdentity() const;
71 
setResult(unsigned i,AffineExpr e)72   void setResult(unsigned i, AffineExpr e) { map.setResult(i, e); }
getResult(unsigned i)73   AffineExpr getResult(unsigned i) { return map.getResult(i); }
getNumOperands()74   inline unsigned getNumOperands() const { return operands.size(); }
getNumDims()75   inline unsigned getNumDims() const { return map.getNumDims(); }
getNumSymbols()76   inline unsigned getNumSymbols() const { return map.getNumSymbols(); }
getNumResults()77   inline unsigned getNumResults() const { return map.getNumResults(); }
78 
79   Value getOperand(unsigned i) const;
80   ArrayRef<Value> getOperands() const;
81   AffineMap getAffineMap() const;
82 
83   /// Attempts to canonicalize the map and operands. Return success if the map
84   /// and/or operands have been modified.
85   LogicalResult canonicalize();
86 
87 private:
88   // A mutable affine map.
89   MutableAffineMap map;
90 
91   // TODO: make these trailing objects?
92   /// The SSA operands binding to the dim's and symbols of 'map'.
93   SmallVector<Value, 4> operands;
94   /// The SSA results binding to the results of 'map'.
95   SmallVector<Value, 4> results;
96 };
97 
98 } // namespace affine
99 } // namespace mlir
100 
101 #endif // MLIR_DIALECT_AFFINE_IR_AFFINEVALUEMAP_H
102