109 lines
4.3 KiB
C++
109 lines
4.3 KiB
C++
//===- AffineValueMap.h - MLIR Affine Value Map Class -----------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// An AffineValueMap is an affine map plus its ML value operands and results for
|
|
// analysis purposes.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef MLIR_DIALECT_AFFINE_IR_AFFINEVALUEMAP_H
|
|
#define MLIR_DIALECT_AFFINE_IR_AFFINEVALUEMAP_H
|
|
|
|
#include "mlir/IR/AffineMap.h"
|
|
#include "mlir/IR/OperationSupport.h"
|
|
#include "mlir/IR/Value.h"
|
|
|
|
namespace mlir {
|
|
namespace affine {
|
|
|
|
/// An AffineValueMap is an affine map plus its ML value operands and
|
|
/// results for analysis purposes. The structure is still a tree form that is
|
|
/// same as that of an affine map or an AffineApplyOp. However, its operands,
|
|
/// results, and its map can themselves change as a result of
|
|
/// substitutions, simplifications, and other analysis.
|
|
// An affine value map can readily be constructed from an AffineApplyOp, or an
|
|
// AffineBound of a AffineForOp. It can be further transformed, substituted
|
|
// into, or simplified. Unlike AffineMap's, AffineValueMap's are created and
|
|
// destroyed during analysis. Only the AffineMap expressions that are pointed by
|
|
// them are unique'd. An affine value map, and the operations on it, maintain
|
|
// the invariant that operands are always positionally aligned with the
|
|
// AffineDimExpr and AffineSymbolExpr in the underlying AffineMap.
|
|
class AffineValueMap {
|
|
public:
|
|
// Creates an empty AffineValueMap (users should call 'reset' to reset map
|
|
// and operands).
|
|
AffineValueMap() = default;
|
|
AffineValueMap(AffineMap map, ValueRange operands, ValueRange results = {});
|
|
|
|
~AffineValueMap();
|
|
|
|
// Resets this AffineValueMap with 'map', 'operands', and 'results'.
|
|
void reset(AffineMap map, ValueRange operands, ValueRange results = {});
|
|
|
|
/// Composes all incoming affine.apply ops and then simplifies and
|
|
/// canonicalizes the map and operands. This can change the number of
|
|
/// operands, but the result count remains the same.
|
|
void composeSimplifyAndCanonicalize();
|
|
|
|
/// Return the value map that is the difference of value maps 'a' and 'b',
|
|
/// represented as an affine map and its operands. The output map + operands
|
|
/// are canonicalized and simplified.
|
|
static void difference(const AffineValueMap &a, const AffineValueMap &b,
|
|
AffineValueMap *res);
|
|
|
|
/// Return true if the idx^th result can be proved to be a multiple of
|
|
/// 'factor', false otherwise.
|
|
inline bool isMultipleOf(unsigned idx, int64_t factor) const;
|
|
|
|
/// Return true if the idx^th result depends on 'value', false otherwise.
|
|
bool isFunctionOf(unsigned idx, Value value) const;
|
|
|
|
/// Return true if the result at 'idx' is a constant, false
|
|
/// otherwise.
|
|
bool isConstant(unsigned idx) const;
|
|
|
|
/// Return true if this is an identity map.
|
|
bool isIdentity() const;
|
|
|
|
void setResult(unsigned i, AffineExpr e) { map.setResult(i, e); }
|
|
AffineExpr getResult(unsigned i) { return map.getResult(i); }
|
|
inline unsigned getNumOperands() const { return operands.size(); }
|
|
inline unsigned getNumDims() const { return map.getNumDims(); }
|
|
inline unsigned getNumSymbols() const { return map.getNumSymbols(); }
|
|
inline unsigned getNumResults() const { return map.getNumResults(); }
|
|
|
|
Value getOperand(unsigned i) const;
|
|
ArrayRef<Value> getOperands() const;
|
|
AffineMap getAffineMap() const;
|
|
|
|
/// Attempts to canonicalize the map and operands. Return success if the map
|
|
/// and/or operands have been modified.
|
|
LogicalResult canonicalize();
|
|
|
|
/// Checks if the application of this map to its operands is semantically
|
|
/// equal to `other`'s.
|
|
bool operator==(const AffineValueMap &other) const;
|
|
bool operator!=(const AffineValueMap &other) const {
|
|
return !(*this == other);
|
|
}
|
|
|
|
private:
|
|
// A mutable affine map.
|
|
MutableAffineMap map;
|
|
|
|
// TODO: make these trailing objects?
|
|
/// The SSA operands binding to the dim's and symbols of 'map'.
|
|
SmallVector<Value, 4> operands;
|
|
/// The SSA results binding to the results of 'map'.
|
|
SmallVector<Value, 4> results;
|
|
};
|
|
|
|
} // namespace affine
|
|
} // namespace mlir
|
|
|
|
#endif // MLIR_DIALECT_AFFINE_IR_AFFINEVALUEMAP_H
|