summaryrefslogtreecommitdiff
path: root/source/slang/core.meta.slang
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-10-15 20:59:47 -0700
committerGitHub <noreply@github.com>2025-10-16 03:59:47 +0000
commit01510f2c922af8629c7a730ef92a31fa83bd9f49 (patch)
treebbec0cd5424e99670573dc3fa10fdf441320b684 /source/slang/core.meta.slang
parentd1a935c683ac1eb93d95587ee26bdaae7eb17e31 (diff)
Immutable access qualifier for pointers and use `__ldg` on cuda. (#8710)
This PR implements `Access.Immutable` to allow pointers to immutable data. The new type `ImmutablePtr<T>` is defined as an alias of `Ptr<T, Address.Immutable>`. By forming a immutable pointer, the programmer is conveying to the compiler that the data at the pointer address will never change during the execution of the current program. Therefore loads from immutable pointers can be deduplicated by the compiler, and will translate to `__ldg` when generating code for CUDA. The SPIRV backend is not changed in this PR, since the current SPIRV spec makes it very difficult to specify loads from immutable address without generating tons of wrappers and boilerplate type declarations. We would like to see the spec evolved a bit to around its support of `NonWritable` physical storage pointers or immutable loads before we attempt to express such immutability in SPIRV. For now we simply emit ordinary pointers and loads when generating spirv. --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'source/slang/core.meta.slang')
-rw-r--r--source/slang/core.meta.slang28
1 files changed, 26 insertions, 2 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index ddee52b6b..2bf832eef 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -1300,11 +1300,29 @@ enum MemoryScope : int32_t
}
/// @category misc_types
+/// Describes the access permissions for a pointer type.
__magic_enum(AccessQualifier)
enum Access : uint64_t
{
+ /// The data maybe read and modified through the pointer. This is the default access qualifier
+ /// for a pointer type.
ReadWrite = $((uint64_t)AccessQualifier::ReadWrite),
+
+ /// The data being pointed to by a pointer can only be read through the pointer.
+ /// This is to be distinguished from `Immutable`, which means the data being pointed to
+ /// won't be changed by any means. In contrast, data pointed to by a `Read` pointer
+ /// may still be changed through another pointer that is not read-only.
+ /// This means that a pointer with `Read` access is meaningful only to the front-end
+ /// type system, and is not expected to provide any optimization opportunities to
+ /// the back-end.
Read = $((uint64_t)AccessQualifier::Read),
+
+ /// The data being pointed to by a pointer is known to be immutable and won't
+ /// be changed by any means during the execution of the program. It is UB if
+ /// the data is changed during the program execution. This is a stronger
+ /// qualifier than `Read`, and may allow the backend to perform more aggressive
+ /// optimizations.
+ Immutable = $((uint64_t)AccessQualifier::Immutable),
}
//@public:
@@ -1314,8 +1332,8 @@ enum Access : uint64_t
__magic_type(PtrType)
struct Ptr<
T,
- Access access = Access::ReadWrite,
- AddressSpace addrSpace = AddressSpace::Device>
+ Access access = Access.ReadWrite,
+ AddressSpace addrSpace = AddressSpace.Device>
{
// A user is allowed to explicitly cast between any pointer type of
// the same address space
@@ -1373,6 +1391,12 @@ struct Ptr<
}
};
+/// Represents a pointer to immutable data. Immutable data is known at compile time to remain unchanged during the entire
+/// execution of the program. This knowledge allows the compiler to perform more aggressive optimizations around the memory
+/// accesses through such pointers. If the data is changed during the program execution, the behavior is undefined and loaded
+/// data through such pointers may be invalid.
+typealias ImmutablePtr<T, AddressSpace addrSpace = AddressSpace.Device> = Ptr<T, Access.Immutable, addrSpace>;
+
//@hidden:
__intrinsic_op($(kIROp_AlignedAttr))
internal int __align_attr(int alignment);