diff --git a/Src/ILGPU.Analyzers/ReaderDelegatesGenerator.cs b/Src/ILGPU.Analyzers/ReaderDelegatesGenerator.cs
index ca82a6cd6..3ee0eeca3 100644
--- a/Src/ILGPU.Analyzers/ReaderDelegatesGenerator.cs
+++ b/Src/ILGPU.Analyzers/ReaderDelegatesGenerator.cs
@@ -37,6 +37,8 @@ public void OnVisitSyntaxNode(SyntaxNode node)
{
AttributeSyntax? attribute;
if (node is ClassDeclarationSyntax cl &&
+ cl.Parent is NamespaceDeclarationSyntax ns &&
+ ns.Name.ToString().StartsWith("ILGPU.IR.Values") &&
(attribute = cl.AttributeLists.SelectMany(x => x.Attributes)
.SingleOrDefault(attr => attr.Name.ToString() == "ValueKind"))
is not null)
@@ -72,7 +74,7 @@ public void Execute(GeneratorExecutionContext context)
builder.AppendLine(" {");
foreach (var kv in valueKindReciever.ValueKinds)
{
- builder.AppendLine($" _readerDelegates.Add({kv.Key}, {kv.Value}.Read);");
+ builder.AppendLine($" _readerDelegates.TryAdd({kv.Key}, {kv.Value}.Read);");
}
builder.AppendLine(" }");
builder.AppendLine(" }");
diff --git a/Src/ILGPU/IR/Values/AlignValues.cs b/Src/ILGPU/IR/Values/AlignValues.cs
index d4eaca3ed..693c1b768 100644
--- a/Src/ILGPU/IR/Values/AlignValues.cs
+++ b/Src/ILGPU/IR/Values/AlignValues.cs
@@ -105,8 +105,32 @@ protected override string ToArgString() =>
/// Aligns a pointer or a view to a specified alignment in bytes.
///
[ValueKind(ValueKind.AlignTo)]
- public sealed class AlignTo : BaseAlignOperationValue
+ public sealed class AlignTo : BaseAlignOperationValue, IValueReader
{
+ #region Static
+
+ ///
+ public static Value? Read(ValueHeader header, IIRReader reader)
+ {
+ var methodBuilder = header.Method?.MethodBuilder;
+ if (methodBuilder is not null &&
+ header.Block is not null &&
+ header.Block.GetOrCreateBuilder(methodBuilder,
+ out BasicBlock.Builder? blockBuilder))
+ {
+ return blockBuilder.CreateAlignTo(
+ Location.Unknown,
+ header.Nodes[0],
+ header.Nodes[1]);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ #endregion
+
#region Instance
///
@@ -187,8 +211,32 @@ protected override string ToPrefixString() =>
/// bytes.
///
[ValueKind(ValueKind.AsAligned)]
- public sealed class AsAligned : BaseAlignOperationValue
+ public sealed class AsAligned : BaseAlignOperationValue, IValueReader
{
+ #region Static
+
+ ///
+ public static Value? Read(ValueHeader header, IIRReader reader)
+ {
+ var methodBuilder = header.Method?.MethodBuilder;
+ if (methodBuilder is not null &&
+ header.Block is not null &&
+ header.Block.GetOrCreateBuilder(methodBuilder,
+ out BasicBlock.Builder? blockBuilder))
+ {
+ return blockBuilder.CreateAsAligned(
+ Location.Unknown,
+ header.Nodes[0],
+ header.Nodes[1]);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ #endregion
+
#region Instance
///
diff --git a/Src/ILGPU/IR/Values/Cast.cs b/Src/ILGPU/IR/Values/Cast.cs
index a467b84f0..db1f6af2f 100644
--- a/Src/ILGPU/IR/Values/Cast.cs
+++ b/Src/ILGPU/IR/Values/Cast.cs
@@ -353,8 +353,34 @@ protected internal override void Write(T writer) =>
/// Cast a pointer from one address space to another.
///
[ValueKind(ValueKind.AddressSpaceCast)]
- public sealed class AddressSpaceCast : BaseAddressSpaceCast
+ public sealed class AddressSpaceCast : BaseAddressSpaceCast, IValueReader
{
+ #region Static
+
+ ///
+ public static Value? Read(ValueHeader header, IIRReader reader)
+ {
+ var methodBuilder = header.Method?.MethodBuilder;
+ if (methodBuilder is not null &&
+ header.Block is not null &&
+ header.Block.GetOrCreateBuilder(methodBuilder,
+ out BasicBlock.Builder? blockBuilder) &&
+ reader.Read(out MemoryAddressSpace targetAddrSpace))
+ {
+ return blockBuilder.CreateAddressSpaceCast(
+ Location.Unknown,
+ header.Nodes[0],
+ targetAddrSpace
+ );
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ #endregion
+
#region Instance
///
diff --git a/Src/ILGPU/IR/Values/DeviceConstants.cs b/Src/ILGPU/IR/Values/DeviceConstants.cs
index d829de0b7..9fead9efd 100644
--- a/Src/ILGPU/IR/Values/DeviceConstants.cs
+++ b/Src/ILGPU/IR/Values/DeviceConstants.cs
@@ -41,8 +41,30 @@ internal DeviceConstantValue(
/// Represents the property.
///
[ValueKind(ValueKind.AcceleratorType)]
- public sealed class AcceleratorTypeValue : DeviceConstantValue
+ public sealed class AcceleratorTypeValue : DeviceConstantValue, IValueReader
{
+ #region Static
+
+ ///
+ public static Value? Read(ValueHeader header, IIRReader reader)
+ {
+ var methodBuilder = header.Method?.MethodBuilder;
+ if (methodBuilder is not null &&
+ header.Block is not null &&
+ header.Block.GetOrCreateBuilder(methodBuilder,
+ out BasicBlock.Builder? blockBuilder))
+ {
+ return blockBuilder.CreateAcceleratorTypeValue(
+ Location.Unknown);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ #endregion
+
#region Instance
///
diff --git a/Src/ILGPU/IR/Values/Memory.cs b/Src/ILGPU/IR/Values/Memory.cs
index 97c1e1f56..0c0509bcc 100644
--- a/Src/ILGPU/IR/Values/Memory.cs
+++ b/Src/ILGPU/IR/Values/Memory.cs
@@ -48,8 +48,35 @@ internal MemoryValue(in ValueInitializer initializer, TypeNode staticType)
/// Represents an allocation operation on the stack.
///
[ValueKind(ValueKind.Alloca)]
- public sealed class Alloca : MemoryValue
+ public sealed class Alloca : MemoryValue, IValueReader
{
+ #region Static
+
+ ///
+ public static Value? Read(ValueHeader header, IIRReader reader)
+ {
+ var methodBuilder = header.Method?.MethodBuilder;
+ if (methodBuilder is not null &&
+ header.Block is not null &&
+ header.Block.GetOrCreateBuilder(methodBuilder,
+ out BasicBlock.Builder? blockBuilder) &&
+
+ reader.Read(out long allocaTypeId) &&
+ reader.Read(out MemoryAddressSpace addrSpace))
+ {
+ return blockBuilder.CreateAlloca(
+ Location.Unknown,
+ reader.Context.Types[allocaTypeId],
+ addrSpace);
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ #endregion
+
#region Instance
///
@@ -141,8 +168,11 @@ protected internal override Value Rebuild(
rebuilder.Rebuild(ArrayLength));
///
- protected internal override void Write(T writer) =>
+ protected internal override void Write(T writer)
+ {
+ writer.Write(nameof(AllocaType), AllocaType.Id);
writer.Write(nameof(AddressSpace), AddressSpace);
+ }
///
public override void Accept(T visitor) => visitor.Visit(this);
diff --git a/Src/ILGPU/IR/Values/Undefined.cs b/Src/ILGPU/IR/Values/Undefined.cs
index 91b40ec58..1cd746b37 100644
--- a/Src/ILGPU/IR/Values/Undefined.cs
+++ b/Src/ILGPU/IR/Values/Undefined.cs
@@ -18,8 +18,29 @@ namespace ILGPU.IR.Values
/// Represents an undefined value.
///
[ValueKind(ValueKind.Undefined)]
- public sealed class UndefinedValue : Value
+ public sealed class UndefinedValue : Value, IValueReader
{
+ #region Static
+
+ ///
+ public static Value? Read(ValueHeader header, IIRReader reader)
+ {
+ var methodBuilder = header.Method?.MethodBuilder;
+ if (methodBuilder is not null &&
+ header.Block is not null &&
+ header.Block.GetOrCreateBuilder(methodBuilder,
+ out BasicBlock.Builder? blockBuilder))
+ {
+ return blockBuilder.CreateUndefined();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ #endregion
+
#region Instance
///
diff --git a/Src/ILGPU/IR/Values/ValueKind.cs b/Src/ILGPU/IR/Values/ValueKind.cs
index 678c2f776..1a9176076 100644
--- a/Src/ILGPU/IR/Values/ValueKind.cs
+++ b/Src/ILGPU/IR/Values/ValueKind.cs
@@ -12,6 +12,7 @@
using ILGPU.IR.Serialization;
using ILGPU.Util;
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;
@@ -396,7 +397,7 @@ public ValueKindAttribute(ValueKind kind)
///
public static partial class ValueKinds
{
- private readonly static Dictionary _readerDelegates = new();
///