MLIR 24.0.0git
ExtendToSupportedTypes.cpp
Go to the documentation of this file.
1//===- ExtendToSupportedTypes.cpp - Legalize functions on unsupported floats
2//----------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements legalizing math operations on unsupported floating-point
11// types through arith.extf and arith.truncf.
12//
13//===----------------------------------------------------------------------===//
14
19#include "mlir/IR/Diagnostics.h"
23#include "llvm/ADT/STLExtras.h"
24#include "llvm/ADT/SetVector.h"
25
26namespace mlir::math {
27#define GEN_PASS_DEF_MATHEXTENDTOSUPPORTEDTYPES
28#include "mlir/Dialect/Math/Transforms/Passes.h.inc"
29} // namespace mlir::math
30
31using namespace mlir;
32
33namespace {
34struct ExtendToSupportedTypesRewritePattern final : ConversionPattern {
35 ExtendToSupportedTypesRewritePattern(const TypeConverter &converter,
36 MLIRContext *context)
37 : ConversionPattern(converter, MatchAnyOpTypeTag{}, 1, context) {}
38 LogicalResult
39 matchAndRewrite(Operation *op, ArrayRef<Value> operands,
40 ConversionPatternRewriter &rewriter) const override;
41};
42
43struct ExtendToSupportedTypesPass
44 : mlir::math::impl::MathExtendToSupportedTypesBase<
45 ExtendToSupportedTypesPass> {
46 using math::impl::MathExtendToSupportedTypesBase<
47 ExtendToSupportedTypesPass>::MathExtendToSupportedTypesBase;
48
49 void runOnOperation() override;
50};
51} // namespace
52
54 TypeConverter &typeConverter, const SetVector<Type> &sourceTypes,
55 Type targetType) {
56
57 typeConverter.addConversion(
58 [](Type type) -> std::optional<Type> { return type; });
59 typeConverter.addConversion(
60 [&sourceTypes, targetType](FloatType type) -> std::optional<Type> {
61 if (!sourceTypes.contains(type))
62 return targetType;
63
64 return std::nullopt;
65 });
66 typeConverter.addConversion(
67 [&sourceTypes, targetType](ShapedType type) -> std::optional<Type> {
68 if (auto elemTy = dyn_cast<FloatType>(type.getElementType()))
69 if (!sourceTypes.contains(elemTy))
70 return type.clone(targetType);
71
72 return std::nullopt;
73 });
74 typeConverter.addTargetMaterialization(
75 [](OpBuilder &b, Type target, ValueRange input, Location loc) {
76 auto extFOp = arith::ExtFOp::create(b, loc, TypeRange{target},
77 ValueRange{input.front()},
78 arith::ExtFOp::Properties{});
79 extFOp.setFastmath(arith::FastMathFlags::contract);
80 return extFOp;
81 });
82}
83
85 ConversionTarget &target, TypeConverter &typeConverter) {
86 target.markUnknownOpDynamicallyLegal([&typeConverter](Operation *op) -> bool {
87 if (isa<MathDialect>(op->getDialect()))
88 return typeConverter.isLegal(op);
89 return true;
90 });
91 target.addLegalOp<FmaOp>();
92 target.addLegalOp<arith::ExtFOp, arith::TruncFOp>();
93}
94
95LogicalResult ExtendToSupportedTypesRewritePattern::matchAndRewrite(
96 Operation *op, ArrayRef<Value> operands,
97 ConversionPatternRewriter &rewriter) const {
98 Location loc = op->getLoc();
99 const TypeConverter *converter = getTypeConverter();
100 FailureOr<Operation *> legalized =
101 convertOpResultTypes(op, operands, *converter, rewriter);
102 if (failed(legalized))
103 return failure();
104
105 SmallVector<Value> results = (*legalized)->getResults();
106 for (auto [result, newType, origType] : llvm::zip_equal(
107 results, (*legalized)->getResultTypes(), op->getResultTypes())) {
108 if (newType != origType) {
109 auto truncFOp = arith::TruncFOp::create(rewriter, loc, origType, result);
110 truncFOp.setFastmath(arith::FastMathFlags::contract);
111 result = truncFOp.getResult();
112 }
113 }
114 rewriter.replaceOp(op, results);
115 return success();
116}
117
119 RewritePatternSet &patterns, const TypeConverter &typeConverter) {
120 patterns.add<ExtendToSupportedTypesRewritePattern>(typeConverter,
121 patterns.getContext());
122}
123
124void ExtendToSupportedTypesPass::runOnOperation() {
125 Operation *op = getOperation();
126 MLIRContext *ctx = &getContext();
127
128 // Parse target type
129 FloatType targetType = arith::parseFloatType(ctx, targetTypeStr);
130 if (!targetType) {
131 emitError(UnknownLoc::get(ctx), "could not map target type '" +
132 targetTypeStr +
133 "' to a known floating-point type");
134 return signalPassFailure();
135 }
136
137 // Parse source types
138 llvm::SetVector<Type> sourceTypes;
139 for (const auto &extraTypeStr : extraTypeStrs) {
140 FloatType extraType = arith::parseFloatType(ctx, extraTypeStr);
141 if (!extraType) {
142 emitError(UnknownLoc::get(ctx), "could not map source type '" +
143 extraTypeStr +
144 "' to a known floating-point type");
145 return signalPassFailure();
146 }
147 sourceTypes.insert(extraType);
148 }
149 // f64 and f32 are implicitly supported
150 Builder b(ctx);
151 sourceTypes.insert(b.getF64Type());
152 sourceTypes.insert(b.getF32Type());
153
154 TypeConverter typeConverter;
155 math::populateExtendToSupportedTypesTypeConverter(typeConverter, sourceTypes,
156 targetType);
157 ConversionTarget target(*ctx);
159 RewritePatternSet patterns(ctx);
160 math::populateExtendToSupportedTypesPatterns(patterns, typeConverter);
161 if (failed(applyPartialConversion(op, target, std::move(patterns))))
162 return signalPassFailure();
163}
return success()
b
Return true if permutation is a valid permutation of the outer_dims_perm (case OuterOrInnerPerm::Oute...
b getContext())
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:63
This class helps build Operations.
Definition Builders.h:210
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
Dialect * getDialect()
Return the dialect this operation is associated with, or nullptr if the associated dialect is not loa...
Definition Operation.h:237
Location getLoc()
The source location the operation was defined or derived from.
Definition Operation.h:240
result_type_range getResultTypes()
Definition Operation.h:453
MLIRContext * getContext() const
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
This class provides an abstraction over the various different ranges of value types.
Definition TypeRange.h:40
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition Types.h:74
This class provides an abstraction over the different types of ranges over Values.
Definition ValueRange.h:389
FloatType parseFloatType(MLIRContext *ctx, StringRef name)
Definition Utils.cpp:365
void populateExtendToSupportedTypesPatterns(RewritePatternSet &patterns, const TypeConverter &typeConverter)
void populateExtendToSupportedTypesConversionTarget(ConversionTarget &target, TypeConverter &typeConverter)
void populateExtendToSupportedTypesTypeConverter(TypeConverter &typeConverter, const SetVector< Type > &sourceTypes, Type targetType)
detail::InFlightRemark failed(Location loc, RemarkOpts opts)
Report an optimization remark that failed.
Definition Remarks.h:732
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
llvm::SetVector< T, Vector, Set, N > SetVector
Definition LLVM.h:125