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(); ///