diff --git a/mlir/include/mlir/Transforms/DialectConversion.h b/mlir/include/mlir/Transforms/DialectConversion.h index 45ad6f8586daa..5ff36160dd616 100644 --- a/mlir/include/mlir/Transforms/DialectConversion.h +++ b/mlir/include/mlir/Transforms/DialectConversion.h @@ -163,14 +163,14 @@ class TypeConverter { /// All of the following materializations require function objects that are /// convertible to the following form: - /// `std::optional(OpBuilder &, T, ValueRange, Location)`, + /// `Value(OpBuilder &, T, ValueRange, Location)`, /// where `T` is any subclass of `Type`. This function is responsible for /// creating an operation, using the OpBuilder and Location provided, that /// "casts" a range of values into a single value of the given type `T`. It - /// must return a Value of the type `T` on success, an `std::nullopt` if - /// it failed but other materialization can be attempted, and `nullptr` on - /// unrecoverable failure. Materialization functions must be provided when a - /// type conversion may persist after the conversion has finished. + /// must return a Value of the type `T` on success and `nullptr` if + /// it failed but other materialization should be attempted. Materialization + /// functions must be provided when a type conversion may persist after the + /// conversion has finished. /// /// Note: Target materializations may optionally accept an additional Type /// parameter, which is the original type of the SSA value. @@ -335,14 +335,14 @@ class TypeConverter { /// conversion. /// /// Arguments: builder, result type, inputs, location - using MaterializationCallbackFn = std::function( - OpBuilder &, Type, ValueRange, Location)>; + using MaterializationCallbackFn = + std::function; /// The signature of the callback used to materialize a target conversion. /// /// Arguments: builder, result type, inputs, location, original type - using TargetMaterializationCallbackFn = std::function( - OpBuilder &, Type, ValueRange, Location, Type)>; + using TargetMaterializationCallbackFn = + std::function; /// The signature of the callback used to convert a type attribute. using TypeAttributeConversionCallbackFn = @@ -396,10 +396,10 @@ class TypeConverter { MaterializationCallbackFn wrapMaterialization(FnT &&callback) const { return [callback = std::forward(callback)]( OpBuilder &builder, Type resultType, ValueRange inputs, - Location loc) -> std::optional { + Location loc) -> Value { if (T derivedType = dyn_cast(resultType)) return callback(builder, derivedType, inputs, loc); - return std::nullopt; + return Value(); }; } @@ -417,10 +417,10 @@ class TypeConverter { wrapTargetMaterialization(FnT &&callback) const { return [callback = std::forward(callback)]( OpBuilder &builder, Type resultType, ValueRange inputs, - Location loc, Type originalType) -> std::optional { + Location loc, Type originalType) -> Value { if (T derivedType = dyn_cast(resultType)) return callback(builder, derivedType, inputs, loc, originalType); - return std::nullopt; + return Value(); }; } /// With callback of form: @@ -433,7 +433,7 @@ class TypeConverter { return wrapTargetMaterialization( [callback = std::forward(callback)]( OpBuilder &builder, T resultType, ValueRange inputs, Location loc, - Type originalType) -> std::optional { + Type originalType) -> Value { return callback(builder, resultType, inputs, loc); }); } diff --git a/mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp b/mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp index 7760373913761..9b5aeb3fef30b 100644 --- a/mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp +++ b/mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp @@ -282,9 +282,9 @@ class AsyncRuntimeTypeConverter : public TypeConverter { // Use UnrealizedConversionCast as the bridge so that we don't need to pull // in patterns for other dialects. auto addUnrealizedCast = [](OpBuilder &builder, Type type, - ValueRange inputs, Location loc) { + ValueRange inputs, Location loc) -> Value { auto cast = builder.create(loc, type, inputs); - return std::optional(cast.getResult(0)); + return cast.getResult(0); }; addSourceMaterialization(addUnrealizedCast); diff --git a/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp b/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp index 5a92fa839e984..4e7758bf46d9c 100644 --- a/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp +++ b/mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp @@ -158,36 +158,35 @@ LLVMTypeConverter::LLVMTypeConverter(MLIRContext *ctx, // original block argument type. The dialect conversion framework will then // insert a target materialization from the original block argument type to // a legal type. - addArgumentMaterialization( - [&](OpBuilder &builder, UnrankedMemRefType resultType, ValueRange inputs, - Location loc) -> std::optional { - if (inputs.size() == 1) { - // Bare pointers are not supported for unranked memrefs because a - // memref descriptor cannot be built just from a bare pointer. - return std::nullopt; - } - Value desc = UnrankedMemRefDescriptor::pack(builder, loc, *this, - resultType, inputs); - // An argument materialization must return a value of type - // `resultType`, so insert a cast from the memref descriptor type - // (!llvm.struct) to the original memref type. - return builder.create(loc, resultType, desc) - .getResult(0); - }); + addArgumentMaterialization([&](OpBuilder &builder, + UnrankedMemRefType resultType, + ValueRange inputs, Location loc) { + if (inputs.size() == 1) { + // Bare pointers are not supported for unranked memrefs because a + // memref descriptor cannot be built just from a bare pointer. + return Value(); + } + Value desc = + UnrankedMemRefDescriptor::pack(builder, loc, *this, resultType, inputs); + // An argument materialization must return a value of type + // `resultType`, so insert a cast from the memref descriptor type + // (!llvm.struct) to the original memref type. + return builder.create(loc, resultType, desc) + .getResult(0); + }); addArgumentMaterialization([&](OpBuilder &builder, MemRefType resultType, - ValueRange inputs, - Location loc) -> std::optional { + ValueRange inputs, Location loc) { Value desc; if (inputs.size() == 1) { // This is a bare pointer. We allow bare pointers only for function entry // blocks. BlockArgument barePtr = dyn_cast(inputs.front()); if (!barePtr) - return std::nullopt; + return Value(); Block *block = barePtr.getOwner(); if (!block->isEntryBlock() || !isa(block->getParentOp())) - return std::nullopt; + return Value(); desc = MemRefDescriptor::fromStaticShape(builder, loc, *this, resultType, inputs[0]); } else { @@ -202,19 +201,17 @@ LLVMTypeConverter::LLVMTypeConverter(MLIRContext *ctx, // Add generic source and target materializations to handle cases where // non-LLVM types persist after an LLVM conversion. addSourceMaterialization([&](OpBuilder &builder, Type resultType, - ValueRange inputs, - Location loc) -> std::optional { + ValueRange inputs, Location loc) { if (inputs.size() != 1) - return std::nullopt; + return Value(); return builder.create(loc, resultType, inputs) .getResult(0); }); addTargetMaterialization([&](OpBuilder &builder, Type resultType, - ValueRange inputs, - Location loc) -> std::optional { + ValueRange inputs, Location loc) { if (inputs.size() != 1) - return std::nullopt; + return Value(); return builder.create(loc, resultType, inputs) .getResult(0); diff --git a/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp index 83de9b37974f6..0b3a494794f3f 100644 --- a/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp +++ b/mlir/lib/Dialect/EmitC/Transforms/TypeConversions.cpp @@ -16,12 +16,10 @@ using namespace mlir; namespace { -std::optional materializeAsUnrealizedCast(OpBuilder &builder, - Type resultType, - ValueRange inputs, - Location loc) { +Value materializeAsUnrealizedCast(OpBuilder &builder, Type resultType, + ValueRange inputs, Location loc) { if (inputs.size() != 1) - return std::nullopt; + return Value(); return builder.create(loc, resultType, inputs) .getResult(0); diff --git a/mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp b/mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp index 656090314d650..f5700059f68ee 100644 --- a/mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp +++ b/mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp @@ -659,9 +659,9 @@ static Type convertMemrefType(const spirv::TargetEnv &targetEnv, /// This function is meant to handle the **compute** side; so it does not /// involve storage classes in its logic. The storage side is expected to be /// handled by MemRef conversion logic. -static std::optional castToSourceType(const spirv::TargetEnv &targetEnv, - OpBuilder &builder, Type type, - ValueRange inputs, Location loc) { +static Value castToSourceType(const spirv::TargetEnv &targetEnv, + OpBuilder &builder, Type type, ValueRange inputs, + Location loc) { // We can only cast one value in SPIR-V. if (inputs.size() != 1) { auto castOp = builder.create(loc, type, inputs); @@ -1459,7 +1459,7 @@ SPIRVTypeConverter::SPIRVTypeConverter(spirv::TargetEnvAttr targetAttr, addTargetMaterialization([](OpBuilder &builder, Type type, ValueRange inputs, Location loc) { auto cast = builder.create(loc, type, inputs); - return std::optional(cast.getResult(0)); + return cast.getResult(0); }); } diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/SparseIterationToScf.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/SparseIterationToScf.cpp index 04466d198b5b6..e8a40b1e033dd 100644 --- a/mlir/lib/Dialect/SparseTensor/Transforms/SparseIterationToScf.cpp +++ b/mlir/lib/Dialect/SparseTensor/Transforms/SparseIterationToScf.cpp @@ -425,8 +425,7 @@ mlir::SparseIterationTypeConverter::SparseIterationTypeConverter() { addConversion(convertIterSpaceType); addSourceMaterialization([](OpBuilder &builder, IterSpaceType spTp, - ValueRange inputs, - Location loc) -> std::optional { + ValueRange inputs, Location loc) -> Value { return builder .create(loc, TypeRange(spTp), inputs) .getResult(0); diff --git a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/SparseTensorDescriptor.cpp b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/SparseTensorDescriptor.cpp index 6ac26ad550f9f..a3db50573c272 100644 --- a/mlir/lib/Dialect/SparseTensor/Transforms/Utils/SparseTensorDescriptor.cpp +++ b/mlir/lib/Dialect/SparseTensor/Transforms/Utils/SparseTensorDescriptor.cpp @@ -60,11 +60,10 @@ SparseTensorTypeToBufferConverter::SparseTensorTypeToBufferConverter() { // Required by scf.for 1:N type conversion. addSourceMaterialization([](OpBuilder &builder, RankedTensorType tp, - ValueRange inputs, - Location loc) -> std::optional { + ValueRange inputs, Location loc) -> Value { if (!getSparseTensorEncoding(tp)) // Not a sparse tensor. - return std::nullopt; + return Value(); // Sparsifier knows how to cancel out these casts. return genTuple(builder, loc, tp, inputs); }); diff --git a/mlir/lib/Dialect/Tensor/TransformOps/TensorTransformOps.cpp b/mlir/lib/Dialect/Tensor/TransformOps/TensorTransformOps.cpp index f911619d71227..99199252710f9 100644 --- a/mlir/lib/Dialect/Tensor/TransformOps/TensorTransformOps.cpp +++ b/mlir/lib/Dialect/Tensor/TransformOps/TensorTransformOps.cpp @@ -153,29 +153,29 @@ void transform::TypeConversionCastShapeDynamicDimsOp:: converter.addSourceMaterialization([ignoreDynamicInfo]( OpBuilder &builder, Type resultType, ValueRange inputs, - Location loc) -> std::optional { + Location loc) -> Value { if (inputs.size() != 1) { - return std::nullopt; + return Value(); } Value input = inputs[0]; if (!ignoreDynamicInfo && !tensor::preservesStaticInformation(resultType, input.getType())) { - return std::nullopt; + return Value(); } if (!tensor::CastOp::areCastCompatible(input.getType(), resultType)) { - return std::nullopt; + return Value(); } return builder.create(loc, resultType, input).getResult(); }); converter.addTargetMaterialization([](OpBuilder &builder, Type resultType, ValueRange inputs, - Location loc) -> std::optional { + Location loc) -> Value { if (inputs.size() != 1) { - return std::nullopt; + return Value(); } Value input = inputs[0]; if (!tensor::CastOp::areCastCompatible(input.getType(), resultType)) { - return std::nullopt; + return Value(); } return builder.create(loc, resultType, input).getResult(); }); diff --git a/mlir/lib/Dialect/Tosa/Transforms/TosaTypeConverters.cpp b/mlir/lib/Dialect/Tosa/Transforms/TosaTypeConverters.cpp index d2650de8cd7f0..3b697a2ee3e47 100644 --- a/mlir/lib/Dialect/Tosa/Transforms/TosaTypeConverters.cpp +++ b/mlir/lib/Dialect/Tosa/Transforms/TosaTypeConverters.cpp @@ -33,18 +33,18 @@ void mlir::tosa::populateTosaTypeConversion(TypeConverter &converter) { }); converter.addSourceMaterialization([&](OpBuilder &builder, Type resultType, ValueRange inputs, - Location loc) -> std::optional { + Location loc) -> Value { if (inputs.size() != 1) - return std::nullopt; + return Value(); return builder.create(loc, resultType, inputs) .getResult(0); }); converter.addTargetMaterialization([&](OpBuilder &builder, Type resultType, ValueRange inputs, - Location loc) -> std::optional { + Location loc) -> Value { if (inputs.size() != 1) - return std::nullopt; + return Value(); return builder.create(loc, resultType, inputs) .getResult(0); diff --git a/mlir/lib/Transforms/Utils/DialectConversion.cpp b/mlir/lib/Transforms/Utils/DialectConversion.cpp index b8d0329906a86..3cfcaa965f354 100644 --- a/mlir/lib/Transforms/Utils/DialectConversion.cpp +++ b/mlir/lib/Transforms/Utils/DialectConversion.cpp @@ -2812,8 +2812,8 @@ Value TypeConverter::materializeArgumentConversion(OpBuilder &builder, ValueRange inputs) const { for (const MaterializationCallbackFn &fn : llvm::reverse(argumentMaterializations)) - if (std::optional result = fn(builder, resultType, inputs, loc)) - return *result; + if (Value result = fn(builder, resultType, inputs, loc)) + return result; return nullptr; } @@ -2822,8 +2822,8 @@ Value TypeConverter::materializeSourceConversion(OpBuilder &builder, ValueRange inputs) const { for (const MaterializationCallbackFn &fn : llvm::reverse(sourceMaterializations)) - if (std::optional result = fn(builder, resultType, inputs, loc)) - return *result; + if (Value result = fn(builder, resultType, inputs, loc)) + return result; return nullptr; } @@ -2833,9 +2833,8 @@ Value TypeConverter::materializeTargetConversion(OpBuilder &builder, Type originalType) const { for (const TargetMaterializationCallbackFn &fn : llvm::reverse(targetMaterializations)) - if (std::optional result = - fn(builder, resultType, inputs, loc, originalType)) - return *result; + if (Value result = fn(builder, resultType, inputs, loc, originalType)) + return result; return nullptr; } diff --git a/mlir/test/lib/Conversion/OneToNTypeConversion/TestOneToNTypeConversionPass.cpp b/mlir/test/lib/Conversion/OneToNTypeConversion/TestOneToNTypeConversionPass.cpp index 1ea65109bf79d..5c03ac12d1e58 100644 --- a/mlir/test/lib/Conversion/OneToNTypeConversion/TestOneToNTypeConversionPass.cpp +++ b/mlir/test/lib/Conversion/OneToNTypeConversion/TestOneToNTypeConversionPass.cpp @@ -180,9 +180,8 @@ buildGetTupleElementOps(OpBuilder &builder, TypeRange resultTypes, Value input, /// /// This function has been copied (with small adaptions) from /// TestDecomposeCallGraphTypes.cpp. -static std::optional buildMakeTupleOp(OpBuilder &builder, - TupleType resultType, - ValueRange inputs, Location loc) { +static Value buildMakeTupleOp(OpBuilder &builder, TupleType resultType, + ValueRange inputs, Location loc) { // Build one value for each element at this nesting level. SmallVector elements; elements.reserve(resultType.getTypes().size()); @@ -201,13 +200,13 @@ static std::optional buildMakeTupleOp(OpBuilder &builder, inputIt += numNestedFlattenedTypes; // Recurse on the values for the nested TupleType. - std::optional res = buildMakeTupleOp(builder, nestedTupleType, - nestedFlattenedelements, loc); - if (!res.has_value()) - return {}; + Value res = buildMakeTupleOp(builder, nestedTupleType, + nestedFlattenedelements, loc); + if (!res) + return Value(); // The tuple constructed by the conversion is the element value. - elements.push_back(res.value()); + elements.push_back(res); } else { // Base case: take one input as is. elements.push_back(*inputIt++); diff --git a/mlir/test/lib/Dialect/Arith/TestEmulateWideInt.cpp b/mlir/test/lib/Dialect/Arith/TestEmulateWideInt.cpp index a6678995fc6f6..738d4ee59cbde 100644 --- a/mlir/test/lib/Dialect/Arith/TestEmulateWideInt.cpp +++ b/mlir/test/lib/Dialect/Arith/TestEmulateWideInt.cpp @@ -59,7 +59,7 @@ struct TestEmulateWideIntPass // TODO: Consider extending `arith.bitcast` to support scalar-to-1D-vector // casts (and vice versa) and using it insted of `llvm.bitcast`. auto addBitcast = [](OpBuilder &builder, Type type, ValueRange inputs, - Location loc) -> std::optional { + Location loc) -> Value { auto cast = builder.create(loc, type, inputs); return cast->getResult(0); }; diff --git a/mlir/test/lib/Dialect/Func/TestDecomposeCallGraphTypes.cpp b/mlir/test/lib/Dialect/Func/TestDecomposeCallGraphTypes.cpp index 0d7dce2240f4c..92216da9f201e 100644 --- a/mlir/test/lib/Dialect/Func/TestDecomposeCallGraphTypes.cpp +++ b/mlir/test/lib/Dialect/Func/TestDecomposeCallGraphTypes.cpp @@ -43,9 +43,8 @@ static LogicalResult buildDecomposeTuple(OpBuilder &builder, Location loc, /// Creates a `test.make_tuple` op out of the given inputs building a tuple of /// type `resultType`. If that type is nested, each nested tuple is built /// recursively with another `test.make_tuple` op. -static std::optional buildMakeTupleOp(OpBuilder &builder, - TupleType resultType, - ValueRange inputs, Location loc) { +static Value buildMakeTupleOp(OpBuilder &builder, TupleType resultType, + ValueRange inputs, Location loc) { // Build one value for each element at this nesting level. SmallVector elements; elements.reserve(resultType.getTypes().size()); @@ -64,13 +63,13 @@ static std::optional buildMakeTupleOp(OpBuilder &builder, inputIt += numNestedFlattenedTypes; // Recurse on the values for the nested TupleType. - std::optional res = buildMakeTupleOp(builder, nestedTupleType, - nestedFlattenedelements, loc); - if (!res.has_value()) - return {}; + Value res = buildMakeTupleOp(builder, nestedTupleType, + nestedFlattenedelements, loc); + if (!res) + return Value(); // The tuple constructed by the conversion is the element value. - elements.push_back(res.value()); + elements.push_back(res); } else { // Base case: take one input as is. elements.push_back(*inputIt++); diff --git a/mlir/test/lib/Dialect/Test/TestPatterns.cpp b/mlir/test/lib/Dialect/Test/TestPatterns.cpp index 3cbc307835afd..3eade0369f765 100644 --- a/mlir/test/lib/Dialect/Test/TestPatterns.cpp +++ b/mlir/test/lib/Dialect/Test/TestPatterns.cpp @@ -1140,9 +1140,8 @@ struct TestTypeConverter : public TypeConverter { /// Hook for materializing a conversion. This is necessary because we generate /// 1->N type mappings. - static std::optional materializeCast(OpBuilder &builder, - Type resultType, - ValueRange inputs, Location loc) { + static Value materializeCast(OpBuilder &builder, Type resultType, + ValueRange inputs, Location loc) { return builder.create(loc, resultType, inputs).getResult(); } }; diff --git a/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.cpp b/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.cpp index a0a7afce66d9a..face4de8e27d3 100644 --- a/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.cpp +++ b/mlir/test/lib/Dialect/Transform/TestTransformDialectExtension.cpp @@ -871,9 +871,9 @@ class TestTypeConverter : public TypeConverter { }); auto unrealizedCastConverter = [&](OpBuilder &builder, Type resultType, ValueRange inputs, - Location loc) -> std::optional { + Location loc) -> Value { if (inputs.size() != 1) - return std::nullopt; + return Value(); return builder.create(loc, resultType, inputs) .getResult(0); }; diff --git a/mlir/test/lib/Transforms/TestDialectConversion.cpp b/mlir/test/lib/Transforms/TestDialectConversion.cpp index 97fe78c35e833..2cc1fb5d39d78 100644 --- a/mlir/test/lib/Transforms/TestDialectConversion.cpp +++ b/mlir/test/lib/Transforms/TestDialectConversion.cpp @@ -44,9 +44,8 @@ struct PDLLTypeConverter : public TypeConverter { return success(); } /// Hook for materializing a conversion. - static std::optional materializeCast(OpBuilder &builder, - Type resultType, - ValueRange inputs, Location loc) { + static Value materializeCast(OpBuilder &builder, Type resultType, + ValueRange inputs, Location loc) { return builder.create(loc, resultType, inputs) .getResult(0); }