154 lines
6.4 KiB
C++
154 lines
6.4 KiB
C++
//===- Utils.h - General Arith transformation utilities ----*- 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This header file defines prototypes for various transformation utilities for
|
|
// the Arith dialect. These are not passes by themselves but are used
|
|
// either by passes, optimization sequences, or in turn by other transformation
|
|
// utilities.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef MLIR_DIALECT_ARITH_UTILS_UTILS_H
|
|
#define MLIR_DIALECT_ARITH_UTILS_UTILS_H
|
|
|
|
#include "mlir/Dialect/Arith/IR/Arith.h"
|
|
#include "mlir/IR/Matchers.h"
|
|
#include "mlir/IR/PatternMatch.h"
|
|
#include "mlir/IR/Value.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
|
|
namespace mlir {
|
|
|
|
using ReassociationIndices = SmallVector<int64_t, 2>;
|
|
|
|
/// Infer the output shape for a {memref|tensor}.expand_shape when it is
|
|
/// possible to do so.
|
|
///
|
|
/// Note: This should *only* be used to implement
|
|
/// `ExpandShapeOp::inferOutputShape` in both the memref and tensor namespaces.
|
|
/// If you need to infer the output shape you should use the static method of
|
|
/// `ExpandShapeOp` instead of calling this.
|
|
///
|
|
/// `inputShape` is the shape of the tensor or memref being expanded as a
|
|
/// sequence of SSA values or constants. `expandedType` is the output shape of
|
|
/// the expand_shape operation. `reassociation` is the reassociation denoting
|
|
/// the output dims each input dim is mapped to.
|
|
///
|
|
/// Returns the output shape in `outputShape` and `staticOutputShape`, following
|
|
/// the conventions for the output_shape and static_output_shape inputs to the
|
|
/// expand_shape ops.
|
|
std::optional<SmallVector<OpFoldResult>>
|
|
inferExpandShapeOutputShape(OpBuilder &b, Location loc, ShapedType expandedType,
|
|
ArrayRef<ReassociationIndices> reassociation,
|
|
ArrayRef<OpFoldResult> inputShape);
|
|
|
|
/// Matches a ConstantIndexOp.
|
|
detail::op_matcher<arith::ConstantIndexOp> matchConstantIndex();
|
|
|
|
llvm::SmallBitVector getPositionsOfShapeOne(unsigned rank,
|
|
ArrayRef<int64_t> shape);
|
|
|
|
/// Converts an OpFoldResult to a Value. Returns the fold result if it casts to
|
|
/// a Value or creates a ConstantOp if it casts to an Integer Attribute.
|
|
/// Other attribute types are not supported.
|
|
Value getValueOrCreateConstantIntOp(OpBuilder &b, Location loc,
|
|
OpFoldResult ofr);
|
|
|
|
/// Converts an OpFoldResult to a Value. Returns the fold result if it casts to
|
|
/// a Value or creates a ConstantIndexOp if it casts to an Integer Attribute.
|
|
/// Other attribute types are not supported.
|
|
Value getValueOrCreateConstantIndexOp(OpBuilder &b, Location loc,
|
|
OpFoldResult ofr);
|
|
|
|
/// Similar to the other overload, but converts multiple OpFoldResults into
|
|
/// Values.
|
|
SmallVector<Value>
|
|
getValueOrCreateConstantIndexOp(OpBuilder &b, Location loc,
|
|
ArrayRef<OpFoldResult> valueOrAttrVec);
|
|
|
|
/// Create a cast from an index-like value (index or integer) to another
|
|
/// index-like value. If the value type and the target type are the same, it
|
|
/// returns the original value.
|
|
Value getValueOrCreateCastToIndexLike(OpBuilder &b, Location loc,
|
|
Type targetType, Value value);
|
|
|
|
/// Converts a scalar value `operand` to type `toType`. If the value doesn't
|
|
/// convert, a warning will be issued and the operand is returned as is (which
|
|
/// will presumably yield a verification issue downstream).
|
|
Value convertScalarToDtype(OpBuilder &b, Location loc, Value operand,
|
|
Type toType, bool isUnsignedCast);
|
|
|
|
/// Create a constant of type `type` at location `loc` whose value is `value`
|
|
/// (an APInt or APFloat whose type must match the element type of `type`).
|
|
/// If `type` is a shaped type, create a splat constant of the given value.
|
|
/// Constants are folded if possible.
|
|
Value createScalarOrSplatConstant(OpBuilder &builder, Location loc, Type type,
|
|
const APInt &value);
|
|
Value createScalarOrSplatConstant(OpBuilder &builder, Location loc, Type type,
|
|
int64_t value);
|
|
Value createScalarOrSplatConstant(OpBuilder &builder, Location loc, Type type,
|
|
const APFloat &value);
|
|
|
|
/// Returns the int type of the integer in ofr.
|
|
/// Other attribute types are not supported.
|
|
Type getType(OpFoldResult ofr);
|
|
|
|
/// Helper struct to build simple arithmetic quantities with minimal type
|
|
/// inference support.
|
|
struct ArithBuilder {
|
|
ArithBuilder(
|
|
OpBuilder &b, Location loc,
|
|
arith::IntegerOverflowFlags ovf = arith::IntegerOverflowFlags::none)
|
|
: b(b), loc(loc), ovf(ovf) {}
|
|
|
|
Value _and(Value lhs, Value rhs);
|
|
Value add(Value lhs, Value rhs);
|
|
Value sub(Value lhs, Value rhs);
|
|
Value mul(Value lhs, Value rhs);
|
|
Value select(Value cmp, Value lhs, Value rhs);
|
|
Value sgt(Value lhs, Value rhs);
|
|
Value slt(Value lhs, Value rhs);
|
|
|
|
private:
|
|
OpBuilder &b;
|
|
Location loc;
|
|
arith::IntegerOverflowFlags ovf;
|
|
};
|
|
|
|
/// ArithBuilder specialized specifically for tensor/memref indexing
|
|
/// calculations. Those calculations generally should never signed overflow and
|
|
/// always use signed integers, so we can set oveflow flags accordingly.
|
|
struct ArithIndexingBuilder : public ArithBuilder {
|
|
ArithIndexingBuilder(OpBuilder &b, Location loc)
|
|
: ArithBuilder(b, loc, arith::IntegerOverflowFlags::nsw) {}
|
|
};
|
|
|
|
namespace arith {
|
|
|
|
// Build the product of a sequence.
|
|
// If values = (v0, v1, ..., vn) than the returned
|
|
// value is v0 * v1 * ... * vn.
|
|
// All values must have the same type.
|
|
//
|
|
// The version without `resultType` must contain at least one element in values.
|
|
// Then the result will have the same type as the elements in `values`.
|
|
// If `values` is empty in the version with `resultType` returns 1 with type
|
|
// `resultType`.
|
|
Value createProduct(OpBuilder &builder, Location loc, ArrayRef<Value> values);
|
|
Value createProduct(OpBuilder &builder, Location loc, ArrayRef<Value> values,
|
|
Type resultType);
|
|
|
|
// Map strings to float types. Returns nullptr if the name is not a known
|
|
// floating-point type.
|
|
FloatType parseFloatType(MLIRContext *ctx, StringRef name);
|
|
|
|
} // namespace arith
|
|
} // namespace mlir
|
|
|
|
#endif // MLIR_DIALECT_ARITH_UTILS_UTILS_H
|