diff --git a/mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt b/mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt index 82938962fb939..7c94d52d38299 100644 --- a/mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt +++ b/mlir/include/mlir/Dialect/Ptr/IR/CMakeLists.txt @@ -5,3 +5,15 @@ set(LLVM_TARGET_DEFINITIONS PtrOps.td) mlir_tablegen(PtrOpsAttrs.h.inc -gen-attrdef-decls -attrdefs-dialect=ptr) mlir_tablegen(PtrOpsAttrs.cpp.inc -gen-attrdef-defs -attrdefs-dialect=ptr) add_public_tablegen_target(MLIRPtrOpsAttributesIncGen) + +set(LLVM_TARGET_DEFINITIONS MemorySpaceInterfaces.td) +mlir_tablegen(MemorySpaceInterfaces.h.inc -gen-op-interface-decls) +mlir_tablegen(MemorySpaceInterfaces.cpp.inc -gen-op-interface-defs) +mlir_tablegen(MemorySpaceAttrInterfaces.h.inc -gen-attr-interface-decls) +mlir_tablegen(MemorySpaceAttrInterfaces.cpp.inc -gen-attr-interface-defs) +add_public_tablegen_target(MLIRPtrMemorySpaceInterfacesIncGen) + +set(LLVM_TARGET_DEFINITIONS PtrOps.td) +mlir_tablegen(PtrOpsEnums.h.inc -gen-enum-decls) +mlir_tablegen(PtrOpsEnums.cpp.inc -gen-enum-defs) +add_public_tablegen_target(MLIRPtrOpsEnumsGen) diff --git a/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h b/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h new file mode 100644 index 0000000000000..a0467550c4623 --- /dev/null +++ b/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h @@ -0,0 +1,32 @@ +//===-- MemorySpaceInterfaces.h - ptr memory space interfaces ---*- 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 file defines the ptr dialect memory space interfaces. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_DIALECT_PTR_IR_MEMORYSPACEINTERFACES_H +#define MLIR_DIALECT_PTR_IR_MEMORYSPACEINTERFACES_H + +#include "mlir/IR/Attributes.h" +#include "mlir/IR/BuiltinAttributes.h" +#include "mlir/IR/OpDefinition.h" + +namespace mlir { +class Operation; +namespace ptr { +enum class AtomicBinOp : uint64_t; +enum class AtomicOrdering : uint64_t; +} // namespace ptr +} // namespace mlir + +#include "mlir/Dialect/Ptr/IR/MemorySpaceAttrInterfaces.h.inc" + +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h.inc" + +#endif // MLIR_DIALECT_PTR_IR_MEMORYSPACEINTERFACES_H diff --git a/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td b/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td new file mode 100644 index 0000000000000..3e9f99e0e1d6a --- /dev/null +++ b/mlir/include/mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td @@ -0,0 +1,117 @@ +//===-- MemorySpaceInterfaces.td - Memory space interfaces ----------------===// +// +// 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 file defines memory space attribute interfaces. +// +//===----------------------------------------------------------------------===// + +#ifndef PTR_MEMORYSPACEINTERFACES +#define PTR_MEMORYSPACEINTERFACES + +include "mlir/IR/AttrTypeBase.td" +include "mlir/IR/OpBase.td" + +//===----------------------------------------------------------------------===// +// Memory space attribute interface. +//===----------------------------------------------------------------------===// + +def MemorySpaceAttrInterface : AttrInterface<"MemorySpaceAttrInterface"> { + let description = [{ + This interface defines a common API for interacting with the memory model of + a memory space and the operations in the pointer dialect. + + Furthermore, this interface allows concepts such as read-only memory to be + adequately modeled and enforced. + }]; + let cppNamespace = "::mlir::ptr"; + let methods = [ + InterfaceMethod< + /*desc=*/ [{ + This method checks if it's valid to load a value from the memory space + with a specific type, alignment, and atomic ordering. + If `emitError` is non-null then the method is allowed to emit errors. + }], + /*returnType=*/ "::mlir::LogicalResult", + /*methodName=*/ "isValidLoad", + /*args=*/ (ins "::mlir::Type":$type, + "::mlir::ptr::AtomicOrdering":$ordering, + "::mlir::IntegerAttr":$alignment, + "::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError) + >, + InterfaceMethod< + /*desc=*/ [{ + This method checks if it's valid to store a value in the memory space + with a specific type, alignment, and atomic ordering. + If `emitError` is non-null then the method is allowed to emit errors. + }], + /*returnType=*/ "::mlir::LogicalResult", + /*methodName=*/ "isValidStore", + /*args=*/ (ins "::mlir::Type":$type, + "::mlir::ptr::AtomicOrdering":$ordering, + "::mlir::IntegerAttr":$alignment, + "::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError) + >, + InterfaceMethod< + /*desc=*/ [{ + This method checks if it's valid to perform an atomic operation in the + memory space with a specific type, alignment, and atomic ordering. + If `emitError` is non-null then the method is allowed to emit errors. + }], + /*returnType=*/ "::mlir::LogicalResult", + /*methodName=*/ "isValidAtomicOp", + /*args=*/ (ins "::mlir::ptr::AtomicBinOp":$op, + "::mlir::Type":$type, + "::mlir::ptr::AtomicOrdering":$ordering, + "::mlir::IntegerAttr":$alignment, + "::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError) + >, + InterfaceMethod< + /*desc=*/ [{ + This method checks if it's valid to perform an atomic exchange operation + in the memory space with a specific type, alignment, and atomic + orderings. + If `emitError` is non-null then the method is allowed to emit errors. + }], + /*returnType=*/ "::mlir::LogicalResult", + /*methodName=*/ "isValidAtomicXchg", + /*args=*/ (ins "::mlir::Type":$type, + "::mlir::ptr::AtomicOrdering":$successOrdering, + "::mlir::ptr::AtomicOrdering":$failureOrdering, + "::mlir::IntegerAttr":$alignment, + "::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError) + >, + InterfaceMethod< + /*desc=*/ [{ + This method checks if it's valid to perform an `addrspacecast` op + in the memory space. + If `emitError` is non-null then the method is allowed to emit errors. + }], + /*returnType=*/ "::mlir::LogicalResult", + /*methodName=*/ "isValidAddrSpaceCast", + /*args=*/ (ins "::mlir::Type":$tgt, + "::mlir::Type":$src, + "::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError) + >, + InterfaceMethod< + /*desc=*/ [{ + This method checks if it's valid to perform a `ptrtoint` or `inttoptr` + op in the memory space. + The first type is expected to be integer-like, while the second must be a + ptr-like type. + If `emitError` is non-null then the method is allowed to emit errors. + }], + /*returnType=*/ "::mlir::LogicalResult", + /*methodName=*/ "isValidPtrIntCast", + /*args=*/ (ins "::mlir::Type":$intLikeTy, + "::mlir::Type":$ptrLikeTy, + "::llvm::function_ref<::mlir::InFlightDiagnostic()>":$emitError) + >, + ]; +} + +#endif // PTR_MEMORYSPACEINTERFACES diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h index 72e767764d98b..5ffe23e45fe12 100644 --- a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h +++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h @@ -18,4 +18,6 @@ #define GET_ATTRDEF_CLASSES #include "mlir/Dialect/Ptr/IR/PtrOpsAttrs.h.inc" +#include "mlir/Dialect/Ptr/IR/PtrOpsEnums.h.inc" + #endif // MLIR_DIALECT_PTR_IR_PTRATTRS_H diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td index bc377dcc72e48..857e68cec8c76 100644 --- a/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td +++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td @@ -45,7 +45,7 @@ def Ptr_PtrType : Ptr_Type<"Ptr", "ptr", [ let description = [{ The `ptr` type is an opaque pointer type. This type typically represents a handle to an object in memory or target-dependent values like `nullptr`. - Pointers are optionally parameterized by a memory space. + Pointers are parameterized by a memory space. Syntax: @@ -54,14 +54,14 @@ def Ptr_PtrType : Ptr_Type<"Ptr", "ptr", [ memory-space ::= attribute-value ``` }]; - let parameters = (ins OptionalParameter<"Attribute">:$memorySpace); - let assemblyFormat = "(`<` $memorySpace^ `>`)?"; + let parameters = (ins "MemorySpaceAttrInterface":$memorySpace); + let assemblyFormat = "`<` $memorySpace `>`"; let builders = [ - TypeBuilder<(ins CArg<"Attribute", "nullptr">:$memorySpace), [{ - return $_get($_ctxt, memorySpace); + TypeBuilderWithInferredContext<(ins + "MemorySpaceAttrInterface":$memorySpace), [{ + return $_get(memorySpace.getContext(), memorySpace); }]> ]; - let skipDefaultBuilders = 1; } //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td new file mode 100644 index 0000000000000..0a8a7ede5d1ff --- /dev/null +++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td @@ -0,0 +1,69 @@ +//===-- PtrEnums.td - Ptr dialect enumerations -------------*- tablegen -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef PTR_ENUMS +#define PTR_ENUMS + +include "mlir/IR/EnumAttr.td" + +//===----------------------------------------------------------------------===// +// Atomic binary op enum attribute. +//===----------------------------------------------------------------------===// + +def AtomicBinOpXchg : I64EnumAttrCase<"xchg", 0, "xchg">; +def AtomicBinOpAdd : I64EnumAttrCase<"add", 1, "add">; +def AtomicBinOpSub : I64EnumAttrCase<"sub", 2, "sub">; +def AtomicBinOpAnd : I64EnumAttrCase<"_and", 3, "_and">; +def AtomicBinOpNand : I64EnumAttrCase<"nand", 4, "nand">; +def AtomicBinOpOr : I64EnumAttrCase<"_or", 5, "_or">; +def AtomicBinOpXor : I64EnumAttrCase<"_xor", 6, "_xor">; +def AtomicBinOpMax : I64EnumAttrCase<"max", 7, "max">; +def AtomicBinOpMin : I64EnumAttrCase<"min", 8, "min">; +def AtomicBinOpUMax : I64EnumAttrCase<"umax", 9, "umax">; +def AtomicBinOpUMin : I64EnumAttrCase<"umin", 10, "umin">; +def AtomicBinOpFAdd : I64EnumAttrCase<"fadd", 11, "fadd">; +def AtomicBinOpFSub : I64EnumAttrCase<"fsub", 12, "fsub">; +def AtomicBinOpFMax : I64EnumAttrCase<"fmax", 13, "fmax">; +def AtomicBinOpFMin : I64EnumAttrCase<"fmin", 14, "fmin">; +def AtomicBinOpUIncWrap : I64EnumAttrCase<"uinc_wrap", 15, "uinc_wrap">; +def AtomicBinOpUDecWrap : I64EnumAttrCase<"udec_wrap", 16, "udec_wrap">; + +def AtomicBinOp : I64EnumAttr< + "AtomicBinOp", + "ptr.atomicrmw binary operations", + [AtomicBinOpXchg, AtomicBinOpAdd, AtomicBinOpSub, AtomicBinOpAnd, + AtomicBinOpNand, AtomicBinOpOr, AtomicBinOpXor, AtomicBinOpMax, + AtomicBinOpMin, AtomicBinOpUMax, AtomicBinOpUMin, AtomicBinOpFAdd, + AtomicBinOpFSub, AtomicBinOpFMax, AtomicBinOpFMin, AtomicBinOpUIncWrap, + AtomicBinOpUDecWrap]> { + let cppNamespace = "::mlir::ptr"; +} + +//===----------------------------------------------------------------------===// +// Atomic ordering enum attribute. +//===----------------------------------------------------------------------===// + +def AtomicOrderingNotAtomic : I64EnumAttrCase<"not_atomic", 0, "not_atomic">; +def AtomicOrderingUnordered : I64EnumAttrCase<"unordered", 1, "unordered">; +def AtomicOrderingMonotonic : I64EnumAttrCase<"monotonic", 2, "monotonic">; +def AtomicOrderingAcquire : I64EnumAttrCase<"acquire", 3, "acquire">; +def AtomicOrderingRelease : I64EnumAttrCase<"release", 4, "release">; +def AtomicOrderingAcqRel : I64EnumAttrCase<"acq_rel", 5, "acq_rel">; +def AtomicOrderingSeqCst : I64EnumAttrCase<"seq_cst", 6, "seq_cst">; + +def AtomicOrdering : I64EnumAttr< + "AtomicOrdering", + "Atomic ordering for LLVM's memory model", + [AtomicOrderingNotAtomic, AtomicOrderingUnordered, AtomicOrderingMonotonic, + AtomicOrderingAcquire, AtomicOrderingRelease, AtomicOrderingAcqRel, + AtomicOrderingSeqCst + ]> { + let cppNamespace = "::mlir::ptr"; +} + +#endif // PTR_ENUMS diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td index 84e3e33f6fcb9..02ea71f4322ef 100644 --- a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td +++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td @@ -11,6 +11,7 @@ include "mlir/Dialect/Ptr/IR/PtrDialect.td" include "mlir/Dialect/Ptr/IR/PtrAttrDefs.td" +include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td" include "mlir/IR/OpAsmInterface.td" #endif // PTR_OPS diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrTypes.h b/mlir/include/mlir/Dialect/Ptr/IR/PtrTypes.h index 264a97c80722a..4fe1b5a1aa423 100644 --- a/mlir/include/mlir/Dialect/Ptr/IR/PtrTypes.h +++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrTypes.h @@ -13,6 +13,7 @@ #ifndef MLIR_DIALECT_PTR_IR_PTRTYPES_H #define MLIR_DIALECT_PTR_IR_PTRTYPES_H +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "mlir/IR/Types.h" #include "mlir/Interfaces/DataLayoutInterfaces.h" diff --git a/mlir/lib/Dialect/Ptr/IR/CMakeLists.txt b/mlir/lib/Dialect/Ptr/IR/CMakeLists.txt index 9cf3643c73d3e..ba32a76273ed4 100644 --- a/mlir/lib/Dialect/Ptr/IR/CMakeLists.txt +++ b/mlir/lib/Dialect/Ptr/IR/CMakeLists.txt @@ -7,7 +7,8 @@ add_mlir_dialect_library( DEPENDS MLIRPtrOpsAttributesIncGen MLIRPtrOpsIncGen - + MLIRPtrOpsEnumsGen + MLIRPtrMemorySpaceInterfacesIncGen LINK_LIBS PUBLIC MLIRIR diff --git a/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp b/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp index 7830ffe893dfd..ff231dae60c27 100644 --- a/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp +++ b/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp @@ -48,6 +48,12 @@ void PtrDialect::initialize() { #define GET_ATTRDEF_CLASSES #include "mlir/Dialect/Ptr/IR/PtrOpsAttrs.cpp.inc" +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.cpp.inc" + +#include "mlir/Dialect/Ptr/IR/MemorySpaceAttrInterfaces.cpp.inc" + +#include "mlir/Dialect/Ptr/IR/PtrOpsEnums.cpp.inc" + #define GET_TYPEDEF_CLASSES #include "mlir/Dialect/Ptr/IR/PtrOpsTypes.cpp.inc" diff --git a/mlir/lib/Dialect/Ptr/IR/PtrTypes.cpp b/mlir/lib/Dialect/Ptr/IR/PtrTypes.cpp index 1fc424c05f6c7..cab9ca11e679e 100644 --- a/mlir/lib/Dialect/Ptr/IR/PtrTypes.cpp +++ b/mlir/lib/Dialect/Ptr/IR/PtrTypes.cpp @@ -28,7 +28,7 @@ constexpr const static unsigned kDefaultPointerAlignmentBits = 8; /// Searches the data layout for the pointer spec, returns nullptr if it is not /// found. static SpecAttr getPointerSpec(DataLayoutEntryListRef params, PtrType type, - Attribute defaultMemorySpace) { + MemorySpaceAttrInterface defaultMemorySpace) { for (DataLayoutEntryInterface entry : params) { if (!entry.isTypeEntry()) continue; @@ -38,9 +38,11 @@ static SpecAttr getPointerSpec(DataLayoutEntryListRef params, PtrType type, return spec; } } - // If not found, and this is the pointer to the default memory space, assume - // 64-bit pointers. - if (type.getMemorySpace() == defaultMemorySpace) + // If not found, and this is the pointer to the default memory space or if + // `defaultMemorySpace` is null, assume 64-bit pointers. `defaultMemorySpace` + // might be null if the data layout doesn't define the default memory space. + if (type.getMemorySpace() == defaultMemorySpace || + defaultMemorySpace == nullptr) return SpecAttr::get(type.getContext(), kDefaultPointerSizeBits, kDefaultPointerAlignmentBits, kDefaultPointerAlignmentBits, kDefaultPointerSizeBits); @@ -93,44 +95,47 @@ bool PtrType::areCompatible(DataLayoutEntryListRef oldLayout, uint64_t PtrType::getABIAlignment(const DataLayout &dataLayout, DataLayoutEntryListRef params) const { - Attribute defaultMemorySpace = dataLayout.getDefaultMemorySpace(); + auto defaultMemorySpace = llvm::cast_if_present( + dataLayout.getDefaultMemorySpace()); if (SpecAttr spec = getPointerSpec(params, *this, defaultMemorySpace)) return spec.getAbi() / kBitsInByte; - return dataLayout.getTypeABIAlignment(get(getContext(), defaultMemorySpace)); + return dataLayout.getTypeABIAlignment(get(defaultMemorySpace)); } std::optional PtrType::getIndexBitwidth(const DataLayout &dataLayout, DataLayoutEntryListRef params) const { - Attribute defaultMemorySpace = dataLayout.getDefaultMemorySpace(); + auto defaultMemorySpace = llvm::cast_if_present( + dataLayout.getDefaultMemorySpace()); if (SpecAttr spec = getPointerSpec(params, *this, defaultMemorySpace)) { return spec.getIndex() == SpecAttr::kOptionalSpecValue ? spec.getSize() : spec.getIndex(); } - return dataLayout.getTypeIndexBitwidth(get(getContext(), defaultMemorySpace)); + return dataLayout.getTypeIndexBitwidth(get(defaultMemorySpace)); } llvm::TypeSize PtrType::getTypeSizeInBits(const DataLayout &dataLayout, DataLayoutEntryListRef params) const { - Attribute defaultMemorySpace = dataLayout.getDefaultMemorySpace(); + auto defaultMemorySpace = llvm::cast_if_present( + dataLayout.getDefaultMemorySpace()); if (SpecAttr spec = getPointerSpec(params, *this, defaultMemorySpace)) return llvm::TypeSize::getFixed(spec.getSize()); // For other memory spaces, use the size of the pointer to the default memory // space. - return dataLayout.getTypeSizeInBits(get(getContext(), defaultMemorySpace)); + return dataLayout.getTypeSizeInBits(get(defaultMemorySpace)); } uint64_t PtrType::getPreferredAlignment(const DataLayout &dataLayout, DataLayoutEntryListRef params) const { - Attribute defaultMemorySpace = dataLayout.getDefaultMemorySpace(); + auto defaultMemorySpace = llvm::cast_if_present( + dataLayout.getDefaultMemorySpace()); if (SpecAttr spec = getPointerSpec(params, *this, defaultMemorySpace)) return spec.getPreferred() / kBitsInByte; - return dataLayout.getTypePreferredAlignment( - get(getContext(), defaultMemorySpace)); + return dataLayout.getTypePreferredAlignment(get(defaultMemorySpace)); } LogicalResult PtrType::verifyEntries(DataLayoutEntryListRef entries, diff --git a/mlir/test/Dialect/Ptr/layout.mlir b/mlir/test/Dialect/Ptr/layout.mlir index 356c57402651f..f904e729fcbe3 100644 --- a/mlir/test/Dialect/Ptr/layout.mlir +++ b/mlir/test/Dialect/Ptr/layout.mlir @@ -1,61 +1,61 @@ // RUN: mlir-opt --test-data-layout-query --split-input-file --verify-diagnostics %s | FileCheck %s module attributes { dlti.dl_spec = #dlti.dl_spec< - #dlti.dl_entry>, - #dlti.dl_entry,#ptr.spec>, - #dlti.dl_entry, #ptr.spec>, - #dlti.dl_entry<"dlti.default_memory_space", 7 : ui64>, - #dlti.dl_entry<"dlti.alloca_memory_space", 5 : ui64>, - #dlti.dl_entry<"dlti.global_memory_space", 2 : ui64>, - #dlti.dl_entry<"dlti.program_memory_space", 3 : ui64>, + #dlti.dl_entry, #ptr.spec>, + #dlti.dl_entry>,#ptr.spec>, + #dlti.dl_entry>, #ptr.spec>, + #dlti.dl_entry<"dlti.default_memory_space", #test.const_memory_space<7>>, + #dlti.dl_entry<"dlti.alloca_memory_space", #test.const_memory_space<5>>, + #dlti.dl_entry<"dlti.global_memory_space", #test.const_memory_space<2>>, + #dlti.dl_entry<"dlti.program_memory_space", #test.const_memory_space<3>>, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64> >} { // CHECK-LABEL: @spec func.func @spec() { // CHECK: alignment = 4 - // CHECK: alloca_memory_space = 5 + // CHECK: alloca_memory_space = #test.const_memory_space<5> // CHECK: bitsize = 32 - // CHECK: default_memory_space = 7 - // CHECK: global_memory_space = 2 + // CHECK: default_memory_space = #test.const_memory_space<7> + // CHECK: global_memory_space = #test.const_memory_space<2> // CHECK: index = 32 // CHECK: preferred = 8 - // CHECK: program_memory_space = 3 + // CHECK: program_memory_space = #test.const_memory_space<3> // CHECK: size = 4 // CHECK: stack_alignment = 128 - "test.data_layout_query"() : () -> !ptr.ptr + "test.data_layout_query"() : () -> !ptr.ptr<#test.const_memory_space> // CHECK: alignment = 1 - // CHECK: alloca_memory_space = 5 + // CHECK: alloca_memory_space = #test.const_memory_space<5> // CHECK: bitsize = 64 - // CHECK: default_memory_space = 7 - // CHECK: global_memory_space = 2 + // CHECK: default_memory_space = #test.const_memory_space<7> + // CHECK: global_memory_space = #test.const_memory_space<2> // CHECK: index = 64 // CHECK: preferred = 1 - // CHECK: program_memory_space = 3 + // CHECK: program_memory_space = #test.const_memory_space<3> // CHECK: size = 8 // CHECK: stack_alignment = 128 - "test.data_layout_query"() : () -> !ptr.ptr<3> + "test.data_layout_query"() : () -> !ptr.ptr<#test.const_memory_space<3>> // CHECK: alignment = 8 - // CHECK: alloca_memory_space = 5 + // CHECK: alloca_memory_space = #test.const_memory_space<5> // CHECK: bitsize = 64 - // CHECK: default_memory_space = 7 - // CHECK: global_memory_space = 2 + // CHECK: default_memory_space = #test.const_memory_space<7> + // CHECK: global_memory_space = #test.const_memory_space<2> // CHECK: index = 64 // CHECK: preferred = 8 - // CHECK: program_memory_space = 3 + // CHECK: program_memory_space = #test.const_memory_space<3> // CHECK: size = 8 // CHECK: stack_alignment = 128 - "test.data_layout_query"() : () -> !ptr.ptr<5> + "test.data_layout_query"() : () -> !ptr.ptr<#test.const_memory_space<5>> // CHECK: alignment = 8 - // CHECK: alloca_memory_space = 5 + // CHECK: alloca_memory_space = #test.const_memory_space<5> // CHECK: bitsize = 32 - // CHECK: default_memory_space = 7 - // CHECK: global_memory_space = 2 + // CHECK: default_memory_space = #test.const_memory_space<7> + // CHECK: global_memory_space = #test.const_memory_space<2> // CHECK: index = 24 // CHECK: preferred = 8 - // CHECK: program_memory_space = 3 + // CHECK: program_memory_space = #test.const_memory_space<3> // CHECK: size = 4 // CHECK: stack_alignment = 128 - "test.data_layout_query"() : () -> !ptr.ptr<4> + "test.data_layout_query"() : () -> !ptr.ptr<#test.const_memory_space<4>> return } } @@ -63,8 +63,8 @@ module attributes { dlti.dl_spec = #dlti.dl_spec< // ----- module attributes { dlti.dl_spec = #dlti.dl_spec< - #dlti.dl_entry, #ptr.spec>, - #dlti.dl_entry<"dlti.default_memory_space", 1 : ui64> + #dlti.dl_entry, #ptr.spec>, + #dlti.dl_entry<"dlti.default_memory_space", #test.const_memory_space> >} { // CHECK-LABEL: @default_memory_space func.func @default_memory_space() { @@ -73,19 +73,19 @@ module attributes { dlti.dl_spec = #dlti.dl_spec< // CHECK: index = 32 // CHECK: preferred = 4 // CHECK: size = 4 - "test.data_layout_query"() : () -> !ptr.ptr + "test.data_layout_query"() : () -> !ptr.ptr<#test.const_memory_space> // CHECK: alignment = 4 // CHECK: bitsize = 32 // CHECK: index = 32 // CHECK: preferred = 4 // CHECK: size = 4 - "test.data_layout_query"() : () -> !ptr.ptr<1> + "test.data_layout_query"() : () -> !ptr.ptr<#test.const_memory_space<1>> // CHECK: alignment = 4 // CHECK: bitsize = 32 // CHECK: index = 32 // CHECK: preferred = 4 // CHECK: size = 4 - "test.data_layout_query"() : () -> !ptr.ptr<2> + "test.data_layout_query"() : () -> !ptr.ptr<#test.const_memory_space<2>> return } } @@ -94,7 +94,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec< // expected-error@+2 {{preferred alignment is expected to be at least as large as ABI alignment}} module attributes { dlti.dl_spec = #dlti.dl_spec< - #dlti.dl_entry> + #dlti.dl_entry, #ptr.spec> >} { func.func @pointer() { return @@ -105,7 +105,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec< // expected-error@+2 {{size entry must be divisible by 8}} module attributes { dlti.dl_spec = #dlti.dl_spec< - #dlti.dl_entry> + #dlti.dl_entry, #ptr.spec> >} { func.func @pointer() { return @@ -117,7 +117,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec< // expected-error@+2 {{abi entry must be divisible by 8}} module attributes { dlti.dl_spec = #dlti.dl_spec< - #dlti.dl_entry> + #dlti.dl_entry, #ptr.spec> >} { func.func @pointer() { return @@ -129,7 +129,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec< // expected-error@+2 {{preferred entry must be divisible by 8}} module attributes { dlti.dl_spec = #dlti.dl_spec< - #dlti.dl_entry> + #dlti.dl_entry, #ptr.spec> >} { func.func @pointer() { return @@ -141,7 +141,7 @@ module attributes { dlti.dl_spec = #dlti.dl_spec< // expected-error@+2 {{index entry must be divisible by 8}} module attributes { dlti.dl_spec = #dlti.dl_spec< - #dlti.dl_entry> + #dlti.dl_entry, #ptr.spec> >} { func.func @pointer() { return diff --git a/mlir/test/Dialect/Ptr/types.mlir b/mlir/test/Dialect/Ptr/types.mlir index 279213bd6fc3e..6f4e89eb3e19b 100644 --- a/mlir/test/Dialect/Ptr/types.mlir +++ b/mlir/test/Dialect/Ptr/types.mlir @@ -1,17 +1,24 @@ // RUN: mlir-opt %s -split-input-file | mlir-opt | FileCheck %s // CHECK-LABEL: func @ptr_test -// CHECK: (%[[ARG0:.*]]: !ptr.ptr, %[[ARG1:.*]]: !ptr.ptr<1 : i32>) -// CHECK: -> (!ptr.ptr<1 : i32>, !ptr.ptr) -func.func @ptr_test(%arg0: !ptr.ptr, %arg1: !ptr.ptr<1 : i32>) -> (!ptr.ptr<1 : i32>, !ptr.ptr) { - // CHECK: return %[[ARG1]], %[[ARG0]] : !ptr.ptr<1 : i32>, !ptr.ptr - return %arg1, %arg0 : !ptr.ptr<1 : i32>, !ptr.ptr +// CHECK: (%[[ARG0:.*]]: !ptr.ptr<#test.const_memory_space>, %[[ARG1:.*]]: !ptr.ptr<#test.const_memory_space<1>>) +// CHECK: -> (!ptr.ptr<#test.const_memory_space<1>>, !ptr.ptr<#test.const_memory_space>) +func.func @ptr_test(%arg0: !ptr.ptr<#test.const_memory_space>, %arg1: !ptr.ptr<#test.const_memory_space<1>>) -> (!ptr.ptr<#test.const_memory_space<1>>, !ptr.ptr<#test.const_memory_space>) { + // CHECK: return %[[ARG1]], %[[ARG0]] : !ptr.ptr<#test.const_memory_space<1>>, !ptr.ptr<#test.const_memory_space> + return %arg1, %arg0 : !ptr.ptr<#test.const_memory_space<1>>, !ptr.ptr<#test.const_memory_space> } // ----- // CHECK-LABEL: func @ptr_test -// CHECK: %[[ARG:.*]]: memref -func.func @ptr_test(%arg0: memref) { +// CHECK: %[[ARG:.*]]: memref> +func.func @ptr_test(%arg0: memref>) { + return +} + +// CHECK-LABEL: func @ptr_test_1 +// CHECK: (%[[ARG0:.*]]: !ptr.ptr<#test.const_memory_space>, %[[ARG1:.*]]: !ptr.ptr<#test.const_memory_space<3>>) +func.func @ptr_test_1(%arg0: !ptr.ptr<#test.const_memory_space>, + %arg1: !ptr.ptr<#test.const_memory_space<3>>) { return } diff --git a/mlir/test/lib/Dialect/Test/CMakeLists.txt b/mlir/test/lib/Dialect/Test/CMakeLists.txt index 618b13da9899f..a48ac24ca056d 100644 --- a/mlir/test/lib/Dialect/Test/CMakeLists.txt +++ b/mlir/test/lib/Dialect/Test/CMakeLists.txt @@ -84,6 +84,7 @@ mlir_target_link_libraries(MLIRTestDialect PUBLIC MLIRInferTypeOpInterface MLIRLinalgDialect MLIRLinalgTransforms + MLIRPtrDialect MLIRLLVMDialect MLIRPass MLIRPolynomialDialect diff --git a/mlir/test/lib/Dialect/Test/TestAttrDefs.td b/mlir/test/lib/Dialect/Test/TestAttrDefs.td index 4b809c1c0a765..fc2d77af29f12 100644 --- a/mlir/test/lib/Dialect/Test/TestAttrDefs.td +++ b/mlir/test/lib/Dialect/Test/TestAttrDefs.td @@ -17,6 +17,7 @@ include "TestDialect.td" include "TestEnumDefs.td" include "mlir/Dialect/Polynomial/IR/PolynomialAttributes.td" +include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td" include "mlir/Dialect/Utils/StructuredOpsUtils.td" include "mlir/IR/AttrTypeBase.td" include "mlir/IR/BuiltinAttributeInterfaces.td" @@ -384,6 +385,14 @@ def NestedPolynomialAttr2 : Test_Attr<"NestedPolynomialAttr2"> { }]; } +// Test a ptr constant memory space. +def TestConstMemorySpaceAttr : Test_Attr<"TestConstMemorySpace", [ + DeclareAttrInterfaceMethods + ]> { + let mnemonic = "const_memory_space"; + let parameters = (ins DefaultValuedParameter<"unsigned", "0">:$addressSpace); + let assemblyFormat = "(`<` $addressSpace^ `>`)?"; +} // Test custom location handling. def TestCustomLocationAttr : Test_LocAttr<"TestCustomLocation"> { diff --git a/mlir/test/lib/Dialect/Test/TestAttributes.cpp b/mlir/test/lib/Dialect/Test/TestAttributes.cpp index 7c467308386f1..057d9fb4a215f 100644 --- a/mlir/test/lib/Dialect/Test/TestAttributes.cpp +++ b/mlir/test/lib/Dialect/Test/TestAttributes.cpp @@ -327,6 +327,49 @@ TestOpAsmAttrInterfaceAttr::getAlias(::llvm::raw_ostream &os) const { return ::mlir::OpAsmDialectInterface::AliasResult::FinalAlias; } +//===----------------------------------------------------------------------===// +// TestConstMemorySpaceAttr +//===----------------------------------------------------------------------===// + +LogicalResult TestConstMemorySpaceAttr::isValidLoad( + Type type, mlir::ptr::AtomicOrdering ordering, IntegerAttr alignment, + function_ref emitError) const { + return success(); +} + +LogicalResult TestConstMemorySpaceAttr::isValidStore( + Type type, mlir::ptr::AtomicOrdering ordering, IntegerAttr alignment, + function_ref emitError) const { + return emitError ? (emitError() << "memory space is read-only") : failure(); +} + +LogicalResult TestConstMemorySpaceAttr::isValidAtomicOp( + mlir::ptr::AtomicBinOp binOp, Type type, mlir::ptr::AtomicOrdering ordering, + IntegerAttr alignment, function_ref emitError) const { + return emitError ? (emitError() << "memory space is read-only") : failure(); +} + +LogicalResult TestConstMemorySpaceAttr::isValidAtomicXchg( + Type type, mlir::ptr::AtomicOrdering successOrdering, + mlir::ptr::AtomicOrdering failureOrdering, IntegerAttr alignment, + function_ref emitError) const { + return emitError ? (emitError() << "memory space is read-only") : failure(); +} + +LogicalResult TestConstMemorySpaceAttr::isValidAddrSpaceCast( + Type tgt, Type src, function_ref emitError) const { + return emitError + ? (emitError() << "memory space doesn't allow addrspace casts") + : failure(); +} + +LogicalResult TestConstMemorySpaceAttr::isValidPtrIntCast( + Type intLikeTy, Type ptrLikeTy, + function_ref emitError) const { + return emitError ? (emitError() << "memory space doesn't allow int-ptr casts") + : failure(); +} + //===----------------------------------------------------------------------===// // Tablegen Generated Definitions //===----------------------------------------------------------------------===// diff --git a/mlir/test/lib/Dialect/Test/TestAttributes.h b/mlir/test/lib/Dialect/Test/TestAttributes.h index 7099bcf317294..bcbc360758eec 100644 --- a/mlir/test/lib/Dialect/Test/TestAttributes.h +++ b/mlir/test/lib/Dialect/Test/TestAttributes.h @@ -18,6 +18,7 @@ #include "TestTraits.h" #include "mlir/Dialect/Polynomial/IR/PolynomialAttributes.h" +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "mlir/Dialect/Utils/StructuredOpsUtils.h" #include "mlir/IR/Attributes.h" #include "mlir/IR/Diagnostics.h"