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