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