addSourceMaterialization(
[&](mlir::OpBuilder &builder, mlir::Type resultType,
mlir::ValueRange inputs,
- mlir::Location loc) -> llvm::Optional<mlir::Value> {
+ mlir::Location loc) -> std::optional<mlir::Value> {
if (inputs.size() != 1)
return std::nullopt;
return inputs[0];
addTargetMaterialization(
[&](mlir::OpBuilder &builder, mlir::Type resultType,
mlir::ValueRange inputs,
- mlir::Location loc) -> llvm::Optional<mlir::Value> {
+ mlir::Location loc) -> std::optional<mlir::Value> {
if (inputs.size() != 1)
return std::nullopt;
return inputs[0];
mlir::Type indexType() { return mlir::IntegerType::get(&getContext(), 64); }
// fir.type<name(p : TY'...){f : TY...}> --> llvm<"%name = { ty... }">
- llvm::Optional<mlir::LogicalResult>
+ std::optional<mlir::LogicalResult>
convertRecordType(fir::RecordType derived,
llvm::SmallVectorImpl<mlir::Type> &results,
llvm::ArrayRef<mlir::Type> callStack) {
namespace spirv {
/// Mapping from numeric MemRef memory spaces into SPIR-V symbolic ones.
using MemorySpaceToStorageClassMap =
- std::function<Optional<spirv::StorageClass>(Attribute)>;
+ std::function<std::optional<spirv::StorageClass>(Attribute)>;
/// Maps MemRef memory spaces to storage classes for Vulkan-flavored SPIR-V
/// using the default rule. Returns std::nullopt if the memory space is unknown.
-Optional<spirv::StorageClass> mapMemorySpaceToVulkanStorageClass(Attribute);
+std::optional<spirv::StorageClass>
+ mapMemorySpaceToVulkanStorageClass(Attribute);
/// Maps storage classes for Vulkan-flavored SPIR-V to MemRef memory spaces
/// using the default rule. Returns std::nullopt if the storage class is
/// unsupported.
-Optional<unsigned> mapVulkanStorageClassToMemorySpace(spirv::StorageClass);
+std::optional<unsigned> mapVulkanStorageClassToMemorySpace(spirv::StorageClass);
/// Maps MemRef memory spaces to storage classes for OpenCL-flavored SPIR-V
/// using the default rule. Returns std::nullopt if the memory space is unknown.
-Optional<spirv::StorageClass> mapMemorySpaceToOpenCLStorageClass(Attribute);
+std::optional<spirv::StorageClass>
+ mapMemorySpaceToOpenCLStorageClass(Attribute);
/// Maps storage classes for OpenCL-flavored SPIR-V to MemRef memory spaces
/// using the default rule. Returns std::nullopt if the storage class is
/// unsupported.
-Optional<unsigned> mapOpenCLStorageClassToMemorySpace(spirv::StorageClass);
+std::optional<unsigned> mapOpenCLStorageClassToMemorySpace(spirv::StorageClass);
/// Type converter for converting numeric MemRef memory spaces into SPIR-V
/// symbolic ones.
/// the given `storage` class. This method does not guarantee the uniqueness
/// of extensions; the same extension may be appended multiple times.
void getExtensions(ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
/// The capability requirements for each type are following the
/// ((Capability::A OR Extension::B) AND (Capability::C OR Capability::D))
/// uniqueness of capabilities; the same capability may be appended multiple
/// times.
void getCapabilities(CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
/// Returns the size in bytes for each type. If no size can be calculated,
/// returns `std::nullopt`. Note that if the type has explicit layout, it is
/// also taken into account in calculation.
- Optional<int64_t> getSizeInBytes();
+ std::optional<int64_t> getSizeInBytes();
};
// SPIR-V scalar type: bool type, integer type, floating point type.
static bool isValid(IntegerType);
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
- Optional<int64_t> getSizeInBytes();
+ std::optional<int64_t> getSizeInBytes();
};
// SPIR-V composite type: VectorType, SPIR-V ArrayType, or SPIR-V StructType.
bool hasCompileTimeKnownNumElements() const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
- Optional<int64_t> getSizeInBytes();
+ std::optional<int64_t> getSizeInBytes();
};
// SPIR-V array type
unsigned getArrayStride() const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
/// Returns the array size in bytes. Since array type may have an explicit
/// stride declaration (in bytes), we also include it in the calculation.
- Optional<int64_t> getSizeInBytes();
+ std::optional<int64_t> getSizeInBytes();
};
// SPIR-V image type
// TODO: Add support for Access qualifier
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
};
// SPIR-V pointer type
StorageClass getStorageClass() const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
};
// SPIR-V run-time array type
unsigned getArrayStride() const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
};
// SPIR-V sampled image type
Type getImageType() const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<spirv::StorageClass> storage = std::nullopt);
- void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<spirv::StorageClass> storage = std::nullopt);
+ std::optional<spirv::StorageClass> storage = std::nullopt);
+ void
+ getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
+ std::optional<spirv::StorageClass> storage = std::nullopt);
};
/// SPIR-V struct type. Two kinds of struct types are supported:
ArrayRef<MemberDecorationInfo> memberDecorations = {});
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
};
llvm::hash_code
unsigned getColumns() const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
};
// SPIR-V joint matrix type
MatrixLayout getMatrixLayout() const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
};
// SPIR-V matrix type
Type getElementType() const;
void getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
void getCapabilities(SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage = std::nullopt);
+ std::optional<StorageClass> storage = std::nullopt);
};
} // namespace spirv
ArrayRef<Type> getConvertedTypes() const { return argTypes; }
/// Get the input mapping for the given argument.
- Optional<InputMapping> getInputMapping(unsigned input) const {
+ std::optional<InputMapping> getInputMapping(unsigned input) const {
return remappedInputs[input];
}
unsigned newInputCount = 1);
/// The remapping information for each of the original arguments.
- SmallVector<Optional<InputMapping>, 4> remappedInputs;
+ SmallVector<std::optional<InputMapping>, 4> remappedInputs;
/// The set of new argument types.
SmallVector<Type, 4> argTypes;
/// Register a conversion function. A conversion function must be convertible
/// to any of the following forms(where `T` is a class derived from `Type`:
- /// * Optional<Type>(T)
+ /// * std::optional<Type>(T)
/// - This form represents a 1-1 type conversion. It should return nullptr
/// or `std::nullopt` to signify failure. If `std::nullopt` is returned,
/// the converter is allowed to try another conversion function to
/// perform the conversion.
- /// * Optional<LogicalResult>(T, SmallVectorImpl<Type> &)
+ /// * std::optional<LogicalResult>(T, SmallVectorImpl<Type> &)
/// - This form represents a 1-N type conversion. It should return
/// `failure` or `std::nullopt` to signify a failed conversion. If the
/// new set of types is empty, the type is removed and any usages of the
/// existing value are expected to be removed during conversion. If
/// `std::nullopt` is returned, the converter is allowed to try another
/// conversion function to perform the conversion.
- /// * Optional<LogicalResult>(T, SmallVectorImpl<Type> &, ArrayRef<Type>)
+ /// * std::optional<LogicalResult>(T, SmallVectorImpl<Type> &,
+ /// ArrayRef<Type>)
/// - This form represents a 1-N type conversion supporting recursive
/// types. The first two arguments and the return value are the same as
/// for the regular 1-N form. The third argument is contains is the
/// Register a materialization function, which must be convertible to the
/// following form:
- /// `Optional<Value>(OpBuilder &, T, ValueRange, Location)`,
+ /// `std::optional<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
/// This function converts the type signature of the given block, by invoking
/// 'convertSignatureArg' for each argument. This function should return a
/// valid conversion for the signature on success, std::nullopt otherwise.
- Optional<SignatureConversion> convertBlockSignature(Block *block);
+ std::optional<SignatureConversion> convertBlockSignature(Block *block);
/// Materialize a conversion from a set of types into one result type by
/// generating a cast sequence of some kind. See the respective
/// The signature of the callback used to convert a type. If the new set of
/// types is empty, the type is removed and any usages of the existing value
/// are expected to be removed during conversion.
- using ConversionCallbackFn = std::function<Optional<LogicalResult>(
+ using ConversionCallbackFn = std::function<std::optional<LogicalResult>(
Type, SmallVectorImpl<Type> &, ArrayRef<Type>)>;
/// The signature of the callback used to materialize a conversion.
- using MaterializationCallbackFn =
- std::function<Optional<Value>(OpBuilder &, Type, ValueRange, Location)>;
+ using MaterializationCallbackFn = std::function<std::optional<Value>(
+ OpBuilder &, Type, ValueRange, Location)>;
/// Attempt to materialize a conversion using one of the provided
/// materialization functions.
/// Generate a wrapper for the given callback. This allows for accepting
/// different callback forms, that all compose into a single version.
- /// With callback of form: `Optional<Type>(T)`
+ /// With callback of form: `std::optional<Type>(T)`
template <typename T, typename FnT>
std::enable_if_t<std::is_invocable_v<FnT, T>, ConversionCallbackFn>
wrapCallback(FnT &&callback) {
return wrapCallback<T>(
[callback = std::forward<FnT>(callback)](
T type, SmallVectorImpl<Type> &results, ArrayRef<Type>) {
- if (Optional<Type> resultOpt = callback(type)) {
+ if (std::optional<Type> resultOpt = callback(type)) {
bool wasSuccess = static_cast<bool>(*resultOpt);
if (wasSuccess)
results.push_back(*resultOpt);
- return Optional<LogicalResult>(success(wasSuccess));
+ return std::optional<LogicalResult>(success(wasSuccess));
}
- return Optional<LogicalResult>();
+ return std::optional<LogicalResult>();
});
}
- /// With callback of form: `Optional<LogicalResult>(T, SmallVectorImpl<Type>
+ /// With callback of form: `std::optional<LogicalResult>(T,
+ /// SmallVectorImpl<Type>
/// &)`
template <typename T, typename FnT>
std::enable_if_t<std::is_invocable_v<FnT, T, SmallVectorImpl<Type> &>,
return callback(type, results);
});
}
- /// With callback of form: `Optional<LogicalResult>(T, SmallVectorImpl<Type>
+ /// With callback of form: `std::optional<LogicalResult>(T,
+ /// SmallVectorImpl<Type>
/// &, ArrayRef<Type>)`.
template <typename T, typename FnT>
std::enable_if_t<
wrapCallback(FnT &&callback) {
return [callback = std::forward<FnT>(callback)](
Type type, SmallVectorImpl<Type> &results,
- ArrayRef<Type> callStack) -> Optional<LogicalResult> {
+ ArrayRef<Type> callStack) -> std::optional<LogicalResult> {
T derivedType = type.dyn_cast<T>();
if (!derivedType)
return std::nullopt;
MaterializationCallbackFn wrapMaterialization(FnT &&callback) {
return [callback = std::forward<FnT>(callback)](
OpBuilder &builder, Type resultType, ValueRange inputs,
- Location loc) -> Optional<Value> {
+ Location loc) -> std::optional<Value> {
if (T derivedType = resultType.dyn_cast<T>())
return callback(builder, derivedType, inputs, loc);
return std::nullopt;
/// The signature of the callback used to determine if an operation is
/// dynamically legal on the target.
- using DynamicLegalityCallbackFn = std::function<Optional<bool>(Operation *)>;
+ using DynamicLegalityCallbackFn =
+ std::function<std::optional<bool>(Operation *)>;
ConversionTarget(MLIRContext &ctx) : ctx(ctx) {}
virtual ~ConversionTarget() = default;
//===--------------------------------------------------------------------===//
/// Get the legality action for the given operation.
- Optional<LegalizationAction> getOpAction(OperationName op) const;
+ std::optional<LegalizationAction> getOpAction(OperationName op) const;
/// If the given operation instance is legal on this target, a structure
/// containing legality information is returned. If the operation is not
/// Note: Legality is actually a 4-state: Legal(recursive=true),
/// Legal(recursive=false), Illegal or Unknown, where Unknown is treated
/// either as Legal or Illegal depending on context.
- Optional<LegalOpDetails> isLegal(Operation *op) const;
+ std::optional<LegalOpDetails> isLegal(Operation *op) const;
/// Returns true is operation instance is illegal on this target. Returns
/// false if operation is legal, operation legality wasn't registered by user
};
/// Get the legalization information for the given operation.
- Optional<LegalizationInfo> getOpInfo(OperationName op) const;
+ std::optional<LegalizationInfo> getOpInfo(OperationName op) const;
/// A deterministic mapping of operation name and its respective legality
/// information.
auto addUnrealizedCast = [](OpBuilder &builder, Type type,
ValueRange inputs, Location loc) {
auto cast = builder.create<UnrealizedConversionCastOp>(loc, type, inputs);
- return Optional<Value>(cast.getResult(0));
+ return std::optional<Value>(cast.getResult(0));
};
typeConverter.addSourceMaterialization(addUnrealizedCast);
typeConverter.addTargetMaterialization(addUnrealizedCast);
auto addUnrealizedCast = [](OpBuilder &builder, Type type,
ValueRange inputs, Location loc) {
auto cast = builder.create<UnrealizedConversionCastOp>(loc, type, inputs);
- return Optional<Value>(cast.getResult(0));
+ return std::optional<Value>(cast.getResult(0));
};
addSourceMaterialization(addUnrealizedCast);
addTargetMaterialization(addUnrealizedCast);
}
- static Optional<Type> convertAsyncTypes(Type type) {
+ static std::optional<Type> convertAsyncTypes(Type type) {
if (type.isa<TokenType, GroupType, ValueType>())
return AsyncAPI::opaquePointerType(type.getContext());
// memory allocations as local `alloca`s in the default address space. This
// converter drops the private memory space to support the use case above.
LLVMTypeConverter converter(m.getContext(), options);
- converter.addConversion([&](MemRefType type) -> Optional<Type> {
+ converter.addConversion([&](MemRefType type) -> std::optional<Type> {
if (type.getMemorySpaceAsInt() !=
gpu::GPUDialect::getPrivateAddressSpace())
return std::nullopt;
// before the conversions below since conversions are attempted in reverse
// order and those should take priority.
addConversion([](Type type) {
- return LLVM::isCompatibleType(type) ? llvm::Optional<Type>(type)
+ return LLVM::isCompatibleType(type) ? std::optional<Type>(type)
: std::nullopt;
});
// LLVM container types may (recursively) contain other types that must be
// converted even when the outer type is compatible.
- addConversion([&](LLVM::LLVMPointerType type) -> llvm::Optional<Type> {
+ addConversion([&](LLVM::LLVMPointerType type) -> std::optional<Type> {
if (type.isOpaque())
return type;
if (auto pointee = convertType(type.getElementType()))
return std::nullopt;
});
addConversion([&](LLVM::LLVMStructType type, SmallVectorImpl<Type> &results,
- ArrayRef<Type> callStack) -> llvm::Optional<LogicalResult> {
+ ArrayRef<Type> callStack) -> std::optional<LogicalResult> {
// Fastpath for types that won't be converted by this callback anyway.
if (LLVM::isCompatibleType(type)) {
results.push_back(type);
type.getContext(), convertedSubtypes, type.isPacked()));
return success();
});
- addConversion([&](LLVM::LLVMArrayType type) -> llvm::Optional<Type> {
+ addConversion([&](LLVM::LLVMArrayType type) -> std::optional<Type> {
if (auto element = convertType(type.getElementType()))
return LLVM::LLVMArrayType::get(element, type.getNumElements());
return std::nullopt;
});
- addConversion([&](LLVM::LLVMFunctionType type) -> llvm::Optional<Type> {
+ addConversion([&](LLVM::LLVMFunctionType type) -> std::optional<Type> {
Type convertedResType = convertType(type.getReturnType());
if (!convertedResType)
return std::nullopt;
// value represents a memref.
addArgumentMaterialization(
[&](OpBuilder &builder, UnrankedMemRefType resultType, ValueRange inputs,
- Location loc) -> Optional<Value> {
+ Location loc) -> std::optional<Value> {
if (inputs.size() == 1)
return std::nullopt;
return UnrankedMemRefDescriptor::pack(builder, loc, *this, resultType,
});
addArgumentMaterialization([&](OpBuilder &builder, MemRefType resultType,
ValueRange inputs,
- Location loc) -> Optional<Value> {
+ Location loc) -> std::optional<Value> {
// TODO: bare ptr conversion could be handled here but we would need a way
// to distinguish between FuncOp and other regions.
if (inputs.size() == 1)
// non-LLVM types persist after an LLVM conversion.
addSourceMaterialization([&](OpBuilder &builder, Type resultType,
ValueRange inputs,
- Location loc) -> Optional<Value> {
+ Location loc) -> std::optional<Value> {
if (inputs.size() != 1)
return std::nullopt;
});
addTargetMaterialization([&](OpBuilder &builder, Type resultType,
ValueRange inputs,
- Location loc) -> Optional<Value> {
+ Location loc) -> std::optional<Value> {
if (inputs.size() != 1)
return std::nullopt;
auto addUnrealizedCast = [](OpBuilder &builder, Type type, ValueRange inputs,
Location loc) {
auto cast = builder.create<UnrealizedConversionCastOp>(loc, type, inputs);
- return Optional<Value>(cast.getResult(0));
+ return std::optional<Value>(cast.getResult(0));
};
typeConverter.addSourceMaterialization(addUnrealizedCast);
typeConverter.addTargetMaterialization(addUnrealizedCast);
MAP_FN(spirv::StorageClass::Input, 9) \
MAP_FN(spirv::StorageClass::Output, 10)
-Optional<spirv::StorageClass>
+std::optional<spirv::StorageClass>
spirv::mapMemorySpaceToVulkanStorageClass(Attribute memorySpaceAttr) {
// Handle null memory space attribute specially.
if (!memorySpaceAttr)
#undef STORAGE_SPACE_MAP_FN
}
-Optional<unsigned>
+std::optional<unsigned>
spirv::mapVulkanStorageClassToMemorySpace(spirv::StorageClass storageClass) {
#define STORAGE_SPACE_MAP_FN(storage, space) \
case storage: \
MAP_FN(spirv::StorageClass::Function, 6) \
MAP_FN(spirv::StorageClass::Image, 7)
-Optional<spirv::StorageClass>
+std::optional<spirv::StorageClass>
spirv::mapMemorySpaceToOpenCLStorageClass(Attribute memorySpaceAttr) {
// Handle null memory space attribute specially.
if (!memorySpaceAttr)
#undef STORAGE_SPACE_MAP_FN
}
-Optional<unsigned>
+std::optional<unsigned>
spirv::mapOpenCLStorageClassToMemorySpace(spirv::StorageClass storageClass) {
#define STORAGE_SPACE_MAP_FN(storage, space) \
case storage: \
// Pass through for all other types.
addConversion([](Type type) { return type; });
- addConversion([this](BaseMemRefType memRefType) -> Optional<Type> {
- Optional<spirv::StorageClass> storage =
+ addConversion([this](BaseMemRefType memRefType) -> std::optional<Type> {
+ std::optional<spirv::StorageClass> storage =
this->memorySpaceMap(memRefType.getMemorySpace());
if (!storage) {
LLVM_DEBUG(llvm::dbgs()
auto addUnrealizedCast = [](OpBuilder &builder, Type type, ValueRange inputs,
Location loc) {
auto cast = builder.create<UnrealizedConversionCastOp>(loc, type, inputs);
- return Optional<Value>(cast.getResult(0));
+ return std::optional<Value>(cast.getResult(0));
};
typeConverter.addSourceMaterialization(addUnrealizedCast);
typeConverter.addTargetMaterialization(addUnrealizedCast);
/// Converts SPIR-V struct with a regular (according to `VulkanLayoutUtils`)
/// offset to LLVM struct. Otherwise, the conversion is not supported.
-static Optional<Type>
+static std::optional<Type>
convertStructTypeWithOffset(spirv::StructType type,
LLVMTypeConverter &converter) {
if (type != VulkanLayoutUtils::decorateType(type))
/// Converts SPIR-V array type to LLVM array. Natural stride (according to
/// `VulkanLayoutUtils`) is also mapped to LLVM array. This has to be respected
/// when converting ops that manipulate array types.
-static Optional<Type> convertArrayType(spirv::ArrayType type,
- TypeConverter &converter) {
+static std::optional<Type> convertArrayType(spirv::ArrayType type,
+ TypeConverter &converter) {
unsigned stride = type.getArrayStride();
Type elementType = type.getElementType();
auto sizeInBytes = elementType.cast<spirv::SPIRVType>().getSizeInBytes();
/// Converts SPIR-V runtime array to LLVM array. Since LLVM allows indexing over
/// the bounds, the runtime array is converted to a 0-sized LLVM array. There is
/// no modelling of array stride at the moment.
-static Optional<Type> convertRuntimeArrayType(spirv::RuntimeArrayType type,
- TypeConverter &converter) {
+static std::optional<Type> convertRuntimeArrayType(spirv::RuntimeArrayType type,
+ TypeConverter &converter) {
if (type.getArrayStride() != 0)
return std::nullopt;
auto elementType = converter.convertType(type.getElementType());
/// Converts SPIR-V struct to LLVM struct. There is no support of structs with
/// member decorations. Also, only natural offset is supported.
-static Optional<Type> convertStructType(spirv::StructType type,
- LLVMTypeConverter &converter) {
+static std::optional<Type> convertStructType(spirv::StructType type,
+ LLVMTypeConverter &converter) {
SmallVector<spirv::StructType::MemberDecorationInfo, 4> memberDecorations;
type.getMemberDecorations(memberDecorations);
if (!memberDecorations.empty())
auto addUnrealizedCast = [](OpBuilder &builder, Type type, ValueRange inputs,
Location loc) {
auto cast = builder.create<UnrealizedConversionCastOp>(loc, type, inputs);
- return Optional<Value>(cast.getResult(0));
+ return std::optional<Value>(cast.getResult(0));
};
typeConverter.addSourceMaterialization(addUnrealizedCast);
typeConverter.addTargetMaterialization(addUnrealizedCast);
assert(widestIntSupportedByTarget >= 2 && "Integer type too narrow");
// Allow unknown types.
- addConversion([](Type ty) -> Optional<Type> { return ty; });
+ addConversion([](Type ty) -> std::optional<Type> { return ty; });
// Scalar case.
- addConversion([this](IntegerType ty) -> Optional<Type> {
+ addConversion([this](IntegerType ty) -> std::optional<Type> {
unsigned width = ty.getWidth();
if (width <= maxIntWidth)
return ty;
});
// Vector case.
- addConversion([this](VectorType ty) -> Optional<Type> {
+ addConversion([this](VectorType ty) -> std::optional<Type> {
auto intTy = ty.getElementType().dyn_cast<IntegerType>();
if (!intTy)
return ty;
});
// Function case.
- addConversion([this](FunctionType ty) -> Optional<Type> {
+ addConversion([this](FunctionType ty) -> std::optional<Type> {
// Convert inputs and results, e.g.:
// (i2N, i2N) -> i2N --> (vector<2xiN>, vector<2xiN>) -> vector<2xiN>
SmallVector<Type> inputs;
target
.addDynamicallyLegalOp<DivSIOp, CeilDivSIOp, CeilDivUIOp, FloorDivSIOp,
RemSIOp, MinSIOp, MaxSIOp, ExtSIOp>(
- [&solver](Operation *op) -> Optional<bool> {
+ [&solver](Operation *op) -> std::optional<bool> {
return failed(staticallyNonNegative(solver, op));
});
target.addDynamicallyLegalOp<CmpIOp>(
- [&solver](CmpIOp op) -> Optional<bool> {
+ [&solver](CmpIOp op) -> std::optional<bool> {
return failed(isCmpIConvertable(solver, op));
});
void memref::populateMemRefWideIntEmulationConversions(
arith::WideIntEmulationConverter &typeConverter) {
typeConverter.addConversion(
- [&typeConverter](MemRefType ty) -> Optional<Type> {
+ [&typeConverter](MemRefType ty) -> std::optional<Type> {
auto intTy = ty.getElementType().dyn_cast<IntegerType>();
if (!intTy)
return ty;
unsigned ArrayType::getArrayStride() const { return getImpl()->stride; }
void ArrayType::getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
getElementType().cast<SPIRVType>().getExtensions(extensions, storage);
}
void ArrayType::getCapabilities(
SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
getElementType().cast<SPIRVType>().getCapabilities(capabilities, storage);
}
-Optional<int64_t> ArrayType::getSizeInBytes() {
+std::optional<int64_t> ArrayType::getSizeInBytes() {
auto elementType = getElementType().cast<SPIRVType>();
- Optional<int64_t> size = elementType.getSizeInBytes();
+ std::optional<int64_t> size = elementType.getSizeInBytes();
if (!size)
return std::nullopt;
return (*size + getArrayStride()) * getNumElements();
void CompositeType::getExtensions(
SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
TypeSwitch<Type>(*this)
.Case<ArrayType, CooperativeMatrixNVType, JointMatrixINTELType,
MatrixType, RuntimeArrayType, StructType>(
void CompositeType::getCapabilities(
SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
TypeSwitch<Type>(*this)
.Case<ArrayType, CooperativeMatrixNVType, JointMatrixINTELType,
MatrixType, RuntimeArrayType, StructType>(
.Default([](Type) { llvm_unreachable("invalid composite type"); });
}
-Optional<int64_t> CompositeType::getSizeInBytes() {
+std::optional<int64_t> CompositeType::getSizeInBytes() {
if (auto arrayType = dyn_cast<ArrayType>())
return arrayType.getSizeInBytes();
if (auto structType = dyn_cast<StructType>())
return structType.getSizeInBytes();
if (auto vectorType = dyn_cast<VectorType>()) {
- Optional<int64_t> elementSize =
+ std::optional<int64_t> elementSize =
vectorType.getElementType().cast<ScalarType>().getSizeInBytes();
if (!elementSize)
return std::nullopt;
void CooperativeMatrixNVType::getExtensions(
SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
getElementType().cast<SPIRVType>().getExtensions(extensions, storage);
static const Extension exts[] = {Extension::SPV_NV_cooperative_matrix};
ArrayRef<Extension> ref(exts, std::size(exts));
void CooperativeMatrixNVType::getCapabilities(
SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
getElementType().cast<SPIRVType>().getCapabilities(capabilities, storage);
static const Capability caps[] = {Capability::CooperativeMatrixNV};
ArrayRef<Capability> ref(caps, std::size(caps));
void JointMatrixINTELType::getExtensions(
SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
getElementType().cast<SPIRVType>().getExtensions(extensions, storage);
static const Extension exts[] = {Extension::SPV_INTEL_joint_matrix};
ArrayRef<Extension> ref(exts, std::size(exts));
void JointMatrixINTELType::getCapabilities(
SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
getElementType().cast<SPIRVType>().getCapabilities(capabilities, storage);
static const Capability caps[] = {Capability::JointMatrixINTEL};
ArrayRef<Capability> ref(caps, std::size(caps));
ImageFormat ImageType::getImageFormat() const { return getImpl()->format; }
void ImageType::getExtensions(SPIRVType::ExtensionArrayRefVector &,
- Optional<StorageClass>) {
+ std::optional<StorageClass>) {
// Image types do not require extra extensions thus far.
}
void ImageType::getCapabilities(
- SPIRVType::CapabilityArrayRefVector &capabilities, Optional<StorageClass>) {
+ SPIRVType::CapabilityArrayRefVector &capabilities,
+ std::optional<StorageClass>) {
if (auto dimCaps = spirv::getCapabilities(getDim()))
capabilities.push_back(*dimCaps);
}
void PointerType::getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
// Use this pointer type's storage class because this pointer indicates we are
// using the pointee type in that specific storage class.
getPointeeType().cast<SPIRVType>().getExtensions(extensions,
void PointerType::getCapabilities(
SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
// Use this pointer type's storage class because this pointer indicates we are
// using the pointee type in that specific storage class.
getPointeeType().cast<SPIRVType>().getCapabilities(capabilities,
void RuntimeArrayType::getExtensions(
SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
getElementType().cast<SPIRVType>().getExtensions(extensions, storage);
}
void RuntimeArrayType::getCapabilities(
SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
{
static const Capability caps[] = {Capability::Shader};
ArrayRef<Capability> ref(caps, std::size(caps));
}
void ScalarType::getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
// 8- or 16-bit integer/floating-point numbers will require extra extensions
// to appear in interface storage classes. See SPV_KHR_16bit_storage and
// SPV_KHR_8bit_storage for more details.
void ScalarType::getCapabilities(
SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
unsigned bitwidth = getIntOrFloatBitWidth();
// 8- or 16-bit integer/floating-point numbers will require extra capabilities
#undef WIDTH_CASE
}
-Optional<int64_t> ScalarType::getSizeInBytes() {
+std::optional<int64_t> ScalarType::getSizeInBytes() {
auto bitWidth = getIntOrFloatBitWidth();
// According to the SPIR-V spec:
// "There is no physical size or bit pattern defined for values with boolean
}
void SPIRVType::getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
if (auto scalarType = dyn_cast<ScalarType>()) {
scalarType.getExtensions(extensions, storage);
} else if (auto compositeType = dyn_cast<CompositeType>()) {
void SPIRVType::getCapabilities(
SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
if (auto scalarType = dyn_cast<ScalarType>()) {
scalarType.getCapabilities(capabilities, storage);
} else if (auto compositeType = dyn_cast<CompositeType>()) {
}
}
-Optional<int64_t> SPIRVType::getSizeInBytes() {
+std::optional<int64_t> SPIRVType::getSizeInBytes() {
if (auto scalarType = dyn_cast<ScalarType>())
return scalarType.getSizeInBytes();
if (auto compositeType = dyn_cast<CompositeType>())
void SampledImageType::getExtensions(
SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
getImageType().cast<ImageType>().getExtensions(extensions, storage);
}
void SampledImageType::getCapabilities(
SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
getImageType().cast<ImageType>().getCapabilities(capabilities, storage);
}
}
void StructType::getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
for (Type elementType : getElementTypes())
elementType.cast<SPIRVType>().getExtensions(extensions, storage);
}
void StructType::getCapabilities(
SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
for (Type elementType : getElementTypes())
elementType.cast<SPIRVType>().getCapabilities(capabilities, storage);
}
}
void MatrixType::getExtensions(SPIRVType::ExtensionArrayRefVector &extensions,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
getColumnType().cast<SPIRVType>().getExtensions(extensions, storage);
}
void MatrixType::getCapabilities(
SPIRVType::CapabilityArrayRefVector &capabilities,
- Optional<StorageClass> storage) {
+ std::optional<StorageClass> storage) {
{
static const Capability caps[] = {Capability::Matrix};
ArrayRef<Capability> ref(caps, std::size(caps));
// TODO: This is a utility function that should probably be exposed by the
// SPIR-V dialect. Keeping it local till the use case arises.
-static Optional<int64_t> getTypeNumBytes(const SPIRVConversionOptions &options,
- Type type) {
+static std::optional<int64_t>
+getTypeNumBytes(const SPIRVConversionOptions &options, Type type) {
if (type.isa<spirv::ScalarType>()) {
auto bitWidth = type.getIntOrFloatBitWidth();
// According to the SPIR-V spec:
}
/// Converts a scalar `type` to a suitable type under the given `targetEnv`.
-static Type convertScalarType(const spirv::TargetEnv &targetEnv,
- const SPIRVConversionOptions &options,
- spirv::ScalarType type,
- Optional<spirv::StorageClass> storageClass = {}) {
+static Type
+convertScalarType(const spirv::TargetEnv &targetEnv,
+ const SPIRVConversionOptions &options, spirv::ScalarType type,
+ std::optional<spirv::StorageClass> storageClass = {}) {
// Get extension and capability requirements for the given type.
SmallVector<ArrayRef<spirv::Extension>, 1> extensions;
SmallVector<ArrayRef<spirv::Capability>, 2> capabilities;
}
/// Converts a vector `type` to a suitable type under the given `targetEnv`.
-static Type convertVectorType(const spirv::TargetEnv &targetEnv,
- const SPIRVConversionOptions &options,
- VectorType type,
- Optional<spirv::StorageClass> storageClass = {}) {
+static Type
+convertVectorType(const spirv::TargetEnv &targetEnv,
+ const SPIRVConversionOptions &options, VectorType type,
+ std::optional<spirv::StorageClass> storageClass = {}) {
auto scalarType = type.getElementType().cast<spirv::ScalarType>();
if (type.getRank() <= 1 && type.getNumElements() == 1)
return convertScalarType(targetEnv, options, scalarType, storageClass);
return nullptr;
}
- Optional<int64_t> scalarSize = getTypeNumBytes(options, scalarType);
- Optional<int64_t> tensorSize = getTypeNumBytes(options, type);
+ std::optional<int64_t> scalarSize = getTypeNumBytes(options, scalarType);
+ std::optional<int64_t> tensorSize = getTypeNumBytes(options, type);
if (!scalarSize || !tensorSize) {
LLVM_DEBUG(llvm::dbgs()
<< type << " illegal: cannot deduce element count\n");
auto arrayElemType = convertScalarType(targetEnv, options, scalarType);
if (!arrayElemType)
return nullptr;
- Optional<int64_t> arrayElemSize = getTypeNumBytes(options, arrayElemType);
+ std::optional<int64_t> arrayElemSize =
+ getTypeNumBytes(options, arrayElemType);
if (!arrayElemSize) {
LLVM_DEBUG(llvm::dbgs()
<< type << " illegal: cannot deduce converted element size\n");
convertScalarType(targetEnv, options, elementType, storageClass);
if (!arrayElemType)
return nullptr;
- Optional<int64_t> arrayElemSize = getTypeNumBytes(options, arrayElemType);
+ std::optional<int64_t> arrayElemSize =
+ getTypeNumBytes(options, arrayElemType);
if (!arrayElemSize) {
LLVM_DEBUG(llvm::dbgs()
<< type << " illegal: cannot deduce converted element size\n");
if (!arrayElemType)
return nullptr;
- Optional<int64_t> arrayElemSize = getTypeNumBytes(options, arrayElemType);
+ std::optional<int64_t> arrayElemSize =
+ getTypeNumBytes(options, arrayElemType);
if (!arrayElemSize) {
LLVM_DEBUG(llvm::dbgs()
<< type << " illegal: cannot deduce converted element size\n");
return wrapInStructAndGetPointer(arrayType, storageClass);
}
- Optional<int64_t> memrefSize = getTypeNumBytes(options, type);
+ std::optional<int64_t> memrefSize = getTypeNumBytes(options, type);
if (!memrefSize) {
LLVM_DEBUG(llvm::dbgs()
<< type << " illegal: cannot deduce element count\n");
addConversion([this](IndexType /*indexType*/) { return getIndexType(); });
- addConversion([this](IntegerType intType) -> Optional<Type> {
+ addConversion([this](IntegerType intType) -> std::optional<Type> {
if (auto scalarType = intType.dyn_cast<spirv::ScalarType>())
return convertScalarType(this->targetEnv, this->options, scalarType);
return Type();
});
- addConversion([this](FloatType floatType) -> Optional<Type> {
+ addConversion([this](FloatType floatType) -> std::optional<Type> {
if (auto scalarType = floatType.dyn_cast<spirv::ScalarType>())
return convertScalarType(this->targetEnv, this->options, scalarType);
return Type();
/// Given a list of resource element `types`, returns the index of the canonical
/// resource that all resources should be unified into. Returns std::nullopt if
/// unable to unify.
-static Optional<int> deduceCanonicalResource(ArrayRef<spirv::SPIRVType> types) {
+static std::optional<int>
+deduceCanonicalResource(ArrayRef<spirv::SPIRVType> types) {
// scalarNumBits: contains all resources' scalar types' bit counts.
// vectorNumBits: only contains resources whose element types are vectors.
// vectorIndices: each vector's original index in `types`.
return std::nullopt; // Odd-sized vector has special layout
// requirements.
- Optional<int64_t> numBytes = type.getSizeInBytes();
+ std::optional<int64_t> numBytes = type.getSizeInBytes();
if (!numBytes)
return std::nullopt;
elementTypes.push_back(type);
}
- Optional<int> index = deduceCanonicalResource(elementTypes);
+ std::optional<int> index = deduceCanonicalResource(elementTypes);
if (!index)
return;
}
/// Maps a sparse tensor type to the appropriate compounded buffers.
-static Optional<LogicalResult>
+static std::optional<LogicalResult>
convertSparseTensorType(Type type, SmallVectorImpl<Type> &fields) {
auto enc = getSparseTensorEncoding(type);
if (!enc)
// Required by scf.for 1:N type conversion.
addSourceMaterialization([](OpBuilder &builder, RankedTensorType tp,
ValueRange inputs,
- Location loc) -> Optional<Value> {
+ Location loc) -> std::optional<Value> {
if (!getSparseTensorEncoding(tp))
// Not a sparse tensor.
return std::nullopt;
//===----------------------------------------------------------------------===//
/// Maps each sparse tensor type to an opaque pointer.
-static Optional<Type> convertSparseTensorTypes(Type type) {
+static std::optional<Type> convertSparseTensorTypes(Type type) {
if (getSparseTensorEncoding(type) != nullptr)
return LLVM::LLVMPointerType::get(IntegerType::get(type.getContext(), 8));
return std::nullopt;
// Don't check this operation's children for conversion if the operation
// is recursively legal.
- auto legalityInfo = target ? target->isLegal(&op)
- : Optional<ConversionTarget::LegalOpDetails>();
+ auto legalityInfo =
+ target ? target->isLegal(&op)
+ : std::optional<ConversionTarget::LegalOpDetails>();
if (legalityInfo && legalityInfo->isRecursivelyLegal)
continue;
for (auto ®ion : op.getRegions()) {
/// The conversion information for each of the arguments. The information is
/// std::nullopt if the argument was dropped during conversion.
- SmallVector<Optional<ConvertedArgInfo>, 1> argInfo;
+ SmallVector<std::optional<ConvertedArgInfo>, 1> argInfo;
/// The type converter used to convert the arguments.
TypeConverter *converter;
// Process the remapping for each of the original arguments.
for (unsigned i = 0, e = origBlock->getNumArguments(); i != e; ++i) {
- Optional<ConvertedArgInfo> &argInfo = blockInfo.argInfo[i];
+ std::optional<ConvertedArgInfo> &argInfo = blockInfo.argInfo[i];
BlockArgument origArg = origBlock->getArgument(i);
// Handle the case of a 1->0 value mapping.
/// success if the values could be remapped, failure otherwise. `valueDiagTag`
/// is the tag used when describing a value within a diagnostic, e.g.
/// "operand".
- LogicalResult remapValues(StringRef valueDiagTag, Optional<Location> inputLoc,
+ LogicalResult remapValues(StringRef valueDiagTag,
+ std::optional<Location> inputLoc,
PatternRewriter &rewriter, ValueRange values,
SmallVectorImpl<Value> &remapped);
}
LogicalResult ConversionPatternRewriterImpl::remapValues(
- StringRef valueDiagTag, Optional<Location> inputLoc,
+ StringRef valueDiagTag, std::optional<Location> inputLoc,
PatternRewriter &rewriter, ValueRange values,
SmallVectorImpl<Value> &remapped) {
remapped.reserve(llvm::size(values));
// Check to see if any of the generated operations are invalid.
if (llvm::any_of(pattern->getGeneratedOps(), [&](OperationName op) {
- Optional<LegalizationAction> action = target.getOpAction(op);
+ std::optional<LegalizationAction> action = target.getOpAction(op);
return !legalizerPatterns.count(op) &&
(!action || action == LegalizationAction::Illegal);
}))
LogicalResult legalizeUnresolvedMaterializations(
ConversionPatternRewriter &rewriter,
ConversionPatternRewriterImpl &rewriterImpl,
- Optional<DenseMap<Value, SmallVector<Value>>> &inverseMapping);
+ std::optional<DenseMap<Value, SmallVector<Value>>> &inverseMapping);
/// Legalize an operation result that was marked as "erased".
LogicalResult
LogicalResult
OperationConverter::finalize(ConversionPatternRewriter &rewriter) {
- Optional<DenseMap<Value, SmallVector<Value>>> inverseMapping;
+ std::optional<DenseMap<Value, SmallVector<Value>>> inverseMapping;
ConversionPatternRewriterImpl &rewriterImpl = rewriter.getImpl();
if (failed(legalizeUnresolvedMaterializations(rewriter, rewriterImpl,
inverseMapping)) ||
LogicalResult OperationConverter::legalizeUnresolvedMaterializations(
ConversionPatternRewriter &rewriter,
ConversionPatternRewriterImpl &rewriterImpl,
- Optional<DenseMap<Value, SmallVector<Value>>> &inverseMapping) {
+ std::optional<DenseMap<Value, SmallVector<Value>>> &inverseMapping) {
if (rewriterImpl.unresolvedMaterializations.empty())
return success();
inverseMapping = rewriterImpl.mapping.getInverse();
auto popConversionCallStack =
llvm::make_scope_exit([this]() { conversionCallStack.pop_back(); });
for (ConversionCallbackFn &converter : llvm::reverse(conversions)) {
- if (Optional<LogicalResult> result =
+ if (std::optional<LogicalResult> result =
converter(t, results, conversionCallStack)) {
if (!succeeded(*result)) {
cachedDirectConversions.try_emplace(t, nullptr);
MutableArrayRef<MaterializationCallbackFn> materializations,
OpBuilder &builder, Location loc, Type resultType, ValueRange inputs) {
for (MaterializationCallbackFn &fn : llvm::reverse(materializations))
- if (Optional<Value> result = fn(builder, resultType, inputs, loc))
+ if (std::optional<Value> result = fn(builder, resultType, inputs, loc))
return *result;
return nullptr;
}
auto TypeConverter::convertBlockSignature(Block *block)
- -> Optional<SignatureConversion> {
+ -> std::optional<SignatureConversion> {
SignatureConversion conversion(block->getNumArguments());
if (failed(convertSignatureArgs(block->getArgumentTypes(), conversion)))
return std::nullopt;
}
auto ConversionTarget::getOpAction(OperationName op) const
- -> Optional<LegalizationAction> {
- Optional<LegalizationInfo> info = getOpInfo(op);
- return info ? info->action : Optional<LegalizationAction>();
+ -> std::optional<LegalizationAction> {
+ std::optional<LegalizationInfo> info = getOpInfo(op);
+ return info ? info->action : std::optional<LegalizationAction>();
}
auto ConversionTarget::isLegal(Operation *op) const
- -> Optional<LegalOpDetails> {
- Optional<LegalizationInfo> info = getOpInfo(op->getName());
+ -> std::optional<LegalOpDetails> {
+ std::optional<LegalizationInfo> info = getOpInfo(op->getName());
if (!info)
return std::nullopt;
auto isOpLegal = [&] {
// Handle dynamic legality either with the provided legality function.
if (info->action == LegalizationAction::Dynamic) {
- Optional<bool> result = info->legalityFn(op);
+ std::optional<bool> result = info->legalityFn(op);
if (result)
return *result;
}
}
bool ConversionTarget::isIllegal(Operation *op) const {
- Optional<LegalizationInfo> info = getOpInfo(op->getName());
+ std::optional<LegalizationInfo> info = getOpInfo(op->getName());
if (!info)
return false;
if (info->action == LegalizationAction::Dynamic) {
- Optional<bool> result = info->legalityFn(op);
+ std::optional<bool> result = info->legalityFn(op);
if (!result)
return false;
return newCallback;
auto chain = [oldCl = std::move(oldCallback), newCl = std::move(newCallback)](
- Operation *op) -> Optional<bool> {
- if (Optional<bool> result = newCl(op))
+ Operation *op) -> std::optional<bool> {
+ if (std::optional<bool> result = newCl(op))
return *result;
return oldCl(op);
}
auto ConversionTarget::getOpInfo(OperationName op) const
- -> Optional<LegalizationInfo> {
+ -> std::optional<LegalizationInfo> {
// Check for info for this specific operation.
auto it = legalOperations.find(op);
if (it != legalOperations.end())
// 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) -> Optional<Value> {
+ Location loc) -> std::optional<Value> {
auto cast = builder.create<LLVM::BitcastOp>(loc, type, inputs);
return cast->getResult(0);
};
typeConverter.addArgumentMaterialization(
[](OpBuilder &builder, TupleType resultType, ValueRange inputs,
- Location loc) -> Optional<Value> {
+ Location loc) -> std::optional<Value> {
if (inputs.size() == 1)
return std::nullopt;
TupleType tuple = builder.getTupleType(inputs.getTypes());
/// Hook for materializing a conversion. This is necessary because we generate
/// 1->N type mappings.
- static Optional<Value> materializeCast(OpBuilder &builder, Type resultType,
- ValueRange inputs, Location loc) {
+ static std::optional<Value> materializeCast(OpBuilder &builder,
+ Type resultType,
+ ValueRange inputs, Location loc) {
return builder.create<TestCastOp>(loc, resultType, inputs).getResult();
}
};
// Convert a recursive self-referring type into a non-self-referring
// type named "outer_converted_type" that contains a SimpleAType.
[&](test::TestRecursiveType type, SmallVectorImpl<Type> &results,
- ArrayRef<Type> callStack) -> Optional<LogicalResult> {
+ ArrayRef<Type> callStack) -> std::optional<LogicalResult> {
// If the type is already converted, return it to indicate that it is
// legal.
if (type.getName() == "outer_converted_type") {
return success();
}
/// Hook for materializing a conversion.
- static Optional<Value> materializeCast(OpBuilder &builder, Type resultType,
- ValueRange inputs, Location loc) {
+ static std::optional<Value> materializeCast(OpBuilder &builder,
+ Type resultType,
+ ValueRange inputs, Location loc) {
return builder.create<UnrealizedConversionCastOp>(loc, resultType, inputs)
.getResult(0);
}
});
int callbackCalled2 = 0;
- target.addDynamicallyLegalOp<DummyOp>([&](Operation *) -> Optional<bool> {
- callbackCalled2 = ++index;
- return std::nullopt;
- });
+ target.addDynamicallyLegalOp<DummyOp>(
+ [&](Operation *) -> std::optional<bool> {
+ callbackCalled2 = ++index;
+ return std::nullopt;
+ });
auto *op = createOp(&context);
EXPECT_TRUE(target.isLegal(op));
int index = 0;
int callbackCalled = 0;
- target.addDynamicallyLegalOp<DummyOp>([&](Operation *) -> Optional<bool> {
- callbackCalled = ++index;
- return std::nullopt;
- });
+ target.addDynamicallyLegalOp<DummyOp>(
+ [&](Operation *) -> std::optional<bool> {
+ callbackCalled = ++index;
+ return std::nullopt;
+ });
auto *op = createOp(&context);
EXPECT_FALSE(target.isLegal(op));
});
int callbackCalled2 = 0;
- target.markUnknownOpDynamicallyLegal([&](Operation *) -> Optional<bool> {
+ target.markUnknownOpDynamicallyLegal([&](Operation *) -> std::optional<bool> {
callbackCalled2 = ++index;
return std::nullopt;
});
ConversionTarget target(context);
target.addDynamicallyLegalOp<DummyOp>(
- [&](Operation *) -> Optional<bool> { return std::nullopt; });
+ [&](Operation *) -> std::optional<bool> { return std::nullopt; });
auto *op = createOp(&context);
EXPECT_FALSE(target.isLegal(op));
ConversionTarget target(context);
target.markUnknownOpDynamicallyLegal(
- [&](Operation *) -> Optional<bool> { return std::nullopt; });
+ [&](Operation *) -> std::optional<bool> { return std::nullopt; });
auto *op = createOp(&context);
EXPECT_FALSE(target.isLegal(op));