diff --git a/LICENSE-3RD-PARTY.txt b/LICENSE-3RD-PARTY.txt index 2323141ca..03d07731b 100644 --- a/LICENSE-3RD-PARTY.txt +++ b/LICENSE-3RD-PARTY.txt @@ -9,6 +9,8 @@ ILGPU Dependencies: (https://www.nuget.org/packages/System.Reflection.Metadata) - System.Runtime.CompilerServices.Unsafe (https://www.nuget.org/packages/system.runtime.CompilerServices.Unsafe/) + - .NET Runtime + (https://github.com/dotnet/runtime/) ******************************************************************************** ******************************************************************************** @@ -38,3 +40,11 @@ http://go.microsoft.com/fwlink/?LinkId=329770 System.Runtime.CompilerServices.Unsafe license can be found via: http://go.microsoft.com/fwlink/?LinkId=329770 + +******************************************************************************** + ILGPU Compiler Dependency: .NET Runtime + +For compatibility with older frameworks, parts of ILGPU makes use of source +code for Nullable Attributes from the .NET runtime. This code is licensed +under the MIT license, and can be found via: +https://raw.githubusercontent.com/dotnet/runtime/v7.0.0/LICENSE.TXT diff --git a/Src/Directory.Build.props b/Src/Directory.Build.props index 9f2832a31..b319281b3 100644 --- a/Src/Directory.Build.props +++ b/Src/Directory.Build.props @@ -2,6 +2,7 @@ net7.0 + $(LibraryTargetFrameworks) $(LibraryTargetFrameworks);net471;netstandard2.1;net5.0;net6.0 @@ -18,6 +19,7 @@ net7.0 + $(LibraryUnitTestTargetFrameworks) $(LibraryUnitTestTargetFrameworks);net471;netcoreapp3.1;net5.0;net6.0 diff --git a/Src/ILGPU.Algorithms.Tests/Generic/AlgorithmsTestData.tt b/Src/ILGPU.Algorithms.Tests/Generic/AlgorithmsTestData.tt index dcc6fcbf0..0f9129dcf 100644 --- a/Src/ILGPU.Algorithms.Tests/Generic/AlgorithmsTestData.tt +++ b/Src/ILGPU.Algorithms.Tests/Generic/AlgorithmsTestData.tt @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: AlgorithmsTestData.tt/AlgorithmsTestData.cs @@ -16,6 +16,7 @@ using ILGPU.Algorithms.RadixSortOperations; using ILGPU.Algorithms.ScanReduceOperations; +using ILGPU.Util; using System.Numerics; using System.Runtime.CompilerServices; using Xunit.Abstractions; @@ -30,7 +31,10 @@ namespace ILGPU.Algorithms.Tests public class AlgorithmsTestData : IXunitSerializable { - public AlgorithmsTestData() { } + public AlgorithmsTestData() + { + Value = Utilities.InitNotNullable(); + } public AlgorithmsTestData(T value) { @@ -48,7 +52,7 @@ namespace ILGPU.Algorithms.Tests info.AddValue(nameof(Value), Value); } - public override string ToString() => Value.ToString(); + public override string ToString() => $"{Value}"; } #region Xunit Sequencer Structures diff --git a/Src/ILGPU.Algorithms.Tests/ILGPU.Algorithms.Tests.csproj b/Src/ILGPU.Algorithms.Tests/ILGPU.Algorithms.Tests.csproj index 71621a973..c2ad09328 100644 --- a/Src/ILGPU.Algorithms.Tests/ILGPU.Algorithms.Tests.csproj +++ b/Src/ILGPU.Algorithms.Tests/ILGPU.Algorithms.Tests.csproj @@ -6,6 +6,14 @@ latest + + + enable + + + $(NoWarn);nullable + + $(MSBuildProjectDirectory)\..\ILGPU.Tests\.test.runsettings diff --git a/Src/ILGPU.Algorithms/CL/CLContext.cs b/Src/ILGPU.Algorithms/CL/CLContext.cs index eb03072ee..5f9c7222a 100644 --- a/Src/ILGPU.Algorithms/CL/CLContext.cs +++ b/Src/ILGPU.Algorithms/CL/CLContext.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CLContext.cs @@ -40,7 +40,8 @@ static partial class CLContext private static readonly MethodInfo MathCodeGenerator = CLMathType.GetMethod( nameof(CLMath.GenerateMathIntrinsic), - AlgorithmContext.IntrinsicBindingFlags); + AlgorithmContext.IntrinsicBindingFlags) + .ThrowIfNull(); /// /// Represents the intrinsic representation of the @@ -49,7 +50,8 @@ static partial class CLContext private static readonly CLIntrinsic MathCodeGeneratorIntrinsic = new CLIntrinsic( MathCodeGenerator, - IntrinsicImplementationMode.GenerateCode); + IntrinsicImplementationMode.GenerateCode) + .ThrowIfNull(); /// /// The type. @@ -74,7 +76,8 @@ private static CLIntrinsic GetMathIntrinsic(string name, params Type[] types) AlgorithmContext.IntrinsicBindingFlags, null, types, - null); + null) + .ThrowIfNull(); return new CLIntrinsic(targetMethod, IntrinsicImplementationMode.Redirect); } @@ -93,7 +96,8 @@ private static void RegisterIntrinsicMapping( { var sourceMethod = sourceType.GetMethod( name, - AlgorithmContext.IntrinsicBindingFlags); + AlgorithmContext.IntrinsicBindingFlags) + .ThrowIfNull(); manager.RegisterMethod( sourceMethod, new CLIntrinsic(targetType, name, IntrinsicImplementationMode.Redirect)); @@ -118,7 +122,8 @@ private static void RegisterIntrinsicCodeGenerator( { var sourceMethod = sourceType.GetMethod( name, - AlgorithmContext.IntrinsicBindingFlags); + AlgorithmContext.IntrinsicBindingFlags) + .ThrowIfNull(); manager.RegisterMethod( sourceMethod, new CLIntrinsic( @@ -150,7 +155,8 @@ private static void RegisterXMathCodeGenerator( AlgorithmContext.IntrinsicBindingFlags, null, types, - null), + null) + .ThrowIfNull(), new CLIntrinsic( targetType, codeGeneratorName, @@ -176,7 +182,7 @@ internal static void GenerateScanReduce( where TScanReduce : struct, IScanReduceOperation { // Allocate target and load source argument - var reduce = value as MethodCall; + var reduce = value.AsNotNullCast(); var sourceValue = codeGenerator.Load(reduce[0]); var target = codeGenerator.Allocate(value); diff --git a/Src/ILGPU.Algorithms/CL/CLMath.cs b/Src/ILGPU.Algorithms/CL/CLMath.cs index 75d45723c..de2acbe53 100644 --- a/Src/ILGPU.Algorithms/CL/CLMath.cs +++ b/Src/ILGPU.Algorithms/CL/CLMath.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: CLMath.cs @@ -35,7 +35,7 @@ public static void GenerateMathIntrinsic( Value value) { // Manually generate code for "1.0 / argument" - var arithmeticValue = value as UnaryArithmeticValue; + var arithmeticValue = value.AsNotNullCast(); var argument = codeGenerator.Load(arithmeticValue.Value); var target = codeGenerator.Allocate(arithmeticValue); var operation = CLInstructions.GetArithmeticOperation( diff --git a/Src/ILGPU.Algorithms/ConcurrentStreamProcessor.cs b/Src/ILGPU.Algorithms/ConcurrentStreamProcessor.cs index f3c67fe57..ffcc6eab4 100644 --- a/Src/ILGPU.Algorithms/ConcurrentStreamProcessor.cs +++ b/Src/ILGPU.Algorithms/ConcurrentStreamProcessor.cs @@ -38,7 +38,7 @@ public class ConcurrentStreamProcessor : DisposeBase public ConcurrentStreamProcessor( Accelerator accelerator, int maxNumConcurrentStreams = 0, - Func streamProvider = null) + Func? streamProvider = null) { maxNumConcurrentStreams = Math.Max( Math.Max(maxNumConcurrentStreams, 1), @@ -93,7 +93,7 @@ public void ProcessConcurrently( /// The action to invoke on each stream to submit work. /// public void ProcessConcurrently( - AcceleratorStream stream, + AcceleratorStream? stream, int numActions, Action action) { diff --git a/Src/ILGPU.Algorithms/HistogramExtensions.cs b/Src/ILGPU.Algorithms/HistogramExtensions.cs index ca494654c..669030d0d 100644 --- a/Src/ILGPU.Algorithms/HistogramExtensions.cs +++ b/Src/ILGPU.Algorithms/HistogramExtensions.cs @@ -12,6 +12,7 @@ using ILGPU.Algorithms.HistogramOperations; using ILGPU.Algorithms.Resources; using ILGPU.Runtime; +using ILGPU.Util; using System; using System.Reflection; @@ -145,12 +146,14 @@ private delegate void HistogramUncheckedDelegate< private static readonly MethodInfo HistogramKernelMethod = typeof(HistogramExtensions).GetMethod( nameof(HistogramKernel), - BindingFlags.NonPublic | BindingFlags.Static); + BindingFlags.NonPublic | BindingFlags.Static) + .ThrowIfNull(); private static readonly MethodInfo HistogramUncheckedKernelMethod = typeof(HistogramExtensions).GetMethod( nameof(HistogramUncheckedKernel), - BindingFlags.NonPublic | BindingFlags.Static); + BindingFlags.NonPublic | BindingFlags.Static) + .ThrowIfNull(); /// /// The actual histogram kernel implementation. diff --git a/Src/ILGPU.Algorithms/IL/ILContext.cs b/Src/ILGPU.Algorithms/IL/ILContext.cs index 5be5c274d..a3532ba7d 100644 --- a/Src/ILGPU.Algorithms/IL/ILContext.cs +++ b/Src/ILGPU.Algorithms/IL/ILContext.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: ILContext.cs @@ -12,6 +12,7 @@ using ILGPU.Backends; using ILGPU.Backends.IL; using ILGPU.IR.Intrinsics; +using ILGPU.Util; using System; namespace ILGPU.Algorithms.IL @@ -63,7 +64,8 @@ private static void RegisterIntrinsicMapping( { var sourceMethod = sourceType.GetMethod( name, - AlgorithmContext.IntrinsicBindingFlags); + AlgorithmContext.IntrinsicBindingFlags) + .ThrowIfNull(); manager.RegisterMethod( sourceMethod, new ILIntrinsic(targetType, name, IntrinsicImplementationMode.Redirect)); diff --git a/Src/ILGPU.Algorithms/ILGPU.Algorithms.csproj b/Src/ILGPU.Algorithms/ILGPU.Algorithms.csproj index 20d86661e..a312c8fd6 100644 --- a/Src/ILGPU.Algorithms/ILGPU.Algorithms.csproj +++ b/Src/ILGPU.Algorithms/ILGPU.Algorithms.csproj @@ -10,6 +10,14 @@ $(LibraryFileVersion) + + + enable + + + $(NoWarn);nullable + + true en-US @@ -23,6 +31,10 @@ Debug;Release + + + + True diff --git a/Src/ILGPU.Algorithms/MatrixOperations/MaskedMatrixProcessor.cs b/Src/ILGPU.Algorithms/MatrixOperations/MaskedMatrixProcessor.cs index 0ecb86e9f..8e072743e 100644 --- a/Src/ILGPU.Algorithms/MatrixOperations/MaskedMatrixProcessor.cs +++ b/Src/ILGPU.Algorithms/MatrixOperations/MaskedMatrixProcessor.cs @@ -48,7 +48,7 @@ private readonly MaskedSparseMatrixMultiplier public MaskedMatrixProcessor( Accelerator accelerator, int maxNumConcurrentStreams = 0, - Func streamProvider = null) + Func? streamProvider = null) : base(accelerator, maxNumConcurrentStreams, streamProvider) { matrixMultiplier = accelerator.CreateSparseTransposedMatrixMultiplierMasked< diff --git a/Src/ILGPU.Algorithms/PTX/PTXContext.cs b/Src/ILGPU.Algorithms/PTX/PTXContext.cs index 98e869ac2..61a268508 100644 --- a/Src/ILGPU.Algorithms/PTX/PTXContext.cs +++ b/Src/ILGPU.Algorithms/PTX/PTXContext.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: PTXContext.cs @@ -12,6 +12,7 @@ using ILGPU.Backends.PTX; using ILGPU.IR.Intrinsics; using ILGPU.Runtime.Cuda; +using ILGPU.Util; using System; using System.Reflection; @@ -35,7 +36,8 @@ static partial class PTXContext private static readonly MethodInfo MathCodeGenerator = PTXMathType.GetMethod( nameof(PTXMath.GenerateMathIntrinsic), - AlgorithmContext.IntrinsicBindingFlags); + AlgorithmContext.IntrinsicBindingFlags) + .ThrowIfNull(); /// /// Represents the intrinsic representation of the @@ -44,7 +46,8 @@ static partial class PTXContext private static readonly PTXIntrinsic MathCodeGeneratorIntrinsic = new PTXIntrinsic( MathCodeGenerator, - IntrinsicImplementationMode.GenerateCode); + IntrinsicImplementationMode.GenerateCode) + .ThrowIfNull(); /// /// The type. @@ -82,7 +85,8 @@ private static PTXIntrinsic GetMathIntrinsic(string name, params Type[] types) AlgorithmContext.IntrinsicBindingFlags, null, types, - null); + null) + .ThrowIfNull(); return new PTXIntrinsic(targetMethod, IntrinsicImplementationMode.Redirect); } @@ -101,7 +105,8 @@ private static void RegisterIntrinsicMapping( { var sourceMethod = sourceType.GetMethod( name, - AlgorithmContext.IntrinsicBindingFlags); + AlgorithmContext.IntrinsicBindingFlags) + .ThrowIfNull(); manager.RegisterMethod( sourceMethod, new PTXIntrinsic(targetType, name, IntrinsicImplementationMode.Redirect)); @@ -130,14 +135,16 @@ private static void RegisterXMathRedirect( AlgorithmContext.IntrinsicBindingFlags, null, types, - null), + null) + .ThrowIfNull(), new PTXIntrinsic( targetType.GetMethod( replacementName, AlgorithmContext.IntrinsicBindingFlags, null, types, - null), + null) + .ThrowIfNull(), IntrinsicImplementationMode.Redirect)); } } diff --git a/Src/ILGPU.Algorithms/PTX/PTXMath.cs b/Src/ILGPU.Algorithms/PTX/PTXMath.cs index 487231f8c..3c55fc7b2 100644 --- a/Src/ILGPU.Algorithms/PTX/PTXMath.cs +++ b/Src/ILGPU.Algorithms/PTX/PTXMath.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: PTXMath.cs @@ -39,7 +39,7 @@ public static void GenerateMathIntrinsic( PTXCodeGenerator codeGenerator, Value value) { - var arithmeticValue = value as UnaryArithmeticValue; + var arithmeticValue = value.AsNotNullCast(); var instruction = PTXInstructions.GetArithmeticOperation( arithmeticValue.Kind, arithmeticValue.ArithmeticBasicValueType, diff --git a/Src/ILGPU.Algorithms/PTX/PTXWarpExtensions.cs b/Src/ILGPU.Algorithms/PTX/PTXWarpExtensions.cs index 58d30361f..5f88d8045 100644 --- a/Src/ILGPU.Algorithms/PTX/PTXWarpExtensions.cs +++ b/Src/ILGPU.Algorithms/PTX/PTXWarpExtensions.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: PTXWarpExtensions.cs @@ -25,7 +25,7 @@ static class PTXWarpExtensions [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T Reduce(T value) where T : unmanaged - where TReduction : IScanReduceOperation + where TReduction : struct, IScanReduceOperation { TReduction reduction = default; for (int laneOffset = Warp.WarpSize / 2; laneOffset > 0; laneOffset >>= 1) @@ -40,7 +40,7 @@ public static T Reduce(T value) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static T AllReduce(T value) where T : unmanaged - where TReduction : IScanReduceOperation + where TReduction : struct, IScanReduceOperation { TReduction reduction = default; for (int laneMask = Warp.WarpSize / 2; laneMask > 0; laneMask >>= 1) diff --git a/Src/ILGPU.Algorithms/RadixSortExtensions.cs b/Src/ILGPU.Algorithms/RadixSortExtensions.cs index 9d2d03dc1..7669b07ad 100644 --- a/Src/ILGPU.Algorithms/RadixSortExtensions.cs +++ b/Src/ILGPU.Algorithms/RadixSortExtensions.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2019-2022 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: RadixSortExtensions.cs @@ -541,22 +541,26 @@ public readonly int ExtractRadixBits( private static readonly MethodInfo CPURadixSortKernel1Method = typeof(RadixSortExtensions).GetMethod( nameof(CPURadixSortKernel1), - BindingFlags.NonPublic | BindingFlags.Static); + BindingFlags.NonPublic | BindingFlags.Static) + .ThrowIfNull(); private static readonly MethodInfo CPURadixSortKernel2Method = typeof(RadixSortExtensions).GetMethod( nameof(CPURadixSortKernel2), - BindingFlags.NonPublic | BindingFlags.Static); + BindingFlags.NonPublic | BindingFlags.Static) + .ThrowIfNull(); private static readonly MethodInfo RadixSortKernel1Method = typeof(RadixSortExtensions).GetMethod( nameof(RadixSortKernel1), - BindingFlags.NonPublic | BindingFlags.Static); + BindingFlags.NonPublic | BindingFlags.Static) + .ThrowIfNull(); private static readonly MethodInfo RadixSortKernel2Method = typeof(RadixSortExtensions).GetMethod( nameof(RadixSortKernel2), - BindingFlags.NonPublic | BindingFlags.Static); + BindingFlags.NonPublic | BindingFlags.Static) + .ThrowIfNull(); /// /// Represents a single specialization. diff --git a/Src/ILGPU.Algorithms/Random/XorShift128.cs b/Src/ILGPU.Algorithms/Random/XorShift128.cs index 9d1a6b7c7..71e1a7c03 100644 --- a/Src/ILGPU.Algorithms/Random/XorShift128.cs +++ b/Src/ILGPU.Algorithms/Random/XorShift128.cs @@ -193,7 +193,7 @@ public readonly override int GetHashCode() => /// /// The other rng to test. /// True, if the given object is equal to the current rng. - public readonly override bool Equals(object obj) => + public readonly override bool Equals(object? obj) => obj is XorShift128 shift && Equals(shift); /// diff --git a/Src/ILGPU.Algorithms/Random/XorShift128Plus.cs b/Src/ILGPU.Algorithms/Random/XorShift128Plus.cs index bcd14a6e4..89ecb7106 100644 --- a/Src/ILGPU.Algorithms/Random/XorShift128Plus.cs +++ b/Src/ILGPU.Algorithms/Random/XorShift128Plus.cs @@ -173,7 +173,7 @@ public readonly XorShift128Plus CreateProvider( /// /// The other rng to test. /// True, if the given object is equal to the current rng. - public readonly override bool Equals(object obj) => + public readonly override bool Equals(object? obj) => obj is XorShift128Plus shift && Equals(shift); /// diff --git a/Src/ILGPU.Algorithms/Random/XorShift32.cs b/Src/ILGPU.Algorithms/Random/XorShift32.cs index 6f6cad70b..72730de71 100644 --- a/Src/ILGPU.Algorithms/Random/XorShift32.cs +++ b/Src/ILGPU.Algorithms/Random/XorShift32.cs @@ -143,7 +143,7 @@ public readonly XorShift32 CreateProvider(ref TProvider random) /// /// The other rng to test. /// True, if the given object is equal to the current rng. - public readonly override bool Equals(object obj) => + public readonly override bool Equals(object? obj) => obj is XorShift32 shift && Equals(shift); /// diff --git a/Src/ILGPU.Algorithms/Random/XorShift64Star.cs b/Src/ILGPU.Algorithms/Random/XorShift64Star.cs index 211036b67..d1df63694 100644 --- a/Src/ILGPU.Algorithms/Random/XorShift64Star.cs +++ b/Src/ILGPU.Algorithms/Random/XorShift64Star.cs @@ -147,7 +147,7 @@ public readonly XorShift64Star CreateProvider( /// /// The other rng to test. /// True, if the given object is equal to the current rng. - public readonly override bool Equals(object obj) => + public readonly override bool Equals(object? obj) => obj is XorShift64Star shift && Equals(shift); /// diff --git a/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuBlasAPI.cs b/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuBlasAPI.cs index 2cf438ff7..bb7c6b756 100644 --- a/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuBlasAPI.cs +++ b/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuBlasAPI.cs @@ -28,6 +28,7 @@ internal abstract unsafe partial class CuBlasAPI public static CuBlasAPI Create(CuBlasAPIVersion? version) => version.HasValue ? CreateInternal(version.Value) + ?? throw new DllNotFoundException(nameof(CuBlasAPI)) : CreateLatest(); /// @@ -36,12 +37,15 @@ public static CuBlasAPI Create(CuBlasAPIVersion? version) => /// The created API wrapper. private static CuBlasAPI CreateLatest() { - Exception firstException = null; - var versions = Enum.GetValues(typeof(CuBlasAPIVersion)); - + Exception? firstException = null; +#if NET5_0_OR_GREATER + var versions = Enum.GetValues(); +#else + var versions = (CuBlasAPIVersion[])Enum.GetValues(typeof(CuBlasAPIVersion)); +#endif for (var i = versions.Length - 1; i >= 0; i--) { - var version = (CuBlasAPIVersion)versions.GetValue(i); + var version = versions[i]; var api = CreateInternal(version); if (api is null) continue; diff --git a/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuFFTAPI.cs b/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuFFTAPI.cs index e9e1da9fd..dd6a6e176 100644 --- a/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuFFTAPI.cs +++ b/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuFFTAPI.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: CuFFTAPI.cs @@ -31,6 +31,7 @@ public abstract partial class CuFFTAPI public static CuFFTAPI Create(CuFFTAPIVersion? version) => version.HasValue ? CreateInternal(version.Value) + ?? throw new DllNotFoundException(nameof(CuFFTAPI)) : CreateLatest(); /// @@ -39,12 +40,15 @@ public static CuFFTAPI Create(CuFFTAPIVersion? version) => /// The created API wrapper. private static CuFFTAPI CreateLatest() { - Exception firstException = null; - var versions = Enum.GetValues(typeof(CuFFTAPIVersion)); - + Exception? firstException = null; +#if NET5_0_OR_GREATER + var versions = Enum.GetValues(); +#else + var versions = (CuFFTAPIVersion[])Enum.GetValues(typeof(CuFFTAPIVersion)); +#endif for (var i = versions.Length - 1; i >= 0; i--) { - var version = (CuFFTAPIVersion)versions.GetValue(i); + var version = versions[i]; var api = CreateInternal(version); if (api is null) continue; diff --git a/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuFFTWAPI.cs b/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuFFTWAPI.cs index 8a47023f5..a61d03323 100644 --- a/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuFFTWAPI.cs +++ b/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuFFTWAPI.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: CuFFTWAPI.cs @@ -29,6 +29,7 @@ public abstract partial class CuFFTWAPI public static CuFFTWAPI Create(CuFFTWAPIVersion? version) => version.HasValue ? CreateInternal(version.Value) + ?? throw new DllNotFoundException(nameof(CuFFTWAPI)) : CreateLatest(); /// @@ -37,12 +38,15 @@ public static CuFFTWAPI Create(CuFFTWAPIVersion? version) => /// The created API wrapper. private static CuFFTWAPI CreateLatest() { - Exception firstException = null; - var versions = Enum.GetValues(typeof(CuFFTWAPIVersion)); - + Exception? firstException = null; +#if NET5_0_OR_GREATER + var versions = Enum.GetValues(); +#else + var versions = (CuFFTWAPIVersion[])Enum.GetValues(typeof(CuFFTWAPIVersion)); +#endif for (var i = versions.Length - 1; i >= 0; i--) { - var version = (CuFFTWAPIVersion)versions.GetValue(i); + var version = versions[i]; var api = CreateInternal(version); if (api is null) continue; diff --git a/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuRandAPI.cs b/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuRandAPI.cs index 83f04fec3..372d15e8d 100644 --- a/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuRandAPI.cs +++ b/Src/ILGPU.Algorithms/Runtime/Cuda/API/CuRandAPI.cs @@ -28,6 +28,7 @@ public abstract partial class CuRandAPI public static CuRandAPI Create(CuRandAPIVersion? version) => version.HasValue ? CreateInternal(version.Value) + ?? throw new DllNotFoundException(nameof(CuRandAPI)) : CreateLatest(); /// @@ -36,12 +37,15 @@ public static CuRandAPI Create(CuRandAPIVersion? version) => /// The created API wrapper. private static CuRandAPI CreateLatest() { - Exception firstException = null; - var versions = Enum.GetValues(typeof(CuRandAPIVersion)); - + Exception? firstException = null; +#if NET5_0_OR_GREATER + var versions = Enum.GetValues(); +#else + var versions = (CuRandAPIVersion[])Enum.GetValues(typeof(CuRandAPIVersion)); +#endif for (var i = versions.Length - 1; i >= 0; i--) { - var version = (CuRandAPIVersion)versions.GetValue(i); + var version = versions[i]; var api = CreateInternal(version); if (api != null) { diff --git a/Src/ILGPU.Algorithms/Runtime/Cuda/API/NvJpegAPI.cs b/Src/ILGPU.Algorithms/Runtime/Cuda/API/NvJpegAPI.cs index d6c3c74b7..58548450b 100644 --- a/Src/ILGPU.Algorithms/Runtime/Cuda/API/NvJpegAPI.cs +++ b/Src/ILGPU.Algorithms/Runtime/Cuda/API/NvJpegAPI.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: NvJpegAPI.cs @@ -29,6 +29,7 @@ public abstract partial class NvJpegAPI public static NvJpegAPI Create(NvJpegAPIVersion? version) => version.HasValue ? CreateInternal(version.Value) + ?? throw new DllNotFoundException(nameof(NvJpegAPI)) : CreateLatest(); /// @@ -37,12 +38,15 @@ public static NvJpegAPI Create(NvJpegAPIVersion? version) => /// The created API wrapper. private static NvJpegAPI CreateLatest() { - Exception firstException = null; - var versions = Enum.GetValues(typeof(CuFFTAPIVersion)); - + Exception? firstException = null; +#if NET5_0_OR_GREATER + var versions = Enum.GetValues(); +#else + var versions = (NvJpegAPIVersion[])Enum.GetValues(typeof(NvJpegAPIVersion)); +#endif for (var i = versions.Length - 1; i >= 0; i--) { - var version = (NvJpegAPIVersion)versions.GetValue(i); + var version = versions[i]; var api = CreateInternal(version); if (api is null) continue; @@ -122,7 +126,7 @@ public unsafe NvJpegStatus Decode( ReadOnlySpan imageBytes, NvJpegOutputFormat outputFormat, in NvJpegImage destination, - CudaStream stream) + CudaStream? stream) { var imageInterop = destination.ToInterop(); diff --git a/Src/ILGPU.Algorithms/Runtime/Cuda/API/NvmlAPI.cs b/Src/ILGPU.Algorithms/Runtime/Cuda/API/NvmlAPI.cs index 4c197c734..e85b9956d 100644 --- a/Src/ILGPU.Algorithms/Runtime/Cuda/API/NvmlAPI.cs +++ b/Src/ILGPU.Algorithms/Runtime/Cuda/API/NvmlAPI.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: NvmlAPI.cs @@ -9,6 +9,7 @@ // Source License. See LICENSE.txt for details. // --------------------------------------------------------------------------------------- +using ILGPU.Util; using System; using System.Text; @@ -32,6 +33,7 @@ public abstract partial class NvmlAPI public static NvmlAPI Create(NvmlAPIVersion? version) => version.HasValue ? CreateInternal(version.Value) + ?? throw new DllNotFoundException(nameof(NvmlAPI)) : CreateLatest(); /// @@ -40,12 +42,15 @@ public static NvmlAPI Create(NvmlAPIVersion? version) => /// The created API wrapper. private static NvmlAPI CreateLatest() { - Exception firstException = null; - var versions = Enum.GetValues(typeof(NvmlAPIVersion)); - + Exception? firstException = null; +#if NET5_0_OR_GREATER + var versions = Enum.GetValues(); +#else + var versions = (NvmlAPIVersion[])Enum.GetValues(typeof(NvmlAPIVersion)); +#endif for (var i = versions.Length - 1; i >= 0; i--) { - var version = (NvmlAPIVersion)versions.GetValue(i); + var version = versions[i]; var api = CreateInternal(version); if (api is null) continue; @@ -80,7 +85,7 @@ ex is DllNotFoundException || internal unsafe static NvmlReturn GetNvmlString( Func interopFunc, uint length, - out string nvmlString) + out string? nvmlString) { NvmlReturn result; ReadOnlySpan buffer = @@ -120,7 +125,7 @@ internal unsafe delegate NvmlReturn GetNvmlArrayInterop( /// The interop status code. internal unsafe static NvmlReturn GetNvmlArray( GetNvmlArrayInterop interopFunc, - out T[] nvmlArray) + out T[]? nvmlArray) where T : unmanaged { // Query the length of data available. @@ -176,8 +181,8 @@ internal unsafe delegate NvmlReturn GetNvmlArrayInterop( /// The interop status code. internal unsafe static NvmlReturn GetNvmlArray( GetNvmlArrayInterop interopFunc, - out T1[] nvmlArray1, - out T2[] nvmlArray2) + out T1[]? nvmlArray1, + out T2[]? nvmlArray2) where T1 : unmanaged where T2 : unmanaged { @@ -242,7 +247,7 @@ internal unsafe delegate NvmlReturn FillNvmlArrayInterop( internal unsafe static NvmlReturn FillNvmlArray( FillNvmlArrayInterop interopFunc, uint length, - out T[] nvmlArray) + out T[]? nvmlArray) where T : unmanaged { // Allocate enough space for the requested length. @@ -266,7 +271,7 @@ internal unsafe static NvmlReturn FillNvmlArray( /// public unsafe NvmlReturn DeviceGetBoardPartNumber( IntPtr device, - out string partNumber) => + out string? partNumber) => GetNvmlString( (str, len) => DeviceGetBoardPartNumber_Interop(device, str, len), NvmlConstants.NVML_DEVICE_PART_NUMBER_BUFFER_SIZE, @@ -307,7 +312,7 @@ public unsafe NvmlReturn DeviceGetBridgeChipInfo( /// public unsafe NvmlReturn DeviceGetComputeRunningProcesses( IntPtr device, - out NvmlProcessInfo[] infos) + out NvmlProcessInfo[]? infos) { NvmlReturn Interop(ref uint len, NvmlProcessInfo* ptr) => DeviceGetComputeRunningProcesses_v2_Interop(device, ref len, ptr); @@ -320,7 +325,7 @@ NvmlReturn Interop(ref uint len, NvmlProcessInfo* ptr) => /// public unsafe NvmlReturn DeviceGetEncoderSessions( IntPtr device, - out NvmlEncoderSessionInfo[] sessionInfos) + out NvmlEncoderSessionInfo[]? sessionInfos) { NvmlReturn Interop(ref uint len, NvmlEncoderSessionInfo* ptr) => DeviceGetEncoderSessions_Interop(device, ref len, ptr); @@ -333,7 +338,7 @@ NvmlReturn Interop(ref uint len, NvmlEncoderSessionInfo* ptr) => /// public unsafe NvmlReturn DeviceGetInforomImageVersion( IntPtr device, - out string version) => + out string? version) => GetNvmlString( (str, len) => DeviceGetInforomImageVersion_Interop(device, str, len), NvmlConstants.NVML_DEVICE_INFOROM_VERSION_BUFFER_SIZE, @@ -346,7 +351,7 @@ public unsafe NvmlReturn DeviceGetInforomImageVersion( public unsafe NvmlReturn DeviceGetInforomVersion( IntPtr device, NvmlInforomObject inforomObject, - out string version) => + out string? version) => GetNvmlString( (str, len) => { @@ -365,7 +370,7 @@ public unsafe NvmlReturn DeviceGetInforomVersion( /// public unsafe NvmlReturn DeviceGetGraphicsRunningProcesses( IntPtr device, - out NvmlProcessInfo[] infos) + out NvmlProcessInfo[]? infos) { NvmlReturn Interop(ref uint len, NvmlProcessInfo* ptr) => DeviceGetGraphicsRunningProcesses_v2_Interop(device, ref len, ptr); @@ -378,7 +383,7 @@ NvmlReturn Interop(ref uint len, NvmlProcessInfo* ptr) => /// public unsafe NvmlReturn DeviceGetName( IntPtr device, - out string name) => + out string? name) => GetNvmlString( (str, len) => DeviceGetName_Interop(device, str, len), NvmlConstants.NVML_DEVICE_NAME_V2_BUFFER_SIZE, @@ -438,7 +443,7 @@ public unsafe NvmlReturn DeviceGetPciInfo( public unsafe NvmlReturn DeviceGetRetiredPages( IntPtr device, NvmlPageRetirementCause cause, - out ulong[] addresses) + out ulong[]? addresses) { NvmlReturn Interop(ref uint len, ulong* ptr) => DeviceGetRetiredPages_Interop(device, cause, ref len, ptr); @@ -452,8 +457,8 @@ NvmlReturn Interop(ref uint len, ulong* ptr) => public unsafe NvmlReturn DeviceGetRetiredPages_v2( IntPtr device, NvmlPageRetirementCause cause, - out ulong[] addresses, - out ulong[] timestamps) + out ulong[]? addresses, + out ulong[]? timestamps) { NvmlReturn Interop(ref uint len, ulong* ptr1, ulong* ptr2) => DeviceGetRetiredPages_v2_Interop(device, cause, ref len, ptr1, ptr2); @@ -470,7 +475,7 @@ public unsafe NvmlReturn DeviceGetSamples( ulong lastSeenTimeStamp, out NvmlValueType sampleValType, uint sampleCount, - out NvmlSample[] samples) + out NvmlSample[]? samples) { // Allocate enough space for sampleCount. uint length = sampleCount; @@ -507,7 +512,7 @@ public unsafe NvmlReturn DeviceGetSamples( /// public unsafe NvmlReturn DeviceGetSerial( IntPtr device, - out string serial) => + out string? serial) => GetNvmlString( (str, len) => DeviceGetSerial_Interop(device, str, len), NvmlConstants.NVML_DEVICE_SERIAL_BUFFER_SIZE, @@ -520,7 +525,7 @@ public unsafe NvmlReturn DeviceGetSerial( public unsafe NvmlReturn DeviceGetSupportedGraphicsClocks( IntPtr device, uint memoryClockMHz, - out uint[] clocksMHz) + out uint[]? clocksMHz) { NvmlReturn Interop(ref uint len, uint* ptr) => DeviceGetSupportedGraphicsClocks_Interop( @@ -537,7 +542,7 @@ NvmlReturn Interop(ref uint len, uint* ptr) => /// public unsafe NvmlReturn DeviceGetSupportedMemoryClocks( IntPtr device, - out uint[] clocksMHz) + out uint[]? clocksMHz) { NvmlReturn Interop(ref uint len, uint* ptr) => DeviceGetSupportedMemoryClocks_Interop(device, ref len, ptr); @@ -551,7 +556,7 @@ NvmlReturn Interop(ref uint len, uint* ptr) => public unsafe NvmlReturn DeviceGetTopologyNearestGpus( IntPtr device, NvmlGpuTopologyLevel level, - out IntPtr[] deviceArray) + out IntPtr[]? deviceArray) { NvmlReturn Interop(ref uint len, IntPtr* ptr) => DeviceGetTopologyNearestGpus_Interop(device, level, ref len, ptr); @@ -564,7 +569,7 @@ NvmlReturn Interop(ref uint len, IntPtr* ptr) => /// public unsafe NvmlReturn DeviceGetUUID( IntPtr device, - out string uuid) => + out string? uuid) => GetNvmlString( (str, len) => DeviceGetUUID_Interop(device, str, len), NvmlConstants.NVML_DEVICE_UUID_V2_BUFFER_SIZE, @@ -576,7 +581,7 @@ public unsafe NvmlReturn DeviceGetUUID( /// public unsafe NvmlReturn DeviceGetVbiosVersion( IntPtr device, - out string version) => + out string? version) => GetNvmlString( (str, len) => DeviceGetVbiosVersion_Interop(device, str, len), NvmlConstants.NVML_DEVICE_VBIOS_VERSION_BUFFER_SIZE, @@ -588,7 +593,7 @@ public unsafe NvmlReturn DeviceGetVbiosVersion( /// public unsafe NvmlReturn SystemGetTopologyGpuSet( uint cpuNumber, - out IntPtr[] deviceArray) + out IntPtr[]? deviceArray) { NvmlReturn Interop(ref uint len, IntPtr* ptr) => SystemGetTopologyGpuSet_Interop(cpuNumber, ref len, ptr); @@ -601,7 +606,7 @@ NvmlReturn Interop(ref uint len, IntPtr* ptr) => /// public unsafe NvmlReturn VgpuInstanceGetMdevUUID( uint vgpuInstance, - out string version) => + out string? version) => GetNvmlString( (str, len) => VgpuInstanceGetMdevUUID_Interop(vgpuInstance, str, len), NvmlConstants.NVML_DEVICE_UUID_V2_BUFFER_SIZE, @@ -618,7 +623,7 @@ public unsafe NvmlReturn VgpuInstanceGetMdevUUID( public unsafe NvmlReturn DeviceGetCpuAffinity( IntPtr device, uint cpuSetSize, - out ulong[] cpuSet) + out ulong[]? cpuSet) { NvmlReturn Interop(uint len, ulong* ptr) => DeviceGetCpuAffinity_Interop(device, len, ptr); @@ -632,7 +637,7 @@ NvmlReturn Interop(uint len, ulong* ptr) => public unsafe NvmlReturn DeviceGetCpuAffinityWithinScope( IntPtr device, uint cpuSetSize, - out ulong[] cpuSet, + out ulong[]? cpuSet, NvmlAffinityScope scope) { NvmlReturn Interop(uint len, ulong* ptr) => @@ -647,7 +652,7 @@ NvmlReturn Interop(uint len, ulong* ptr) => public unsafe NvmlReturn DeviceGetMemoryAffinity( IntPtr device, uint nodeSetSize, - out ulong[] nodeSet, + out ulong[]? nodeSet, NvmlAffinityScope scope) { NvmlReturn Interop(uint len, ulong* ptr) => @@ -691,7 +696,7 @@ public NvmlReturn SystemGetCudaDriverVersion_v2( /// Provides access to /// without using raw pointers. /// - public NvmlReturn SystemGetDriverVersion(out string version) => + public NvmlReturn SystemGetDriverVersion(out string? version) => GetNvmlString( (str, len) => SystemGetDriverVersion_Interop(str, len), NvmlConstants.NVML_SYSTEM_DRIVER_VERSION_BUFFER_SIZE, @@ -701,7 +706,7 @@ public NvmlReturn SystemGetDriverVersion(out string version) => /// Provides access to /// without using raw pointers. /// - public NvmlReturn SystemGetNVMLVersion(out string version) => + public NvmlReturn SystemGetNVMLVersion(out string? version) => GetNvmlString( (str, len) => SystemGetNVMLVersion_Interop(str, len), NvmlConstants.NVML_SYSTEM_NVML_VERSION_BUFFER_SIZE, @@ -713,7 +718,7 @@ public NvmlReturn SystemGetNVMLVersion(out string version) => /// public NvmlReturn SystemGetProcessName( uint pid, - out string name, + out string? name, uint length) => GetNvmlString( (str, len) => SystemGetProcessName_Interop(pid, str, len), @@ -728,7 +733,7 @@ public NvmlReturn SystemGetProcessName( /// Provides access to /// without using raw pointers. /// - public unsafe NvmlReturn SystemGetHicVersion(out NvmlHwbcEntry[] hwbcEntries) + public unsafe NvmlReturn SystemGetHicVersion(out NvmlHwbcEntry[]? hwbcEntries) { NvmlReturn Interop(ref uint len, NvmlHwbcEntry_Interop* ptr) => SystemGetHicVersion_Interop(ref len, ptr); @@ -737,6 +742,7 @@ NvmlReturn Interop(ref uint len, NvmlHwbcEntry_Interop* ptr) => out var interopResult); if (result == NvmlReturn.NVML_SUCCESS) { + interopResult = interopResult.AsNotNull(); hwbcEntries = new NvmlHwbcEntry[interopResult.Length]; for (int i = 0; i < interopResult.Length; i++) { @@ -770,7 +776,7 @@ NvmlReturn Interop(ref uint len, NvmlHwbcEntry_Interop* ptr) => /// public unsafe NvmlReturn UnitGetDevices( IntPtr unit, - out IntPtr[] devices) + out IntPtr[]? devices) { NvmlReturn Interop(ref uint len, IntPtr* ptr) => UnitGetDevices_Interop(unit, ref len, ptr); diff --git a/Src/ILGPU.Algorithms/Runtime/Cuda/CuBlas.cs b/Src/ILGPU.Algorithms/Runtime/Cuda/CuBlas.cs index 7364a017f..6b09a99db 100644 --- a/Src/ILGPU.Algorithms/Runtime/Cuda/CuBlas.cs +++ b/Src/ILGPU.Algorithms/Runtime/Cuda/CuBlas.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: CuBlas.cs @@ -13,6 +13,7 @@ using ILGPU.Util; using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace ILGPU.Runtime.Cuda @@ -148,7 +149,7 @@ private CuBlas(CudaAccelerator accelerator, CuBlasAPIVersion? apiVersion) API.GetVersion(handle, out int currentVersion)); Version = currentVersion; - Stream = accelerator.DefaultStream as CudaStream; + Stream = accelerator.DefaultStream.AsNotNullCast(); } #endregion @@ -230,6 +231,7 @@ public CuBlasMathMode MathMode public CudaStream Stream { get => stream; + [MemberNotNull(nameof(stream))] set { if (value == null) diff --git a/Src/ILGPU.Algorithms/Runtime/Cuda/CuFFT.cs b/Src/ILGPU.Algorithms/Runtime/Cuda/CuFFT.cs index d1df7cf7d..2ae50353b 100644 --- a/Src/ILGPU.Algorithms/Runtime/Cuda/CuFFT.cs +++ b/Src/ILGPU.Algorithms/Runtime/Cuda/CuFFT.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: CuFFT.cs @@ -50,7 +50,7 @@ public CuFFT(CuFFTAPIVersion? version) /// The transform type. /// The number of transforms. /// The error code. - public CuFFTResult Plan1D(out CuFFTPlan plan, int nx, CuFFTType type, int batch) + public CuFFTResult Plan1D(out CuFFTPlan? plan, int nx, CuFFTType type, int batch) { var errorCode = API.Plan1D(out var planHandle, nx, type, batch); plan = errorCode == CuFFTResult.CUFFT_SUCCESS @@ -67,7 +67,7 @@ public CuFFTResult Plan1D(out CuFFTPlan plan, int nx, CuFFTType type, int batch) /// The transform size in the y dimension. /// The transform type. /// The error code. - public CuFFTResult Plan2D(out CuFFTPlan plan, int nx, int ny, CuFFTType type) + public CuFFTResult Plan2D(out CuFFTPlan? plan, int nx, int ny, CuFFTType type) { var errorCode = API.Plan2D(out var planHandle, nx, ny, type); plan = errorCode == CuFFTResult.CUFFT_SUCCESS @@ -86,7 +86,7 @@ public CuFFTResult Plan2D(out CuFFTPlan plan, int nx, int ny, CuFFTType type) /// The transform type. /// The error code. public CuFFTResult Plan3D( - out CuFFTPlan plan, + out CuFFTPlan? plan, int nx, int ny, int nz, @@ -115,7 +115,7 @@ public CuFFTResult Plan3D( /// The number of transforms. /// The error code. public CuFFTResult PlanMany( - out CuFFTPlan plan, + out CuFFTPlan? plan, int rank, int[] n, int[] inembed, @@ -152,7 +152,7 @@ public CuFFTResult PlanMany( /// /// Creates an extensible plan. /// - public CuFFTResult CreatePlan(out CuFFTPlan plan) + public CuFFTResult CreatePlan(out CuFFTPlan? plan) { var errorCode = API.Create(out var planHandle); plan = errorCode == CuFFTResult.CUFFT_SUCCESS diff --git a/Src/ILGPU.Algorithms/Runtime/Cuda/CuRand.cs b/Src/ILGPU.Algorithms/Runtime/Cuda/CuRand.cs index ecbc015ca..2aae7a7bd 100644 --- a/Src/ILGPU.Algorithms/Runtime/Cuda/CuRand.cs +++ b/Src/ILGPU.Algorithms/Runtime/Cuda/CuRand.cs @@ -14,6 +14,7 @@ using ILGPU.Runtime.Cuda.API; using ILGPU.Util; using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using static ILGPU.Algorithms.Random.RandomExtensions; @@ -232,7 +233,7 @@ private GPUCuRand( API.GetVersion(out int version)); Version = version; - Stream = accelerator.DefaultStream as CudaStream; + Stream = accelerator.DefaultStream.AsNotNullCast(); } #endregion @@ -260,6 +261,7 @@ private GPUCuRand( public CudaStream Stream { get => currentStream; + [MemberNotNull(nameof(currentStream))] set { if (value == null) diff --git a/Src/ILGPU.Algorithms/Runtime/Cuda/NvJpegStructs.cs b/Src/ILGPU.Algorithms/Runtime/Cuda/NvJpegStructs.cs index 0ac4d8273..45f0a9356 100644 --- a/Src/ILGPU.Algorithms/Runtime/Cuda/NvJpegStructs.cs +++ b/Src/ILGPU.Algorithms/Runtime/Cuda/NvJpegStructs.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU Algorithms -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: NvJpegStructs.cs @@ -9,6 +9,7 @@ // Source License. See LICENSE.txt for details. // --------------------------------------------------------------------------------------- +using ILGPU.Util; using System; #pragma warning disable CA1051 // Do not declare visible instance fields @@ -29,7 +30,7 @@ public struct NvJpegImage { #region Properties - public MemoryBuffer1D[] Channel; + public MemoryBuffer1D?[] Channel; public ulong[] Pitch; #endregion @@ -64,7 +65,7 @@ public static NvJpegImage Create( var size = width * height; var outputImage = new NvJpegImage { - Channel = new MemoryBuffer1D[] + Channel = new MemoryBuffer1D?[] { numComponents >= 1 ? accelerator.Allocate1D(size) : null, numComponents >= 2 ? accelerator.Allocate1D(size) : null, @@ -104,7 +105,7 @@ ulong MemoryBufferToUInt64(MemoryBuffer1D buffer) => i < Math.Min(Channel.Length, NvJpegConstants.NVJPEG_MAX_COMPONENT); i++) { - imageInterop.Channel[i] = MemoryBufferToUInt64(Channel[i]); + imageInterop.Channel[i] = MemoryBufferToUInt64(Channel[i].AsNotNull()); imageInterop.Pitch[i] = Pitch[i]; } diff --git a/Src/ILGPU.Algorithms/Vectors/VectorTypes.tt b/Src/ILGPU.Algorithms/Vectors/VectorTypes.tt index 8671a5c66..136274fc8 100644 --- a/Src/ILGPU.Algorithms/Vectors/VectorTypes.tt +++ b/Src/ILGPU.Algorithms/Vectors/VectorTypes.tt @@ -492,7 +492,7 @@ namespace ILGPU.Algorithms.Vectors /// /// Converts this vector instance to a string. /// - public string ToString(string format, IFormatProvider formatProvider) => + public string ToString(string? format, IFormatProvider? formatProvider) => $"<#= string.Join($", ", vectorItemNames .Take(vectorLength) .Select(t => $"{{{t}.ToString(format, formatProvider)}}")) #>"; @@ -797,7 +797,7 @@ namespace ILGPU.Algorithms.Vectors /// static <#= typeName #> IParsable<<#= typeName #>>.Parse( string s, - IFormatProvider provider) => + IFormatProvider? provider) => throw new NotSupportedException(); /// @@ -805,7 +805,7 @@ namespace ILGPU.Algorithms.Vectors /// static <#= typeName #> ISpanParsable<<#= typeName #>>.Parse( ReadOnlySpan s, - IFormatProvider provider) => + IFormatProvider? provider) => throw new NotSupportedException(); /// @@ -814,7 +814,7 @@ namespace ILGPU.Algorithms.Vectors static <#= typeName #> INumberBase<<#= typeName #>>.Parse( ReadOnlySpan s, NumberStyles style, - IFormatProvider provider) => + IFormatProvider? provider) => throw new NotSupportedException(); /// @@ -823,7 +823,7 @@ namespace ILGPU.Algorithms.Vectors static <#= typeName #> INumberBase<<#= typeName #>>.Parse( string s, NumberStyles style, - IFormatProvider provider) => + IFormatProvider? provider) => throw new NotSupportedException(); /// @@ -833,15 +833,15 @@ namespace ILGPU.Algorithms.Vectors Span destination, out int charsWritten, ReadOnlySpan format, - IFormatProvider provider) => + IFormatProvider? provider) => throw new NotSupportedException(); /// /// Tries to parse the given string into a vectorized instance. /// static bool IParsable<<#= typeName #>>.TryParse( - string s, - IFormatProvider provider, + string? s, + IFormatProvider? provider, out <#= typeName #> result) => throw new NotSupportedException(); @@ -850,7 +850,7 @@ namespace ILGPU.Algorithms.Vectors /// static bool ISpanParsable<<#= typeName #>>.TryParse( ReadOnlySpan s, - IFormatProvider provider, + IFormatProvider? provider, out <#= typeName #> result) => throw new NotSupportedException(); @@ -860,7 +860,7 @@ namespace ILGPU.Algorithms.Vectors static bool INumberBase<<#= typeName #>>.TryParse( ReadOnlySpan s, NumberStyles style, - IFormatProvider provider, + IFormatProvider? provider, out <#= typeName #> result) => throw new NotSupportedException(); @@ -868,9 +868,9 @@ namespace ILGPU.Algorithms.Vectors /// Tries to parse the given string into a vectorized instance. /// static bool INumberBase<<#= typeName #>>.TryParse( - string s, + string? s, NumberStyles style, - IFormatProvider provider, + IFormatProvider? provider, out <#= typeName #> result) => throw new NotSupportedException(); diff --git a/Src/ILGPU.Tests/BasicLoops.cs b/Src/ILGPU.Tests/BasicLoops.cs index 3d77eea85..c47cae094 100644 --- a/Src/ILGPU.Tests/BasicLoops.cs +++ b/Src/ILGPU.Tests/BasicLoops.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021-2022 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: BasicLoops.cs @@ -11,7 +11,6 @@ using ILGPU.Runtime; using ILGPU.Util; -using System; using System.Linq; using Xunit; using Xunit.Abstractions; diff --git a/Src/ILGPU.Tests/DisassemblerTests.cs b/Src/ILGPU.Tests/DisassemblerTests.cs index d6e180a31..8937f4f0c 100644 --- a/Src/ILGPU.Tests/DisassemblerTests.cs +++ b/Src/ILGPU.Tests/DisassemblerTests.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: DisassemblerTests.cs @@ -12,6 +12,7 @@ using ILGPU.Frontend; using ILGPU.Frontend.DebugInformation; using ILGPU.Runtime; +using ILGPU.Util; using System; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -102,7 +103,8 @@ public void StelemLdtoken(Type genericType) { var methodInfo = typeof(DisassemblerTests).GetMethod( nameof(StelemLdtokenKernel), - BindingFlags.NonPublic | BindingFlags.Static); + BindingFlags.NonPublic | BindingFlags.Static) + .ThrowIfNull(); var method = methodInfo.MakeGenericMethod(genericType); var disassembler = new Disassembler(method, SequencePointEnumerator.Empty); diff --git a/Src/ILGPU.Tests/FixedBuffers.tt b/Src/ILGPU.Tests/FixedBuffers.tt index a8dc38f00..fcb7eae41 100644 --- a/Src/ILGPU.Tests/FixedBuffers.tt +++ b/Src/ILGPU.Tests/FixedBuffers.tt @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: FixedBuffers.tt/FixedBuffers.cs @@ -64,7 +64,7 @@ namespace ILGPU.Tests return true; } - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is FixedBufferStruct<#= type.Name #> fixedStruct && Equals(fixedStruct); } @@ -121,7 +121,7 @@ namespace ILGPU.Tests return true; } - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is MultiFixedBufferStruct<#= type.Name #> fixedStruct && Equals(fixedStruct); } diff --git a/Src/ILGPU.Tests/Generic/KernelMethodAttribute.cs b/Src/ILGPU.Tests/Generic/KernelMethodAttribute.cs index a9183fec0..42346de50 100644 --- a/Src/ILGPU.Tests/Generic/KernelMethodAttribute.cs +++ b/Src/ILGPU.Tests/Generic/KernelMethodAttribute.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: KernelMethodAttribute.cs @@ -9,6 +9,7 @@ // Source License. See LICENSE.txt for details. // --------------------------------------------------------------------------------------- +using ILGPU.Util; using System; using System.Diagnostics; using System.Reflection; @@ -50,7 +51,7 @@ public KernelMethodAttribute(string methodName, Type type) /// /// Returns the type in which the kernel method could be found (if any). /// - public Type Type { get; } + public Type? Type { get; } /// /// Resolves the kernel method using the current configuration. @@ -58,20 +59,20 @@ public KernelMethodAttribute(string methodName, Type type) /// The kernel type arguments. /// The resolved kernel method. public static MethodInfo GetKernelMethod( - Type[] typeArguments = null, + Type[]? typeArguments = null, int offset = 1) { // TODO: create a nicer way ;) var stackTrace = new StackTrace(); for (int i = offset; i < stackTrace.FrameCount; ++i) { - var frame = stackTrace.GetFrame(i); - var callingMethod = frame.GetMethod(); + var frame = stackTrace.GetFrame(i).ThrowIfNull(); + var callingMethod = frame.GetMethod().ThrowIfNull(); var attribute = callingMethod.GetCustomAttribute< KernelMethodAttribute>(); if (attribute == null) continue; - var type = attribute.Type ?? callingMethod.DeclaringType; + var type = attribute.Type ?? callingMethod.DeclaringType.ThrowIfNull(); return TestBase.GetKernelMethod( type, attribute.MethodName, diff --git a/Src/ILGPU.Tests/Generic/TestBase.cs b/Src/ILGPU.Tests/Generic/TestBase.cs index f8f8efbc8..cc323adf1 100644 --- a/Src/ILGPU.Tests/Generic/TestBase.cs +++ b/Src/ILGPU.Tests/Generic/TestBase.cs @@ -59,7 +59,7 @@ public static bool CleanTests internal static MethodInfo GetKernelMethod( Type type, string name, - Type[] typeArguments) + Type[]? typeArguments) { var method = type.GetMethod( name, diff --git a/Src/ILGPU.Tests/Generic/TestData.cs b/Src/ILGPU.Tests/Generic/TestData.cs index 1e2908226..369c679f0 100644 --- a/Src/ILGPU.Tests/Generic/TestData.cs +++ b/Src/ILGPU.Tests/Generic/TestData.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: TestData.cs @@ -9,6 +9,7 @@ // Source License. See LICENSE.txt for details. // --------------------------------------------------------------------------------------- +using ILGPU.Util; using System; using System.Runtime.InteropServices; using Xunit.Abstractions; @@ -42,7 +43,10 @@ public static class TestData /// The value to wrap. public class TestData : IXunitSerializable { - public TestData() { } + public TestData() + { + Value = Utilities.InitNotNullable(); + } public TestData(T value) { @@ -61,7 +65,7 @@ public void Serialize(IXunitSerializationInfo info) info.AddValue(nameof(Value), Value); } - public override string ToString() => Value.ToString(); + public override string ToString() => $"{Value}"; } #region Data Structures @@ -88,7 +92,7 @@ public void Serialize(IXunitSerializationInfo info) { } public bool Equals(EmptyStruct other) => true; - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is EmptyStruct other && Equals(other); public override int GetHashCode() => 0; @@ -96,9 +100,9 @@ public override bool Equals(object obj) => [Serializable] // warning disabled intentionally for testing this scenario - #pragma warning disable CS0659 // Type does not override Object.GetHashCode() +#pragma warning disable CS0659 // Type does not override Object.GetHashCode() public struct NoHashCodeStruct : IXunitSerializable, IEquatable - #pragma warning restore CS0659 // Type does not override Object.GetHashCode() +#pragma warning restore CS0659 // Type does not override Object.GetHashCode() { public void Deserialize(IXunitSerializationInfo info) { } @@ -106,7 +110,7 @@ public void Serialize(IXunitSerializationInfo info) { } public bool Equals(NoHashCodeStruct other) => true; - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is NoHashCodeStruct other && Equals(other); } @@ -181,7 +185,7 @@ public bool Equals(TestStruct other) => Z == other.Z && W == other.W; - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is TestStruct other && Equals(other); public override int GetHashCode() => @@ -266,7 +270,7 @@ public bool Equals(TestStructEquatable other) => Val2 == other.Val2 && Val1.Equals(other.Val1); - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is TestStructEquatable other && Equals(other); public override int GetHashCode() => @@ -355,7 +359,7 @@ public bool Equals(TestStructEquatable other) => Val0.Equals(other.Val0) && Val2.Equals(other.Val2); - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is TestStructEquatable other && Equals(other); public override int GetHashCode() => data.GetHashCode(); diff --git a/Src/ILGPU.Tests/ILGPU.Tests.csproj b/Src/ILGPU.Tests/ILGPU.Tests.csproj index 6ff11ad0c..eb23233e9 100644 --- a/Src/ILGPU.Tests/ILGPU.Tests.csproj +++ b/Src/ILGPU.Tests/ILGPU.Tests.csproj @@ -6,6 +6,14 @@ + + + enable + + + $(NoWarn);nullable + + latest true diff --git a/Src/ILGPU.Tests/MemoryBufferOperations.tt b/Src/ILGPU.Tests/MemoryBufferOperations.tt index 70479dcb9..da355499e 100644 --- a/Src/ILGPU.Tests/MemoryBufferOperations.tt +++ b/Src/ILGPU.Tests/MemoryBufferOperations.tt @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021-2022 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: MemoryBufferOperations.tt/MemoryBufferOperations.cs @@ -42,6 +42,7 @@ namespace ILGPU.Tests int length, int stride, Func builder) + where T : unmanaged { int counter = 0; int strideCounter = 0; @@ -60,6 +61,7 @@ namespace ILGPU.Tests private static T[,] InitializeArray2D( int length, Func builder) + where T : unmanaged { int counter = 0; var src = new T[length, length]; @@ -78,6 +80,7 @@ namespace ILGPU.Tests private static T[,,] InitializeArray3D( int length, Func builder) + where T : unmanaged { int counter = 0; var src = new T[length, length, length]; diff --git a/Src/ILGPU.Tests/SharedMemory.cs b/Src/ILGPU.Tests/SharedMemory.cs index e632f1992..80ca30fdf 100644 --- a/Src/ILGPU.Tests/SharedMemory.cs +++ b/Src/ILGPU.Tests/SharedMemory.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021-2022 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: SharedMemory.cs @@ -245,19 +245,21 @@ public void MultiDimensionalSharedMemory2D() var expected = Enumerable.Repeat(42, groupSize).ToArray(); Verify(buffer.View, expected); } - + internal static void MultiDimensionalSharedMemoryKernel2DDenseX( ArrayView1D output) { var sharedMemory = ILGPU.SharedMemory.Allocate2DDenseX( new Index2D(20, 100)); - if (Group.IsFirstThread) { + if (Group.IsFirstThread) + { sharedMemory[0, 0] = 0; sharedMemory[1, 0] = 0; } - if (Grid.GlobalIndex.X < 100) { + if (Grid.GlobalIndex.X < 100) + { sharedMemory[0, Grid.GlobalIndex.X] = Grid.GlobalIndex.X; - sharedMemory[1, Grid.GlobalIndex.X] = 7*Grid.GlobalIndex.X; + sharedMemory[1, Grid.GlobalIndex.X] = 7 * Grid.GlobalIndex.X; } Group.Barrier(); if (Grid.GlobalIndex.X < 100) @@ -273,9 +275,9 @@ public void MultiDimensionalSharedMemory2DDenseX() int groupSize = Accelerator.MaxNumThreadsPerGroup; using var buffer = Accelerator.Allocate1D(groupSize); Execute(new KernelConfig(1, groupSize), buffer.View); - var expected = + var expected = Enumerable.Range(0, groupSize).Select( - x => x < 100 ? 7*x : 0).ToArray(); + x => x < 100 ? 7 * x : 0).ToArray(); Verify(buffer.View, expected); } @@ -284,13 +286,15 @@ internal static void MultiDimensionalSharedMemoryKernel2DDenseY( { var sharedMemory = ILGPU.SharedMemory.Allocate2DDenseY( new Index2D(100, 20)); - if (Group.IsFirstThread) { + if (Group.IsFirstThread) + { sharedMemory[0, 0] = 0; sharedMemory[0, 1] = 0; } - if (Grid.GlobalIndex.X < 100) { + if (Grid.GlobalIndex.X < 100) + { sharedMemory[Grid.GlobalIndex.X, 0] = Grid.GlobalIndex.X; - sharedMemory[Grid.GlobalIndex.X, 1] = 7*Grid.GlobalIndex.X; + sharedMemory[Grid.GlobalIndex.X, 1] = 7 * Grid.GlobalIndex.X; } Group.Barrier(); if (Grid.GlobalIndex.X < 100) @@ -306,9 +310,9 @@ public void MultiDimensionalSharedMemory2DDenseY() int groupSize = Accelerator.MaxNumThreadsPerGroup; using var buffer = Accelerator.Allocate1D(groupSize); Execute(new KernelConfig(1, groupSize), buffer.View); - var expected = + var expected = Enumerable.Range(0, groupSize).Select( - x => x < 100 ? 7*x : 0).ToArray(); + x => x < 100 ? 7 * x : 0).ToArray(); Verify(buffer.View, expected); } @@ -335,7 +339,7 @@ public void MultiDimensionalSharedMemory3D() var expected = Enumerable.Repeat(42, groupSize).ToArray(); Verify(buffer.View, expected); } - + internal static void MultiDimensionalSharedMemoryKernel3DDenseXY( ArrayView1D output) { diff --git a/Src/ILGPU.Tests/StaticAbstractInterfaceMembers.cs b/Src/ILGPU.Tests/StaticAbstractInterfaceMembers.cs index 2310a42fd..78f525511 100644 --- a/Src/ILGPU.Tests/StaticAbstractInterfaceMembers.cs +++ b/Src/ILGPU.Tests/StaticAbstractInterfaceMembers.cs @@ -134,7 +134,7 @@ public interface IStaticAbstract static abstract int Inc(int x); } - public class Incrementer: IStaticAbstract + public class Incrementer : IStaticAbstract { public static int Inc(int x) => x + 1; } diff --git a/Src/ILGPU/ArrayView.cs b/Src/ILGPU/ArrayView.cs index 1f9c40c80..bca8c869f 100644 --- a/Src/ILGPU/ArrayView.cs +++ b/Src/ILGPU/ArrayView.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: ArrayView.cs @@ -200,7 +200,6 @@ public interface IArrayView : [NotInsideKernel] public ArrayView(MemoryBuffer source, long index, long length) { - Trace.Assert(source != null, "Invalid source buffer"); Trace.Assert(index >= 0L, "Index out of range"); Trace.Assert(length >= 0L, "Length out of range"); diff --git a/Src/ILGPU/Backends/Backend.cs b/Src/ILGPU/Backends/Backend.cs index cc0c8eb01..22b0b917b 100644 --- a/Src/ILGPU/Backends/Backend.cs +++ b/Src/ILGPU/Backends/Backend.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2022 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: Backend.cs @@ -328,7 +328,7 @@ private CompiledKernel.KernelInfo CreateKernelInfo() /// /// Returns the associated kernel information object (if any). /// - public CompiledKernel.KernelInfo KernelInfo { get; } + public CompiledKernel.KernelInfo? KernelInfo { get; } #endregion @@ -603,8 +603,8 @@ public Method PreCompileKernelMethod( } if (codeGenerationPhase.IsFaulted) - throw codeGenerationPhase.LastException; - generatedKernelMethod = generationResult.Result; + throw codeGenerationPhase.LastException.AsNotNull(); + generatedKernelMethod = generationResult.Result.AsNotNull(); codeGenerationPhase.Optimize(); backendHook.FinishedCodeGeneration(mainContext, generatedKernelMethod); @@ -801,7 +801,11 @@ protected Backend( BackendType backendType, ArgumentMapper argumentMapper) : base(context, capabilities, backendType, argumentMapper) - { } + { + // NB: Initialized later by derived classes. + IntrinsicProvider = + Utilities.InitNotNullable>(); + } #endregion diff --git a/Src/ILGPU/Backends/CodeGeneratorBackend.cs b/Src/ILGPU/Backends/CodeGeneratorBackend.cs index e1e745254..3eb250e13 100644 --- a/Src/ILGPU/Backends/CodeGeneratorBackend.cs +++ b/Src/ILGPU/Backends/CodeGeneratorBackend.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CodeGeneratorBackend.cs @@ -174,7 +174,7 @@ protected abstract TCodeGenerator CreateKernelCodeGenerator( /// The resulting compiled kernel. protected abstract CompiledKernel CreateKernel( EntryPoint entryPoint, - CompiledKernel.KernelInfo kernelInfo, + CompiledKernel.KernelInfo? kernelInfo, TKernelBuilder builder, T data); diff --git a/Src/ILGPU/Backends/CompiledKernel.cs b/Src/ILGPU/Backends/CompiledKernel.cs index 2471005ae..6dcfa4eb4 100644 --- a/Src/ILGPU/Backends/CompiledKernel.cs +++ b/Src/ILGPU/Backends/CompiledKernel.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: CompiledKernel.cs @@ -183,7 +183,7 @@ public virtual void Dump(TextWriter textWriter) protected CompiledKernel( Context context, EntryPoint entryPoint, - KernelInfo info) + KernelInfo? info) { Context = context; EntryPoint = entryPoint; @@ -236,7 +236,7 @@ protected CompiledKernel( /// This instance will be available when the property /// is enabled. /// - public KernelInfo Info { get; } + public KernelInfo? Info { get; } #endregion diff --git a/Src/ILGPU/Backends/EntryPoints/ArgumentMapper.cs b/Src/ILGPU/Backends/EntryPoints/ArgumentMapper.cs index 394dd550c..ab06a25bb 100644 --- a/Src/ILGPU/Backends/EntryPoints/ArgumentMapper.cs +++ b/Src/ILGPU/Backends/EntryPoints/ArgumentMapper.cs @@ -636,7 +636,7 @@ protected Type RegisterTypeMapping(Type type, Type mappedType) protected Type MapType(Type type) { Debug.Assert(type != null, "Invalid source type"); - if (typeMapping.TryGetValue(type, out Type mappedType)) + if (typeMapping.TryGetValue(type, out Type? mappedType)) return mappedType; if (type.IsByRef) @@ -673,7 +673,7 @@ protected Type MapType(Type type) return RegisterTypeMapping(type, typeof(void*)); else if (type.IsEnum) return RegisterTypeMapping(type, type.GetEnumUnderlyingType()); - else if (type.IsArrayViewType(out Type elementType)) + else if (type.IsArrayViewType(out Type? elementType)) return RegisterTypeMapping(type, MapViewType(type, elementType)); else return RegisterTypeMapping(type, MapStructType(type)); @@ -760,7 +760,7 @@ protected void MapInstance( // Copy object from source to target target.EmitStoreTarget(emitter, source); } - else if (sourceType.IsArrayViewType(out Type elementType)) + else if (sourceType.IsArrayViewType(out Type? elementType)) { MapViewInstance(emitter, elementType, source, target); } @@ -896,7 +896,7 @@ protected T MapArgumentsStruct( { var fieldTarget = new StructureTarget( localTarget, - argumentType.GetField(GetFieldName(i))); + argumentType.GetField(GetFieldName(i)).AsNotNull()); // Perform actual instance mapping on local MapParameter(emitter, parameters, i, fieldTarget); @@ -907,7 +907,7 @@ protected T MapArgumentsStruct( var lastFieldName = GetFieldName(parameters.Count - 1); int lastOffset = Marshal.OffsetOf(argumentType, lastFieldName).ToInt32(); int lastFieldSize = Interop.SizeOf( - argumentType.GetField(lastFieldName).FieldType); + argumentType.GetField(lastFieldName).AsNotNull().FieldType); // Map the whole argument structure return mappingHandler.MapArgumentStruct( diff --git a/Src/ILGPU/Backends/EntryPoints/EntryPoint.cs b/Src/ILGPU/Backends/EntryPoints/EntryPoint.cs index af34e9286..f08463096 100644 --- a/Src/ILGPU/Backends/EntryPoints/EntryPoint.cs +++ b/Src/ILGPU/Backends/EntryPoints/EntryPoint.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: EntryPoint.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.Runtime; +using ILGPU.Util; using System; using System.Reflection; @@ -163,7 +164,7 @@ internal RuntimeSystem.ScopedLock CreateLauncherMethod( /// The acquired scoped lock. internal RuntimeSystem.ScopedLock CreateLauncherMethod( RuntimeSystem runtimeSystem, - Type instanceType, + Type? instanceType, out RuntimeSystem.MethodEmitter methodEmitter) => Description.CreateLauncherMethod( runtimeSystem, @@ -189,7 +190,8 @@ public readonly struct SharedMemorySpecification { typeof(int), typeof(bool) - }); + }) + .ThrowIfNull(); #endregion diff --git a/Src/ILGPU/Backends/EntryPoints/EntryPointDescription.cs b/Src/ILGPU/Backends/EntryPoints/EntryPointDescription.cs index c5cb0b7fe..2b0028385 100644 --- a/Src/ILGPU/Backends/EntryPoints/EntryPointDescription.cs +++ b/Src/ILGPU/Backends/EntryPoints/EntryPointDescription.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: EntryPointDescription.cs @@ -76,7 +76,7 @@ public static EntryPointDescription FromImplicitlyGroupedKernel( /// The index type. internal EntryPointDescription( MethodInfo methodSource, - ParameterInfo[] parameters, + ParameterInfo[]? parameters, IndexType indexType) { if (indexType == IndexType.None) @@ -178,7 +178,7 @@ public void Validate() /// The acquired scoped lock. internal RuntimeSystem.ScopedLock CreateLauncherMethod( RuntimeSystem runtimeSystem, - Type instanceType, + Type? instanceType, out RuntimeSystem.MethodEmitter methodEmitter) { var parameterTypes = new Type[ @@ -229,7 +229,7 @@ public bool Equals(EntryPointDescription other) => /// /// The other object. /// True, if the given object is equal to the current one. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is EntryPointDescription other && Equals(other); /// diff --git a/Src/ILGPU/Backends/EntryPoints/ParameterCollection.cs b/Src/ILGPU/Backends/EntryPoints/ParameterCollection.cs index 96b86059f..e68464cc6 100644 --- a/Src/ILGPU/Backends/EntryPoints/ParameterCollection.cs +++ b/Src/ILGPU/Backends/EntryPoints/ParameterCollection.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: ParameterCollection.cs @@ -50,7 +50,7 @@ public Type Current get { var type = enumerator.Current; - return type.IsByRef ? type.GetElementType() : type; + return type.IsByRef ? type.GetElementType().AsNotNull() : type; } } @@ -189,7 +189,7 @@ private static Type GetParameterType( int parameterIndex) { var type = parameterTypes[parameterIndex]; - return type.IsByRef ? type.GetElementType() : type; + return type.IsByRef ? type.GetElementType().AsNotNull() : type; } /// diff --git a/Src/ILGPU/Backends/IL/ILBackend.cs b/Src/ILGPU/Backends/IL/ILBackend.cs index 831c638a0..6390a185a 100644 --- a/Src/ILGPU/Backends/IL/ILBackend.cs +++ b/Src/ILGPU/Backends/IL/ILBackend.cs @@ -16,6 +16,7 @@ using ILGPU.Resources; using ILGPU.Runtime; using ILGPU.Runtime.CPU; +using ILGPU.Util; using System; using System.Collections.Immutable; using System.Reflection; @@ -53,7 +54,8 @@ public delegate void Handler( private static readonly MethodInfo Reconstruct2DIndexMethod = typeof(ILBackend).GetMethod( nameof(Reconstruct2DIndex), - BindingFlags.NonPublic | BindingFlags.Static); + BindingFlags.NonPublic | BindingFlags.Static) + .ThrowIfNull(); /// /// A reference to the static @@ -62,7 +64,8 @@ public delegate void Handler( private static readonly MethodInfo Reconstruct3DIndexMethod = typeof(ILBackend).GetMethod( nameof(Reconstruct3DIndex), - BindingFlags.NonPublic | BindingFlags.Static); + BindingFlags.NonPublic | BindingFlags.Static) + .ThrowIfNull(); /// /// Helper method to reconstruct 2D indices. @@ -132,7 +135,7 @@ internal ILBackend( /// Returns the associated . /// public new ILArgumentMapper ArgumentMapper => - base.ArgumentMapper as ILArgumentMapper; + base.ArgumentMapper.AsNotNullCast(); #endregion @@ -328,17 +331,20 @@ private Type GenerateAcceleratorTask( for (int i = 0, e = argFieldBuilders.Length; i < e; ++i) { argFieldBuilders[i] = taskBuilder.GetField( - string.Format(ArgumentFormat, i)); + string.Format(ArgumentFormat, i)).AsNotNull(); } } taskConstructor = taskType.GetConstructor( - CPUAcceleratorTask.ConstructorParameterTypes); + CPUAcceleratorTask.ConstructorParameterTypes).AsNotNull(); // Map the final fields var resultMapping = ImmutableArray.CreateBuilder( parameters.Count); for (int i = 0, e = parameters.Count; i < e; ++i) - resultMapping.Add(taskType.GetField(argFieldBuilders[i].Name)); + { + resultMapping.Add( + taskType.GetField(argFieldBuilders[i].Name).AsNotNull()); + } taskArgumentMapping = resultMapping.MoveToImmutable(); return taskType; diff --git a/Src/ILGPU/Backends/IL/ILEmitter.cs b/Src/ILGPU/Backends/IL/ILEmitter.cs index 050e3ec5f..2cc6e05f1 100644 --- a/Src/ILGPU/Backends/IL/ILEmitter.cs +++ b/Src/ILGPU/Backends/IL/ILEmitter.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: ILEmitter.cs @@ -525,7 +525,7 @@ public void EmitCall(MethodInfo target) { EmitPrefix(); Writer.Write(target.IsVirtual ? "callvirt " : "call "); - Writer.Write(target.DeclaringType.FullName); + Writer.Write(target.DeclaringType.AsNotNull().FullName); Writer.Write('.'); Writer.WriteLine(target.Name); } @@ -535,7 +535,7 @@ public void EmitNewObject(ConstructorInfo info) { EmitPrefix(); Writer.Write("newobj "); - Writer.Write(info.DeclaringType.FullName); + Writer.Write(info.DeclaringType.AsNotNull().FullName); Writer.Write('.'); Writer.WriteLine(info.Name); } diff --git a/Src/ILGPU/Backends/IL/ILEmitterExtensions.cs b/Src/ILGPU/Backends/IL/ILEmitterExtensions.cs index d48d23542..b2c44573b 100644 --- a/Src/ILGPU/Backends/IL/ILEmitterExtensions.cs +++ b/Src/ILGPU/Backends/IL/ILEmitterExtensions.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: ILEmitterExtensions.cs @@ -9,6 +9,7 @@ // Source License. See LICENSE.txt for details. // --------------------------------------------------------------------------------------- +using ILGPU.Util; using System; using System.Reflection; using System.Reflection.Emit; @@ -20,12 +21,16 @@ namespace ILGPU.Backends.IL /// public static class ILEmitterExtensions { - private static readonly MethodInfo GetHashCodeInfo = typeof(object).GetMethod( - nameof(object.GetHashCode), - BindingFlags.Public | BindingFlags.Instance); - private static readonly MethodInfo EqualsInfo = typeof(object).GetMethod( - nameof(object.Equals), - BindingFlags.Public | BindingFlags.Instance); + private static readonly MethodInfo GetHashCodeInfo = + typeof(object).GetMethod( + nameof(object.GetHashCode), + BindingFlags.Public | BindingFlags.Instance) + .ThrowIfNull(); + private static readonly MethodInfo EqualsInfo = + typeof(object).GetMethod( + nameof(object.Equals), + BindingFlags.Public | BindingFlags.Instance) + .ThrowIfNull(); /// /// Generates hash code and equals functions for the given fields. @@ -70,7 +75,8 @@ public static MethodInfo GenerateHashCode( var fieldHashCode = field.FieldType.GetMethod( GetHashCodeInfo.Name, - BindingFlags.Public | BindingFlags.Instance); + BindingFlags.Public | BindingFlags.Instance) + .AsNotNull(); if (!field.FieldType.IsValueType) { emitter.Emit(OpCodes.Ldfld, field); @@ -131,7 +137,8 @@ public static MethodInfo GenerateEquals( emitter.EmitCall(field.FieldType.GetMethod( EqualsInfo.Name, - new Type[] { field.FieldType })); + new Type[] { field.FieldType }) + .AsNotNull()); // IMPORTANT: Each field can branch to the false label. However, if we // have a large number of fields, depending on the number of IL bytes we diff --git a/Src/ILGPU/Backends/OpenCL/CLArgumentMapper.cs b/Src/ILGPU/Backends/OpenCL/CLArgumentMapper.cs index 4e420fe10..2dd330bc9 100644 --- a/Src/ILGPU/Backends/OpenCL/CLArgumentMapper.cs +++ b/Src/ILGPU/Backends/OpenCL/CLArgumentMapper.cs @@ -15,6 +15,7 @@ using ILGPU.IR.Types; using ILGPU.Runtime; using ILGPU.Runtime.OpenCL; +using ILGPU.Util; using System; using System.Reflection; using System.Reflection.Emit; @@ -35,7 +36,8 @@ public sealed class CLArgumentMapper : ViewArgumentMapper private static readonly MethodInfo SetKernelArgumentMethod = typeof(CLAPI).GetMethod( nameof(CLAPI.SetKernelArgumentUnsafeWithKernel), - BindingFlags.Public | BindingFlags.Instance); + BindingFlags.Public | BindingFlags.Instance) + .ThrowIfNull(); #endregion diff --git a/Src/ILGPU/Backends/OpenCL/CLBackend.cs b/Src/ILGPU/Backends/OpenCL/CLBackend.cs index 8c12a523d..95f4097f5 100644 --- a/Src/ILGPU/Backends/OpenCL/CLBackend.cs +++ b/Src/ILGPU/Backends/OpenCL/CLBackend.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2022 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CLBackend.cs @@ -16,6 +16,7 @@ using ILGPU.IR.Transformations; using ILGPU.Runtime; using ILGPU.Runtime.OpenCL; +using ILGPU.Util; using System.Text; namespace ILGPU.Backends.OpenCL @@ -68,7 +69,7 @@ public CLBackend( CLStdVersion = clStdVersion; InitIntrinsicProvider(); - InitializeKernelTransformers( builder => + InitializeKernelTransformers(builder => { var transformerBuilder = Transformer.CreateBuilder( TransformerConfiguration.Empty); @@ -110,13 +111,13 @@ public CLBackend( /// Returns the associated . /// public new CLArgumentMapper ArgumentMapper => - base.ArgumentMapper as CLArgumentMapper; + base.ArgumentMapper.AsNotNullCast(); /// /// Returns the capabilities of this accelerator. /// public new CLCapabilityContext Capabilities => - base.Capabilities as CLCapabilityContext; + base.Capabilities.AsNotNullCast(); #endregion @@ -162,7 +163,7 @@ protected override StringBuilder CreateKernelBuilder( data = new CLCodeGenerator.GeneratorArgs( this, typeGenerator, - entryPoint as SeparateViewEntryPoint, + entryPoint.AsNotNullCast(), backendContext.SharedAllocations, backendContext.DynamicSharedAllocations); return builder; @@ -192,7 +193,7 @@ protected override CLCodeGenerator CreateKernelCodeGenerator( /// protected override CompiledKernel CreateKernel( EntryPoint entryPoint, - CompiledKernel.KernelInfo kernelInfo, + CompiledKernel.KernelInfo? kernelInfo, StringBuilder builder, CLCodeGenerator.GeneratorArgs data) { @@ -208,7 +209,7 @@ protected override CompiledKernel CreateKernel( var clSource = builder.ToString(); return new CLCompiledKernel( Context, - entryPoint as SeparateViewEntryPoint, + entryPoint.AsNotNullCast(), kernelInfo, clSource, CLStdVersion); diff --git a/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Emitter.cs b/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Emitter.cs index 59ddf58db..5fa76fb1a 100644 --- a/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Emitter.cs +++ b/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Emitter.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CLCodeGenerator.Emitter.cs @@ -465,7 +465,7 @@ public void AppendOperation(RawString operation) => /// The string format arguments. public void AppendOperation( RawString operation, - params object[] arguments) + params object?[] arguments) { var formatExpression = operation.Value; if (!FormatString.TryParse(formatExpression, out var expressions)) @@ -495,49 +495,49 @@ public void AppendOperation( { if (!expression.HasArgument) { - AppendOperation(expression.String); + AppendOperation(expression.String.AsNotNull()); } else { var argument = arguments[expression.Argument]; - var argumentType = argument.GetType(); + var argumentType = argument?.GetType(); switch (Type.GetTypeCode(argumentType)) { case TypeCode.Boolean: - AppendConstant((bool)argument ? 1 : 0); + AppendConstant((bool)argument.AsNotNull() ? 1 : 0); break; case TypeCode.SByte: - AppendConstant((sbyte)argument); + AppendConstant((sbyte)argument.AsNotNull()); break; case TypeCode.Byte: - AppendConstant((byte)argument); + AppendConstant((byte)argument.AsNotNull()); break; case TypeCode.Int16: - AppendConstant((short)argument); + AppendConstant((short)argument.AsNotNull()); break; case TypeCode.UInt16: - AppendConstant((ushort)argument); + AppendConstant((ushort)argument.AsNotNull()); break; case TypeCode.Int32: - AppendConstant((int)argument); + AppendConstant((int)argument.AsNotNull()); break; case TypeCode.UInt32: - AppendConstant((uint)argument); + AppendConstant((uint)argument.AsNotNull()); break; case TypeCode.Int64: - AppendConstant((long)argument); + AppendConstant((long)argument.AsNotNull()); break; case TypeCode.UInt64: - AppendConstant((ulong)argument); + AppendConstant((ulong)argument.AsNotNull()); break; case TypeCode.Single: - AppendConstant((float)argument); + AppendConstant((float)argument.AsNotNull()); break; case TypeCode.Double: - AppendConstant((double)argument); + AppendConstant((double)argument.AsNotNull()); break; case TypeCode.String: - AppendOperation((string)argument); + AppendOperation((string)argument.AsNotNull()); break; default: if (argument is Variable variable) @@ -552,13 +552,13 @@ public void AppendOperation( } else if (argumentType == typeof(Half)) { - AppendConstant((Half)argument); + AppendConstant((Half)argument.AsNotNull()); break; } throw new NotSupportedException(string.Format( ErrorMessages.NotSupportedWriteFormatArgumentType, formatExpression, - argument.GetType().ToString())); + argumentType?.ToString())); } } } diff --git a/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Values.cs b/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Values.cs index fbc810a47..e602844d7 100644 --- a/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Values.cs +++ b/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Values.cs @@ -14,7 +14,6 @@ using ILGPU.IR.Values; using ILGPU.Runtime.OpenCL; using ILGPU.Util; -using System; using System.Runtime.CompilerServices; namespace ILGPU.Backends.OpenCL @@ -138,7 +137,7 @@ public void GenerateCode(TernaryArithmeticValue value) if (!CLInstructions.TryGetArithmeticOperation( value.Kind, value.BasicValueType.IsFloat(), - out string operation)) + out string? operation)) { throw new InvalidCodeGenerationException(); } @@ -593,7 +592,7 @@ public void GenerateCode(SetField value) private void MakeIntrinsicValue( Value value, string operation, - string args = null) + string? args = null) { var target = Allocate(value); using var statement = BeginStatement(target); @@ -663,7 +662,7 @@ public void GenerateCode(DynamicMemoryLengthValue value) // Resolve the name of the global variable containing the length of the // shared dynamic memory buffer. - var dynamicView = value.GetFirstUseNode().ResolveAs(); + var dynamicView = value.GetFirstUseNode().ResolveAs().AsNotNull(); var lengthVariableName = GetSharedMemoryAllocationLengthName(dynamicView); // Load the dynamic memory size (in bytes) from the dynamic length variable @@ -709,7 +708,7 @@ public void GenerateCode(PredicateBarrier barrier) if (!CLInstructions.TryGetPredicateBarrier( barrier.Kind, - out string operation)) + out string? operation)) { throw new InvalidCodeGenerationException(); } @@ -757,7 +756,7 @@ public void GenerateCode(WarpShuffle shuffle) if (!CLInstructions.TryGetShuffleOperation( Backend.Vendor, shuffle.Kind, - out string operation)) + out string? operation)) { throw new InvalidCodeGenerationException(); } diff --git a/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Views.cs b/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Views.cs index 6e2071726..e5a73d142 100644 --- a/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Views.cs +++ b/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.Views.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CLCodeGenerator.Views.cs @@ -11,6 +11,7 @@ using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; namespace ILGPU.Backends.OpenCL { @@ -21,7 +22,7 @@ public void GenerateCode(LoadElementAddress value) { var elementIndex = LoadAs(value.Offset); var source = Load(value.Source); - var target = AllocatePointerType(value.Type as PointerType); + var target = AllocatePointerType(value.Type.AsNotNullCast()); using (var statement = BeginStatement(target)) { @@ -36,20 +37,20 @@ public void GenerateCode(LoadElementAddress value) /// public void GenerateCode(AddressSpaceCast value) { - var targetType = value.TargetType as AddressSpaceType; + var targetType = value.TargetType.AsNotNullCast(); var source = Load(value.Value); var target = Allocate(value); bool isOperation = CLInstructions.TryGetAddressSpaceCast( value.TargetAddressSpace, - out string operation); + out string? operation); void GeneratePointerCast(StatementEmitter statement) { if (isOperation) { // There is a specific cast operation - statement.AppendCommand(operation); + statement.AppendCommand(operation.AsNotNull()); statement.BeginArguments(); } else diff --git a/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.cs b/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.cs index f6fd26159..6c8273db8 100644 --- a/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.cs +++ b/Src/ILGPU/Backends/OpenCL/CLCodeGenerator.cs @@ -16,7 +16,9 @@ using ILGPU.IR.Analyses.TraversalOrders; using ILGPU.IR.Intrinsics; using ILGPU.IR.Values; +using ILGPU.Util; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Text; namespace ILGPU.Backends.OpenCL @@ -151,7 +153,7 @@ protected interface IParametersSetupLogic /// /// The intrinsic parameter. /// The allocated variable (if any). - Variable HandleIntrinsicParameter(int parameterOffset, Parameter parameter); + Variable? HandleIntrinsicParameter(int parameterOffset, Parameter parameter); } /// @@ -225,7 +227,9 @@ public void Allocate(BasicBlock block, PhiValue phiValue) /// The block. /// The variables to declare (if any). /// True, if there are some phi variables to declare. - public bool TryGetPhis(BasicBlock block, out List phisToDeclare) => + public bool TryGetPhis( + BasicBlock block, + [NotNullWhen(true)] out List? phisToDeclare) => phiMapping.TryGetValue(block, out phisToDeclare); } @@ -393,7 +397,7 @@ protected void SetupParameters( foreach (var param in Method.Parameters) { - Variable variable; + Variable? variable; if (offset < paramOffset) { variable = logic.HandleIntrinsicParameter(offset, param); @@ -578,7 +582,7 @@ protected void GenerateCodeInternal() } // Build terminator - this.GenerateCodeFor(block.Terminator); + this.GenerateCodeFor(block.Terminator.AsNotNull()); Builder.AppendLine(); } } diff --git a/Src/ILGPU/Backends/OpenCL/CLCompiledKernel.cs b/Src/ILGPU/Backends/OpenCL/CLCompiledKernel.cs index 04cec3c19..900377a80 100644 --- a/Src/ILGPU/Backends/OpenCL/CLCompiledKernel.cs +++ b/Src/ILGPU/Backends/OpenCL/CLCompiledKernel.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CLCompiledKernel.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.Backends.EntryPoints; +using ILGPU.Util; namespace ILGPU.Backends.OpenCL { @@ -31,7 +32,7 @@ public sealed class CLCompiledKernel : CompiledKernel public CLCompiledKernel( Context context, SeparateViewEntryPoint entryPoint, - KernelInfo info, + KernelInfo? info, string source, CLCVersion version) : base(context, entryPoint, info) @@ -58,7 +59,7 @@ public CLCompiledKernel( /// Returns the internally used entry point. /// internal new SeparateViewEntryPoint EntryPoint => - base.EntryPoint as SeparateViewEntryPoint; + base.EntryPoint.AsNotNullCast(); #endregion } diff --git a/Src/ILGPU/Backends/OpenCL/CLFunctionGenerator.cs b/Src/ILGPU/Backends/OpenCL/CLFunctionGenerator.cs index c41d30d36..9b46a7d11 100644 --- a/Src/ILGPU/Backends/OpenCL/CLFunctionGenerator.cs +++ b/Src/ILGPU/Backends/OpenCL/CLFunctionGenerator.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CLFunctionGenerator.cs @@ -62,7 +62,7 @@ public string GetParameterType(Parameter parameter) => /// /// This setup logic does not support intrinsic parameters. /// - public Variable HandleIntrinsicParameter( + public Variable? HandleIntrinsicParameter( int parameterOffset, Parameter parameter) => null; diff --git a/Src/ILGPU/Backends/OpenCL/CLInstructions.Data.cs b/Src/ILGPU/Backends/OpenCL/CLInstructions.Data.cs index 031a8dc1b..2c68a32da 100644 --- a/Src/ILGPU/Backends/OpenCL/CLInstructions.Data.cs +++ b/Src/ILGPU/Backends/OpenCL/CLInstructions.Data.cs @@ -181,7 +181,7 @@ partial class CLInstructions "private", }; - private static readonly string[] AddressSpaceCastOperations = + private static readonly string?[] AddressSpaceCastOperations = { null, "to_global", @@ -195,7 +195,7 @@ partial class CLInstructions "work_group_barrier", }; - private static readonly string[] PredicateBarrierOperations = + private static readonly string?[] PredicateBarrierOperations = { null, "work_group_all", diff --git a/Src/ILGPU/Backends/OpenCL/CLInstructions.cs b/Src/ILGPU/Backends/OpenCL/CLInstructions.cs index eeae85c1e..33c56ab08 100644 --- a/Src/ILGPU/Backends/OpenCL/CLInstructions.cs +++ b/Src/ILGPU/Backends/OpenCL/CLInstructions.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CLInstructions.cs @@ -12,6 +12,7 @@ using ILGPU.IR; using ILGPU.IR.Values; using ILGPU.Runtime.OpenCL; +using System.Diagnostics.CodeAnalysis; namespace ILGPU.Backends.OpenCL { @@ -44,7 +45,7 @@ public static string GetAddressSpacePrefix(MemoryAddressSpace addressSpace) => /// True, if an operation could be resolved. public static bool TryGetAddressSpaceCast( MemoryAddressSpace addressSpace, - out string operation) + [NotNullWhen(true)] out string? operation) { operation = AddressSpaceCastOperations[(int)addressSpace]; return operation != null; @@ -109,7 +110,7 @@ public static string GetArithmeticOperation( public static bool TryGetArithmeticOperation( TernaryArithmeticKind kind, bool isFloat, - out string operation) => + [NotNullWhen(true)] out string? operation) => TernaryArithmeticOperations.TryGetValue((kind, isFloat), out operation); /// @@ -136,7 +137,7 @@ public static string GetBarrier(BarrierKind kind) => /// True, if the operation could be resolved. public static bool TryGetPredicateBarrier( PredicateBarrierKind kind, - out string operation) + [NotNullWhen(true)] out string? operation) { operation = PredicateBarrierOperations[(int)kind]; return operation != null; @@ -174,7 +175,7 @@ public static string GetMemoryFenceFlags(bool isGlobal) => public static bool TryGetShuffleOperation( CLDeviceVendor vendor, ShuffleKind kind, - out string operation) => + [NotNullWhen(true)] out string? operation) => ShuffleOperations.TryGetValue((vendor, kind), out operation); /// diff --git a/Src/ILGPU/Backends/OpenCL/CLKernelFunctionGenerator.cs b/Src/ILGPU/Backends/OpenCL/CLKernelFunctionGenerator.cs index 878529a06..7257df58d 100644 --- a/Src/ILGPU/Backends/OpenCL/CLKernelFunctionGenerator.cs +++ b/Src/ILGPU/Backends/OpenCL/CLKernelFunctionGenerator.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2022 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CLKernelFunctionGenerator.cs @@ -67,12 +67,12 @@ public KernelParameterSetupLogic(CLKernelFunctionGenerator generator) /// /// Returns the main index variable. /// - public Variable IndexVariable { get; private set; } + public Variable? IndexVariable { get; private set; } /// /// Returns the length variable of implicitly grouped kernels. /// - public Variable LengthVariable { get; private set; } + public Variable? LengthVariable { get; private set; } /// /// Returns the parent type generator. @@ -88,7 +88,7 @@ public string GetParameterType(Parameter parameter) => /// /// Updates index and length variables. /// - public Variable HandleIntrinsicParameter( + public Variable? HandleIntrinsicParameter( int parameterOffset, Parameter parameter) { @@ -476,11 +476,12 @@ private void EmitImplicitKernelIndex( /// /// The length variable of implicitly grouped kernels. /// - private void SetupKernelIndex(Variable indexVariable, Variable lengthVariable) + private void SetupKernelIndex(Variable? indexVariable, Variable? lengthVariable) { if (EntryPoint.IsExplicitlyGrouped) return; Debug.Assert(indexVariable != null, "Invalid index variable"); + Debug.Assert(lengthVariable != null, "Invalid length variable"); if (EntryPoint.IndexType == IndexType.Index1D) { diff --git a/Src/ILGPU/Backends/OpenCL/CLKernelTypeGenerator.cs b/Src/ILGPU/Backends/OpenCL/CLKernelTypeGenerator.cs index d87c696ca..1d3cc0885 100644 --- a/Src/ILGPU/Backends/OpenCL/CLKernelTypeGenerator.cs +++ b/Src/ILGPU/Backends/OpenCL/CLKernelTypeGenerator.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: CLKernelTypeGenerator.cs @@ -13,6 +13,7 @@ using ILGPU.IR; using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; using System.Collections.Generic; using System.Diagnostics; using System.Text; @@ -150,7 +151,7 @@ public void Register(Parameter parameter) // Convert the kernel type using a specific type converter structureType = typeConverter.ConvertType( TypeGenerator.TypeContext, - structureType) as StructureType; + structureType).AsNotNullCast(); // Register internally parameterTypes[parameter.Index] = (structureType, clName); diff --git a/Src/ILGPU/Backends/OpenCL/CLTypeGenerator.cs b/Src/ILGPU/Backends/OpenCL/CLTypeGenerator.cs index ea9731999..b17e52f4c 100644 --- a/Src/ILGPU/Backends/OpenCL/CLTypeGenerator.cs +++ b/Src/ILGPU/Backends/OpenCL/CLTypeGenerator.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CLTypeGenerator.cs @@ -65,7 +65,7 @@ public sealed class CLTypeGenerator : DisposeBase, ICLTypeGenerator /// private static readonly ImmutableArray BasicTypeMapping = ImmutableArray.Create( - null, + string.Empty, "bool", "char", "short", @@ -97,7 +97,7 @@ public sealed class CLTypeGenerator : DisposeBase, ICLTypeGenerator /// /// Maps arithmetic-basic value types to atomic OpenCL language types. /// - private static readonly ImmutableArray AtomicTypeMapping = + private static readonly ImmutableArray AtomicTypeMapping = ImmutableArray.Create( string.Empty, null, @@ -142,7 +142,7 @@ public string GetBasicValueType(ArithmeticBasicValueType basicValueType) => /// /// The basic-value type to resolve. /// The resolved atomic OpenCL type name. - public string GetAtomicType(ArithmeticBasicValueType basicValueType) => + public string? GetAtomicType(ArithmeticBasicValueType basicValueType) => basicValueType == ArithmeticBasicValueType.Float16 && !Capabilities.Float16 ? throw CLCapabilityContext.GetNotSupportedFloat16Exception() : basicValueType == ArithmeticBasicValueType.Float64 && !Capabilities.Float64 @@ -240,7 +240,7 @@ public string this[TypeNode typeNode] // Synchronize all accesses below using a read/write scope using var readWriteScope = readerWriterLock.EnterUpgradeableReadScope(); - if (mapping.TryGetValue(typeNode, out string typeName)) + if (mapping.TryGetValue(typeNode, out string? typeName)) return typeName; // Synchronize all accesses below using a write scope @@ -269,7 +269,7 @@ public string this[TypeNode typeNode] private string GetOrCreateType(TypeNode typeNode) { Debug.Assert(!(typeNode is ViewType), "Invalid view type"); - if (mapping.TryGetValue(typeNode, out string clName)) + if (mapping.TryGetValue(typeNode, out string? clName)) return clName; if (typeNode is PointerType pointerType) diff --git a/Src/ILGPU/Backends/OpenCL/Transformations/CLAcceleratorSpecializer.cs b/Src/ILGPU/Backends/OpenCL/Transformations/CLAcceleratorSpecializer.cs index fd45a41e7..5cb71f142 100644 --- a/Src/ILGPU/Backends/OpenCL/Transformations/CLAcceleratorSpecializer.cs +++ b/Src/ILGPU/Backends/OpenCL/Transformations/CLAcceleratorSpecializer.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: CLAcceleratorSpecializer.cs @@ -11,11 +11,11 @@ using ILGPU.Frontend; using ILGPU.IR; -using ILGPU.IR.Rewriting; using ILGPU.IR.Transformations; using ILGPU.IR.Types; using ILGPU.IR.Values; using ILGPU.Runtime; +using ILGPU.Util; using System.Reflection; namespace ILGPU.Backends.OpenCL.Transformations @@ -44,7 +44,8 @@ private static unsafe void PrintF(string str) private static readonly MethodInfo PrintFMethod = typeof(CLAcceleratorSpecializer).GetMethod( nameof(PrintF), - BindingFlags.Static | BindingFlags.NonPublic); + BindingFlags.Static | BindingFlags.NonPublic) + .ThrowIfNull(); #endregion diff --git a/Src/ILGPU/Backends/PTX/PTXBackend.cs b/Src/ILGPU/Backends/PTX/PTXBackend.cs index ebf1e8735..b9b640462 100644 --- a/Src/ILGPU/Backends/PTX/PTXBackend.cs +++ b/Src/ILGPU/Backends/PTX/PTXBackend.cs @@ -16,6 +16,7 @@ using ILGPU.IR.Transformations; using ILGPU.Runtime; using ILGPU.Runtime.Cuda; +using ILGPU.Util; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; @@ -109,7 +110,7 @@ public PTXBackend( CudaCapabilityContext capabilities, CudaArchitecture architecture, CudaInstructionSet instructionSet, - NvvmAPI nvvmAPI) + NvvmAPI? nvvmAPI) : base( context, capabilities, @@ -174,18 +175,18 @@ protected override void Dispose(bool disposing) /// Returns the associated . /// public new PTXArgumentMapper ArgumentMapper => - base.ArgumentMapper as PTXArgumentMapper; + base.ArgumentMapper.AsNotNullCast(); /// /// Returns the supported capabilities. /// public new CudaCapabilityContext Capabilities => - base.Capabilities as CudaCapabilityContext; + base.Capabilities.AsNotNullCast(); /// /// Returns the NVVM API instance (if available). /// - public NvvmAPI NvvmAPI { get; private set; } + public NvvmAPI? NvvmAPI { get; private set; } #endregion @@ -290,7 +291,7 @@ protected override PTXCodeGenerator CreateKernelCodeGenerator( /// protected override CompiledKernel CreateKernel( EntryPoint entryPoint, - CompiledKernel.KernelInfo kernelInfo, + CompiledKernel.KernelInfo? kernelInfo, StringBuilder builder, PTXCodeGenerator.GeneratorArgs data) { @@ -388,7 +389,7 @@ private unsafe void GenerateLibDeviceCode( if (result == NvvmResult.NVVM_SUCCESS) { var compiledString = - compiledPTX + compiledPTX.AsNotNull() .Replace(".version", "//.version") .Replace(".target", "//.target") .Replace(".address_size", "//.address_size"); diff --git a/Src/ILGPU/Backends/PTX/PTXCodeGenerator.Emitter.cs b/Src/ILGPU/Backends/PTX/PTXCodeGenerator.Emitter.cs index e0b286baa..dbb529153 100644 --- a/Src/ILGPU/Backends/PTX/PTXCodeGenerator.Emitter.cs +++ b/Src/ILGPU/Backends/PTX/PTXCodeGenerator.Emitter.cs @@ -11,6 +11,7 @@ using ILGPU.IR; using ILGPU.IR.Values; +using ILGPU.Util; using System; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -204,7 +205,7 @@ public void AppendArgument(PrimitiveRegister argument) if (argument is ConstantRegister constantRegister) AppendArgument(constantRegister); else - AppendArgument(argument as HardwareRegister); + AppendArgument(argument.AsNotNullCast()); } /// @@ -485,7 +486,7 @@ public PredicateScope(HardwareRegister predicateRegister) /// /// The associated register allocator. /// - public PTXRegisterAllocator RegisterAllocator { get; } + public PTXRegisterAllocator? RegisterAllocator { get; } /// /// The allocated predicate register. @@ -626,8 +627,11 @@ public void EmitComplexCommand( // Invoke final emitter var primitiveRegisters = new PrimitiveRegister[registers.Length]; for (int i = 0, e = registers.Length; i < e; ++i) - primitiveRegisters[i] = registers[i] as PrimitiveRegister; - command = emitter.AdjustCommand(command, primitiveRegisters); + { + primitiveRegisters[i] = + registers[i].AsNotNullCast(); + command = emitter.AdjustCommand(command, primitiveRegisters); + } using (var commandEmitter = BeginCommand(command)) emitter.Emit(commandEmitter, primitiveRegisters); break; @@ -638,7 +642,8 @@ public void EmitComplexCommand( for (int j = 0, e2 = registers.Length; j < e2; ++j) { elementRegisters[j] = - (registers[j] as CompoundRegister).Children[i]; + registers[j].AsNotNullCast() + .Children[i]; } EmitComplexCommand(command, emitter, elementRegisters); } @@ -680,7 +685,7 @@ public void EmitComplexCommandWithOffsets( this, command, structureRegister.Children[access.Index] - as PrimitiveRegister, + .AsNotNullCast(), offset + fieldOffset); } break; @@ -869,7 +874,7 @@ public void EmitIOLoad( where TIOEmitter : struct, IIOEmitter where T : struct { - HardwareRegister originalRegister = null; + HardwareRegister? originalRegister = null; // We need a temporary 32bit register for predicate conversion at this point: // 1) load value into temporary register // 2) convert loaded value into predicate @@ -913,7 +918,7 @@ public void EmitIOStore( // We need a temporary 32bit register for predicate conversion at this point: // 1) convert current predicate into 32bit integer // 2) store the converted value from the temporary register - PrimitiveRegister originalRegister = null; + PrimitiveRegister? originalRegister = null; if (register.BasicValueType == BasicValueType.Int1) { originalRegister = register; @@ -922,7 +927,7 @@ public void EmitIOStore( // Convert predicate ConvertPredicateToValue( originalRegister, - register as HardwareRegister); + register.AsNotNullCast()); } // Emit store @@ -930,7 +935,7 @@ public void EmitIOStore( // Free temp register if (originalRegister != null) - FreeRegister(register as HardwareRegister); + FreeRegister(register.AsNotNullCast()); } /// @@ -1077,7 +1082,7 @@ public HardwareRegister EnsureHardwareRegister(PrimitiveRegister register) { command.AppendRegisterMovementSuffix(register.BasicValueType); command.AppendArgument(hardwareRegister); - command.AppendArgument(register as ConstantRegister); + command.AppendArgument(register.AsNotNullCast()); } return hardwareRegister; } diff --git a/Src/ILGPU/Backends/PTX/PTXCodeGenerator.Values.cs b/Src/ILGPU/Backends/PTX/PTXCodeGenerator.Values.cs index 7972709a8..6672d4863 100644 --- a/Src/ILGPU/Backends/PTX/PTXCodeGenerator.Values.cs +++ b/Src/ILGPU/Backends/PTX/PTXCodeGenerator.Values.cs @@ -329,20 +329,24 @@ public void GenerateCode(Predicate predicate) new PredicateConfiguration(conditionRegister, true))) { statement1.AppendSuffix(BasicValueType.Int1); - statement1.AppendArgument(targetRegister as PrimitiveRegister); - statement1.AppendArgument(trueValue as PrimitiveRegister); + statement1.AppendArgument( + targetRegister.AsNotNullCast()); + statement1.AppendArgument( + trueValue.AsNotNullCast()); } using var statement2 = BeginMove( new PredicateConfiguration(conditionRegister, false)); statement2.AppendSuffix(BasicValueType.Int1); - statement2.AppendArgument(targetRegister as PrimitiveRegister); - statement2.AppendArgument(falseValue as PrimitiveRegister); + statement2.AppendArgument( + targetRegister.AsNotNullCast()); + statement2.AppendArgument( + falseValue.AsNotNullCast()); } else { EmitComplexCommand( - null, + string.Empty, new PredicateEmitter(condition), targetRegister, trueValue, @@ -369,10 +373,10 @@ public void GenerateCode(GenericAtomic atomic) var targetRegister = requiresResult ? AllocateHardware(atomic) : default; using var command = BeginCommand(atomicOperation); command.AppendNonLocalAddressSpace( - (atomic.Target.Type as AddressSpaceType).AddressSpace); + atomic.Target.Type.AsNotNullCast().AddressSpace); command.AppendSuffix(suffix); if (requiresResult) - command.AppendArgument(targetRegister); + command.AppendArgument(targetRegister.AsNotNull()); command.AppendArgumentValue(target); command.AppendArgument(value); } @@ -388,7 +392,7 @@ public void GenerateCode(AtomicCAS atomicCAS) using var command = BeginCommand(PTXInstructions.AtomicCASOperation); command.AppendNonLocalAddressSpace( - (atomicCAS.Target.Type as AddressSpaceType).AddressSpace); + atomicCAS.Target.Type.AsNotNullCast().AddressSpace); command.AppendSuffix(atomicCAS.BasicValueType); command.AppendArgument(targetRegister); command.AppendArgumentValue(target); @@ -474,7 +478,7 @@ public void Emit( codeGenerator.EmitIOLoad( Emitter, command, - register as HardwareRegister, + register.AsNotNullCast(), offset); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -498,7 +502,7 @@ public void Emit( public void GenerateCode(Load load) { var address = LoadHardware(load.Source); - var sourceType = load.Source.Type as PointerType; + var sourceType = load.Source.Type.AsNotNullCast(); var targetRegister = Allocate(load); EmitVectorizedCommand( @@ -598,7 +602,7 @@ public void Emit( public void GenerateCode(Store store) { var address = LoadHardware(store.Target); - var targetType = store.Target.Type as PointerType; + var targetType = store.Target.Type.AsNotNullCast(); var value = Load(store.Value); EmitVectorizedCommand( @@ -802,7 +806,7 @@ public void GenerateCode(StringValue value) { // Check for already existing global constant var key = (value.Encoding, value.String); - if (!stringConstants.TryGetValue(key, out string stringBinding)) + if (!stringConstants.TryGetValue(key, out string? stringBinding)) { stringBinding = "__strconst" + value.Id; stringConstants.Add(key, stringBinding); @@ -901,7 +905,7 @@ public void GenerateCode(GetField value) Bind( value, new CompoundRegister( - value.Type as StructureType, + value.Type.AsNotNullCast(), childRegisters.MoveToImmutable())); } } @@ -1251,7 +1255,7 @@ public void GenerateCode(LanguageEmitValue emit) if (emit.UsingRefParams) { // If there is an input, initialize with the supplied argument value. - var pointerType = argument.Type as PointerType; + var pointerType = argument.Type.AsNotNullCast(); var pointerElementType = pointerType.ElementType; var targetRegister = AllocateRegister( @@ -1275,7 +1279,7 @@ public void GenerateCode(LanguageEmitValue emit) registers.Add( emit.IsOutputArgument(argumentIdx) ? AllocateRegister(ResolveRegisterDescription( - (argument.Type as PointerType).ElementType)) + argument.Type.AsNotNullCast().ElementType)) : LoadPrimitive(argument)); } } @@ -1293,7 +1297,7 @@ public void GenerateCode(LanguageEmitValue emit) } else { - emitter.AppendRawString(expression.String); + emitter.AppendRawString(expression.String.AsNotNull()); } } } @@ -1305,7 +1309,7 @@ public void GenerateCode(LanguageEmitValue emit) { var outputArgument = emit.Nodes[argumentIdx]; var address = LoadHardware(outputArgument); - var targetType = outputArgument.Type as PointerType; + var targetType = outputArgument.Type.AsNotNullCast(); var newValue = registers[argumentIdx]; EmitVectorizedCommand( diff --git a/Src/ILGPU/Backends/PTX/PTXCodeGenerator.Views.cs b/Src/ILGPU/Backends/PTX/PTXCodeGenerator.Views.cs index b306e651f..6006b89e3 100644 --- a/Src/ILGPU/Backends/PTX/PTXCodeGenerator.Views.cs +++ b/Src/ILGPU/Backends/PTX/PTXCodeGenerator.Views.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: PTXCodeGenerator.Views.cs @@ -12,6 +12,7 @@ using ILGPU.IR; using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; using System.Diagnostics; namespace ILGPU.Backends.PTX @@ -26,7 +27,7 @@ public void GenerateCode(LoadElementAddress value) Debug.Assert(value.IsPointerAccess, "Invalid pointer access"); var address = LoadPrimitive(value.Source); - var sourceType = value.Source.Type as AddressSpaceType; + var sourceType = value.Source.Type.AsNotNullCast(); var elementSize = sourceType.ElementType.Size; if (value.Is32BitAccess) diff --git a/Src/ILGPU/Backends/PTX/PTXCodeGenerator.cs b/Src/ILGPU/Backends/PTX/PTXCodeGenerator.cs index e23cad594..bd9436f9e 100644 --- a/Src/ILGPU/Backends/PTX/PTXCodeGenerator.cs +++ b/Src/ILGPU/Backends/PTX/PTXCodeGenerator.cs @@ -17,6 +17,7 @@ using ILGPU.IR.Types; using ILGPU.IR.Values; using ILGPU.Runtime.Cuda; +using ILGPU.Util; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; @@ -172,7 +173,7 @@ internal interface IParameterSetupLogic /// /// The intrinsic parameter. /// The allocated register (if any). - Register HandleIntrinsicParameter(int parameterOffset, Parameter parameter); + Register? HandleIntrinsicParameter(int parameterOffset, Parameter parameter); } /// @@ -183,7 +184,7 @@ internal interface IParameterSetupLogic /// /// Does not handle intrinsic parameters. /// - public Register HandleIntrinsicParameter( + public Register? HandleIntrinsicParameter( int parameterOffset, Parameter parameter) => null; @@ -229,7 +230,7 @@ public void Allocate(BasicBlock block, PhiValue phiValue) => /// private static readonly ImmutableArray BasicSuffixes = ImmutableArray.Create( - default, "pred", + string.Empty, "pred", "b8", "b16", "b32", "b64", "f16", "f32", "f64"); @@ -360,7 +361,7 @@ internal PTXCodeGenerator(in GeneratorArgs args, Method method, Allocas allocas) /// /// Returns the associated backend. /// - public new PTXBackend Backend => base.Backend as PTXBackend; + public new PTXBackend Backend => base.Backend.AsNotNullCast(); /// /// Returns the associated method. @@ -598,7 +599,7 @@ protected void GenerateCodeInternal(int registerOffset) } // Build terminator - this.GenerateCodeFor(block.Terminator); + this.GenerateCodeFor(block.Terminator.AsNotNull()); Builder.AppendLine(); } @@ -690,7 +691,7 @@ internal List SetupParameters( foreach (var param in Method.Parameters) { - Register register = null; + Register? register = null; if (offset < paramOffset) { register = logic.HandleIntrinsicParameter(offset, param); @@ -792,7 +793,7 @@ public readonly void Emit( // using the previously allocated temp register codeGenerator.CreateAddressSpaceCast( TempRegister, - primitiveRegister as HardwareRegister, + primitiveRegister.AsNotNullCast(), MemoryAddressSpace.Generic, addressSpaceType.AddressSpace); } @@ -830,7 +831,7 @@ public readonly void Emit( codeGenerator.EmitIOLoad( Emitter, command, - primitiveRegister as HardwareRegister, + primitiveRegister.AsNotNullCast(), offset); } diff --git a/Src/ILGPU/Backends/PTX/PTXCompiledKernel.cs b/Src/ILGPU/Backends/PTX/PTXCompiledKernel.cs index 58353f5ea..606f49026 100644 --- a/Src/ILGPU/Backends/PTX/PTXCompiledKernel.cs +++ b/Src/ILGPU/Backends/PTX/PTXCompiledKernel.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: PTXCompiledKernel.cs @@ -30,7 +30,7 @@ public sealed class PTXCompiledKernel : CompiledKernel internal PTXCompiledKernel( Context context, EntryPoint entryPoint, - KernelInfo info, + KernelInfo? info, string ptxAssembly) : base(context, entryPoint, info) { diff --git a/Src/ILGPU/Backends/PTX/PTXDebugInfoGenerator.cs b/Src/ILGPU/Backends/PTX/PTXDebugInfoGenerator.cs index e0851eeaa..331a8589a 100644 --- a/Src/ILGPU/Backends/PTX/PTXDebugInfoGenerator.cs +++ b/Src/ILGPU/Backends/PTX/PTXDebugInfoGenerator.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: PTXDebugInfoGenerator.cs @@ -45,7 +45,7 @@ internal PTXDebugInfoGeneratorScope(PTXDebugInfoGenerator parent) /// /// Returns the current location. /// - public FileLocation Current { get; private set; } + public FileLocation? Current { get; private set; } #endregion diff --git a/Src/ILGPU/Backends/PTX/PTXInstructions.cs b/Src/ILGPU/Backends/PTX/PTXInstructions.cs index d432c2b3f..33b356e5b 100644 --- a/Src/ILGPU/Backends/PTX/PTXInstructions.cs +++ b/Src/ILGPU/Backends/PTX/PTXInstructions.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: PTXInstructions.cs @@ -54,14 +54,14 @@ public static string GetCompareOperation( { if (CompareUnorderedFloatOperations.TryGetValue( (kind, type), - out string operation)) + out string? operation)) { return operation; } } else { - if (CompareOperations.TryGetValue((kind, type), out string operation)) + if (CompareOperations.TryGetValue((kind, type), out string? operation)) return operation; } throw new NotSupportedIntrinsicException(kind.ToString()); @@ -76,7 +76,7 @@ public static string GetCompareOperation( public static string GetConvertOperation( ArithmeticBasicValueType source, ArithmeticBasicValueType target) => - ConvertOperations.TryGetValue((source, target), out string operation) + ConvertOperations.TryGetValue((source, target), out string? operation) ? operation : throw new NotSupportedIntrinsicException($"{source} -> {target}"); @@ -111,7 +111,7 @@ public static string GetArithmeticOperation( return fastMath && UnaryArithmeticOperationsFastMath.TryGetValue( key, - out string operation) || + out string? operation) || UnaryArithmeticOperations.TryGetValue(key, out operation) ? operation : throw new NotSupportedIntrinsicException(kind.ToString()); @@ -148,7 +148,7 @@ public static string GetArithmeticOperation( return fastMath && BinaryArithmeticOperationsFastMath.TryGetValue( key, - out string operation) || + out string? operation) || BinaryArithmeticOperations.TryGetValue(key, out operation) ? operation : throw new NotSupportedIntrinsicException(kind.ToString()); @@ -163,7 +163,7 @@ public static string GetArithmeticOperation( public static string GetArithmeticOperation( TernaryArithmeticKind kind, ArithmeticBasicValueType type) => - TernaryArithmeticOperations.TryGetValue((kind, type), out string operation) + TernaryArithmeticOperations.TryGetValue((kind, type), out string? operation) ? operation : throw new NotSupportedIntrinsicException(kind.ToString()); @@ -174,7 +174,7 @@ public static string GetArithmeticOperation( /// True, if the return value is required. /// The resolved atomic operation. public static string GetAtomicOperation(AtomicKind kind, bool requireResult) => - AtomicOperations.TryGetValue((kind, requireResult), out string operation) + AtomicOperations.TryGetValue((kind, requireResult), out string? operation) ? operation : throw new NotSupportedIntrinsicException(kind.ToString()); @@ -187,7 +187,7 @@ public static string GetAtomicOperation(AtomicKind kind, bool requireResult) => public static string GetAtomicOperationSuffix( AtomicKind kind, ArithmeticBasicValueType type) => - AtomicOperationsTypes.TryGetValue((kind, type), out string operation) + AtomicOperationsTypes.TryGetValue((kind, type), out string? operation) ? operation : throw new NotSupportedIntrinsicException(kind.ToString()); @@ -248,7 +248,7 @@ public static string GetShuffleOperation(ShuffleKind kind) => /// The number of elements. /// The vector operation suffix. public static string GetVectorOperationSuffix(int numElements) => - VectorSuffixes.TryGetValue(numElements, out string operation) + VectorSuffixes.TryGetValue(numElements, out string? operation) ? operation : throw new NotSupportedIntrinsicException("v" + numElements.ToString()); } diff --git a/Src/ILGPU/Backends/PTX/PTXKernelFunctionGenerator.cs b/Src/ILGPU/Backends/PTX/PTXKernelFunctionGenerator.cs index 113a22072..413f694ba 100644 --- a/Src/ILGPU/Backends/PTX/PTXKernelFunctionGenerator.cs +++ b/Src/ILGPU/Backends/PTX/PTXKernelFunctionGenerator.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: PTXKernelFunctionGenerator.cs @@ -14,6 +14,7 @@ using ILGPU.IR.Analyses; using ILGPU.IR.Values; using ILGPU.Runtime; +using ILGPU.Util; using System; using System.Text; @@ -47,12 +48,12 @@ public KernelParameterSetupLogic( /// /// Returns the main index register. /// - public Register IndexRegister { get; private set; } + public Register? IndexRegister { get; private set; } /// /// Returns the length register of implicitly grouped kernels. /// - public Register LengthRegister { get; private set; } + public Register? LengthRegister { get; private set; } /// /// Returns the associated register allocator. @@ -62,7 +63,7 @@ public KernelParameterSetupLogic( /// /// Updates index and length registers. /// - public Register HandleIntrinsicParameter( + public Register? HandleIntrinsicParameter( int parameterOffset, Parameter parameter) { @@ -251,7 +252,7 @@ private void EmitImplicitKernelIndex( /// /// The length register of implicitly grouped kernels. /// - private void SetupKernelIndex(Register indexRegister, Register lengthRegister) + private void SetupKernelIndex(Register? indexRegister, Register? lengthRegister) { // Skip this step for grouped kernels if (EntryPoint.IsExplicitlyGrouped) @@ -260,19 +261,19 @@ private void SetupKernelIndex(Register indexRegister, Register lengthRegister) { EmitImplicitKernelIndex( 0, - indexRegister as PrimitiveRegister, - lengthRegister as PrimitiveRegister); + indexRegister.AsNotNullCast(), + lengthRegister.AsNotNullCast()); } else { - var compoundIndex = indexRegister as CompoundRegister; - var compoundLength = lengthRegister as CompoundRegister; + var compoundIndex = indexRegister.AsNotNullCast(); + var compoundLength = lengthRegister.AsNotNullCast(); for (int i = 0, e = (int)EntryPoint.IndexType; i < e; ++i) { EmitImplicitKernelIndex( i, - compoundIndex.Children[i] as PrimitiveRegister, - compoundLength.Children[i] as PrimitiveRegister); + compoundIndex.Children[i].AsNotNullCast(), + compoundLength.Children[i].AsNotNullCast()); } } } diff --git a/Src/ILGPU/Backends/PTX/Transformations/PTXAcceleratorSpecializer.cs b/Src/ILGPU/Backends/PTX/Transformations/PTXAcceleratorSpecializer.cs index 660a21d5e..a02f9046f 100644 --- a/Src/ILGPU/Backends/PTX/Transformations/PTXAcceleratorSpecializer.cs +++ b/Src/ILGPU/Backends/PTX/Transformations/PTXAcceleratorSpecializer.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: PTXAcceleratorSpecializer.cs @@ -16,6 +16,7 @@ using ILGPU.IR.Values; using ILGPU.Resources; using ILGPU.Runtime; +using ILGPU.Util; using System.Reflection; using System.Text; @@ -60,7 +61,8 @@ private static void AssertFailed( private static readonly MethodInfo PrintFMethod = typeof(PTXAcceleratorSpecializer).GetMethod( nameof(PrintF), - BindingFlags.Static | BindingFlags.NonPublic); + BindingFlags.Static | BindingFlags.NonPublic) + .ThrowIfNull(); /// /// A handle to the @@ -69,7 +71,8 @@ private static void AssertFailed( private static readonly MethodInfo AssertFailedMethod = typeof(PTXAcceleratorSpecializer).GetMethod( nameof(AssertFailed), - BindingFlags.Static | BindingFlags.NonPublic); + BindingFlags.Static | BindingFlags.NonPublic) + .ThrowIfNull(); #endregion @@ -129,7 +132,7 @@ protected override void Implement( context.Declare(AssertFailedMethod, out var _)); // Move the debug assertion to this block - var sourceMessage = debugAssert.Message.ResolveAs(); + var sourceMessage = debugAssert.Message.ResolveAs().AsNotNull(); var message = innerBuilder.CreatePrimitiveValue( location, sourceMessage.String, diff --git a/Src/ILGPU/Backends/PointerViews/LowerPointerViews.cs b/Src/ILGPU/Backends/PointerViews/LowerPointerViews.cs index 9565cbed2..c9b652d68 100644 --- a/Src/ILGPU/Backends/PointerViews/LowerPointerViews.cs +++ b/Src/ILGPU/Backends/PointerViews/LowerPointerViews.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: LowerPointerViews.cs @@ -14,6 +14,7 @@ using ILGPU.IR.Transformations; using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; namespace ILGPU.Backends.PointerViews { @@ -192,7 +193,8 @@ private static void Lower( // Compute new length: // newLength = length * sourceElementSize / targetElementSize; - var sourceElementType = (typeLowering[value] as ViewType).ElementType; + var sourceElementType = + typeLowering[value].AsNotNullCast().ElementType; var sourceElementSize = builder.CreateLongSizeOf( location, sourceElementType); diff --git a/Src/ILGPU/Backends/PointerViews/Utilities.cs b/Src/ILGPU/Backends/PointerViews/Utilities.cs index 7bdd75f4e..370fae61a 100644 --- a/Src/ILGPU/Backends/PointerViews/Utilities.cs +++ b/Src/ILGPU/Backends/PointerViews/Utilities.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Utilities.cs @@ -9,6 +9,7 @@ // Source License. See LICENSE.txt for details. // --------------------------------------------------------------------------------------- +using ILGPU.Util; using System; using System.Collections.Generic; using System.Reflection; @@ -55,7 +56,8 @@ public static ConstructorInfo GetViewConstructor(Type implType) => { typeof(ArrayView<>).MakeGenericType( implType.GetGenericArguments()[0]) - }); + }) + .ThrowIfNull(); /// /// Returns the pointer field of a view implementation. @@ -63,7 +65,7 @@ public static ConstructorInfo GetViewConstructor(Type implType) => /// The view implementation type. /// The resolved field. public static FieldInfo GetPtrField(Type implType) => - implType.GetField(nameof(ViewImplementation.Ptr)); + implType.GetField(nameof(ViewImplementation.Ptr)).ThrowIfNull(); /// /// Returns the length field of a view implementation. @@ -71,7 +73,7 @@ public static FieldInfo GetPtrField(Type implType) => /// The view implementation type. /// The resolved field. public static FieldInfo GetLengthField(Type implType) => - implType.GetField(nameof(ViewImplementation.Length)); + implType.GetField(nameof(ViewImplementation.Length)).ThrowIfNull(); /// /// The method handle of the method. @@ -79,7 +81,8 @@ public static FieldInfo GetLengthField(Type implType) => private static readonly MethodInfo GetNativePtrMethodInfo = typeof(ViewImplementation).GetMethod( nameof(GetNativePtr), - BindingFlags.NonPublic | BindingFlags.Static); + BindingFlags.NonPublic | BindingFlags.Static) + .ThrowIfNull(); /// /// Gets the associated native pointer that is stored inside the given view. diff --git a/Src/ILGPU/Backends/RegisterAllocator.cs b/Src/ILGPU/Backends/RegisterAllocator.cs index aa5a7ef20..64e6fbb98 100644 --- a/Src/ILGPU/Backends/RegisterAllocator.cs +++ b/Src/ILGPU/Backends/RegisterAllocator.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: RegisterAllocator.cs @@ -12,6 +12,7 @@ using ILGPU.IR; using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -266,7 +267,7 @@ internal CompoundRegister( /// /// Returns the underlying type. /// - public new StructureType Type => base.Type as StructureType; + public new StructureType Type => base.Type.AsNotNullCast(); /// /// Returns all child registers. @@ -412,7 +413,7 @@ public HardwareRegister Allocate(Value node, RegisterDescription description) { node.AssertNotNull(node); - if (aliases.TryGetValue(node, out Value alias)) + if (aliases.TryGetValue(node, out Value? alias)) node = alias; if (!registerLookup.TryGetValue(node, out RegisterEntry entry)) { @@ -420,7 +421,7 @@ public HardwareRegister Allocate(Value node, RegisterDescription description) entry = new RegisterEntry(targetRegister, node); registerLookup.Add(node, entry); } - var result = entry.Register as HardwareRegister; + var result = entry.Register.AsNotNullCast(); node.AssertNotNull(result); return result; } @@ -444,7 +445,7 @@ public HardwareRegister AllocateHardware(Value node) public Register Allocate(Value node) { node.AssertNotNull(node); - if (aliases.TryGetValue(node, out Value alias)) + if (aliases.TryGetValue(node, out Value? alias)) node = alias; if (!registerLookup.TryGetValue(node, out RegisterEntry entry)) { @@ -504,7 +505,7 @@ public void Alias(Value node, Value aliasNode) { node.AssertNotNull(node); node.AssertNotNull(aliasNode); - if (aliases.TryGetValue(aliasNode, out Value otherAlias)) + if (aliases.TryGetValue(aliasNode, out Value? otherAlias)) aliasNode = otherAlias; aliases[node] = aliasNode; } @@ -517,7 +518,7 @@ public void Alias(Value node, Value aliasNode) public T LoadAs(Value node) where T : Register { - var result = Load(node) as T; + var result = Load(node).AsNotNullCast(); node.AssertNotNull(result); return result; } @@ -530,7 +531,7 @@ public T LoadAs(Value node) public Register Load(Value node) { node.AssertNotNull(node); - if (aliases.TryGetValue(node, out Value alias)) + if (aliases.TryGetValue(node, out Value? alias)) node = alias; return registerLookup.TryGetValue(node, out RegisterEntry entry) ? entry.Register @@ -546,7 +547,7 @@ public PrimitiveRegister LoadPrimitive(Value node) { var result = Load(node); node.AssertNotNull(result); - return result as PrimitiveRegister; + return result.AsNotNullCast(); } /// @@ -558,7 +559,7 @@ public HardwareRegister LoadHardware(Value node) { var result = Load(node); node.AssertNotNull(result); - return result as HardwareRegister; + return result.AsNotNullCast(); } /// diff --git a/Src/ILGPU/Backends/SeparateViews/ViewImplementation.cs b/Src/ILGPU/Backends/SeparateViews/ViewImplementation.cs index 42443ced0..74bbd7c0d 100644 --- a/Src/ILGPU/Backends/SeparateViews/ViewImplementation.cs +++ b/Src/ILGPU/Backends/SeparateViews/ViewImplementation.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: ViewImplementation.cs @@ -32,7 +32,8 @@ public unsafe readonly struct ViewImplementation /// A handle to the method. /// private static readonly MethodInfo CreateMethod = typeof(ViewImplementation). - GetMethod(nameof(Create)); + GetMethod(nameof(Create)) + .ThrowIfNull(); /// /// Returns a specialized create method. @@ -42,8 +43,8 @@ public unsafe readonly struct ViewImplementation [MethodImpl(MethodImplOptions.AggressiveInlining)] public static MethodInfo GetCreateMethod(Type sourceType) { - sourceType.IsArrayViewType(out Type elementType); - return CreateMethod.MakeGenericMethod(elementType); + sourceType.IsArrayViewType(out Type? elementType); + return CreateMethod.MakeGenericMethod(elementType.AsNotNull()); } /// @@ -71,7 +72,7 @@ public static ViewImplementation Create(ArrayView source) /// The view implementation type. /// The resolved field. public static FieldInfo GetIndexField(Type implType) => - implType.GetField(nameof(Index)); + implType.GetField(nameof(Index)).AsNotNull(); /// /// Returns the length field of a view implementation. @@ -79,7 +80,7 @@ public static FieldInfo GetIndexField(Type implType) => /// The view implementation type. /// The resolved field. public static FieldInfo GetLengthField(Type implType) => - implType.GetField(nameof(Length)); + implType.GetField(nameof(Length)).AsNotNull(); #endregion diff --git a/Src/ILGPU/Backends/VariableAllocator.cs b/Src/ILGPU/Backends/VariableAllocator.cs index 80c00e92c..04d5e59e5 100644 --- a/Src/ILGPU/Backends/VariableAllocator.cs +++ b/Src/ILGPU/Backends/VariableAllocator.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: VariableAllocator.cs @@ -146,7 +146,7 @@ internal PointerVariable( /// /// Returns the represented IR type. /// - public new PointerType Type => base.Type as PointerType; + public new PointerType Type => base.Type.AsNotNullCast(); } /// @@ -166,7 +166,7 @@ internal StringVariable(int id, StringType type) /// /// Returns the represented IR string type. /// - public new StringType Type => base.Type as StringType; + public new StringType Type => base.Type.AsNotNullCast(); } /// @@ -186,7 +186,7 @@ internal ObjectVariable(int id, ObjectType type) /// /// Returns the represented IR type. /// - public new ObjectType Type => base.Type as ObjectType; + public new ObjectType Type => base.Type.AsNotNullCast(); } #endregion @@ -213,7 +213,7 @@ protected VariableAllocator() { } /// The allocated variable. public Variable Allocate(Value value) { - if (variableLookup.TryGetValue(value, out Variable variable)) + if (variableLookup.TryGetValue(value, out Variable? variable)) return variable; variable = value is PrimitiveValue primitiveValue ? new ConstantVariable(idCounter++, primitiveValue) @@ -230,7 +230,7 @@ public Variable Allocate(Value value) /// The allocated variable. public Variable Allocate(Value value, ArithmeticBasicValueType basicValueType) { - if (variableLookup.TryGetValue(value, out Variable variable)) + if (variableLookup.TryGetValue(value, out Variable? variable)) return variable; variable = AllocateType(basicValueType); variableLookup.Add(value, variable); @@ -244,7 +244,7 @@ public Variable Allocate(Value value, ArithmeticBasicValueType basicValueType) /// The allocated variable. public T AllocateAs(Value value) where T : Variable => - Allocate(value) as T; + Allocate(value).AsNotNullCast(); /// /// Allocates the given type. diff --git a/Src/ILGPU/CompatibilitySuppressions.xml b/Src/ILGPU/CompatibilitySuppressions.xml index 2f7dfb841..4d6628336 100644 --- a/Src/ILGPU/CompatibilitySuppressions.xml +++ b/Src/ILGPU/CompatibilitySuppressions.xml @@ -1,4 +1,459 @@  + + CP0001 + T:ILGPU.IR.Intrinsics.IntrinsicValueMatcher`1 + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0001 + T:ILGPU.IR.Intrinsics.IntrinsicValueMatcher`2 + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0001 + T:ILGPU.IR.Intrinsics.IntrinsicValueMatcher`1 + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0001 + T:ILGPU.IR.Intrinsics.IntrinsicValueMatcher`2 + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0001 + T:ILGPU.IR.Intrinsics.IntrinsicValueMatcher`1 + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0001 + T:ILGPU.IR.Intrinsics.IntrinsicValueMatcher`2 + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0001 + T:ILGPU.IR.Intrinsics.IntrinsicValueMatcher`1 + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0001 + T:ILGPU.IR.Intrinsics.IntrinsicValueMatcher`2 + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0001 + T:ILGPU.IR.Intrinsics.IntrinsicValueMatcher`1 + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + + + CP0001 + T:ILGPU.IR.Intrinsics.IntrinsicValueMatcher`2 + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + + + CP0002 + F:ILGPU.Frontend.DebugInformation.MethodScope.Invalid + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0002 + M:ILGPU.Frontend.CodeGenerationResult.get_ResultHandle + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.IRContext.TryGetMethodHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.MethodMapping`1.ReadOnlyCollection.TryGetHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.MethodMapping`1.TryGetHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Transformations.LowerViews.ViewTypeLowering.#ctor + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Types.IRTypeContext.get_Dense1DStrideType + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Types.TypeLowering`1.#ctor + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.AcceleratorObject.#ctor + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.AcceleratorStream.#ctor + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.MemoryBuffer.#ctor(System.Int64,System.Int32) + lib/net471/ILGPU.dll + lib/net471/ILGPU.dll + true + + + CP0002 + F:ILGPU.Frontend.DebugInformation.MethodScope.Invalid + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.Frontend.CodeGenerationResult.get_ResultHandle + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.IRContext.TryGetMethodHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.MethodMapping`1.ReadOnlyCollection.TryGetHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.MethodMapping`1.TryGetHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Transformations.LowerViews.ViewTypeLowering.#ctor + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Types.IRTypeContext.get_Dense1DStrideType + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Types.TypeLowering`1.#ctor + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.AcceleratorObject.#ctor + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.AcceleratorStream.#ctor + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.MemoryBuffer.#ctor(System.Int64,System.Int32) + lib/net5.0/ILGPU.dll + lib/net5.0/ILGPU.dll + true + + + CP0002 + F:ILGPU.Frontend.DebugInformation.MethodScope.Invalid + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.Frontend.CodeGenerationResult.get_ResultHandle + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.IRContext.TryGetMethodHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.MethodMapping`1.ReadOnlyCollection.TryGetHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.MethodMapping`1.TryGetHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Transformations.LowerViews.ViewTypeLowering.#ctor + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Types.IRTypeContext.get_Dense1DStrideType + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Types.TypeLowering`1.#ctor + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.AcceleratorObject.#ctor + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.AcceleratorStream.#ctor + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.MemoryBuffer.#ctor(System.Int64,System.Int32) + lib/net6.0/ILGPU.dll + lib/net6.0/ILGPU.dll + true + + + CP0002 + F:ILGPU.Frontend.DebugInformation.MethodScope.Invalid + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.Frontend.CodeGenerationResult.get_ResultHandle + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.IRContext.TryGetMethodHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.MethodMapping`1.ReadOnlyCollection.TryGetHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.MethodMapping`1.TryGetHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Transformations.LowerViews.ViewTypeLowering.#ctor + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Types.IRTypeContext.get_Dense1DStrideType + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Types.TypeLowering`1.#ctor + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.AcceleratorObject.#ctor + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.AcceleratorStream.#ctor + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.MemoryBuffer.#ctor(System.Int64,System.Int32) + lib/net7.0/ILGPU.dll + lib/net7.0/ILGPU.dll + true + + + CP0002 + F:ILGPU.Frontend.DebugInformation.MethodScope.Invalid + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + + + CP0002 + M:ILGPU.Frontend.CodeGenerationResult.get_ResultHandle + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.IRContext.TryGetMethodHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.MethodMapping`1.ReadOnlyCollection.TryGetHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.MethodMapping`1.TryGetHandle(System.Reflection.MethodBase,ILGPU.IR.MethodHandle@) + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Transformations.LowerViews.ViewTypeLowering.#ctor + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Types.IRTypeContext.get_Dense1DStrideType + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + + + CP0002 + M:ILGPU.IR.Types.TypeLowering`1.#ctor + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.AcceleratorObject.#ctor + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.AcceleratorStream.#ctor + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + + + CP0002 + M:ILGPU.Runtime.MemoryBuffer.#ctor(System.Int64,System.Int32) + lib/netstandard2.1/ILGPU.dll + lib/netstandard2.1/ILGPU.dll + true + \ No newline at end of file diff --git a/Src/ILGPU/Context.cs b/Src/ILGPU/Context.cs index 98e16fdcd..b2cb96ecb 100644 --- a/Src/ILGPU/Context.cs +++ b/Src/ILGPU/Context.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2022 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: Context.cs @@ -96,7 +96,7 @@ internal Enumerator(List devices) /// /// Returns the current use. /// - public TDevice Current => enumerator.Current as TDevice; + public TDevice Current => enumerator.Current.AsNotNullCast(); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -142,7 +142,7 @@ public readonly TDevice this[int deviceIndex] if (deviceIndex < 0) throw new ArgumentOutOfRangeException(nameof(deviceIndex)); return deviceIndex < Count - ? devices[deviceIndex] as TDevice + ? devices[deviceIndex].AsNotNullCast() : throw new NotSupportedException( RuntimeErrorMessages.NotSupportedTargetAccelerator); } @@ -176,7 +176,8 @@ public readonly TDevice this[int deviceIndex] static Context() { var versionString = Assembly.GetExecutingAssembly(). - GetCustomAttribute().Version; + GetCustomAttribute().ThrowIfNull() + .Version; int offset = 0; for (int i = 0; i < 3; ++i) offset = versionString.IndexOf('.', offset + 1); @@ -184,7 +185,8 @@ static Context() InliningAttributeBuilder = new CustomAttributeBuilder( typeof(MethodImplAttribute).GetConstructor( - new Type[] { typeof(MethodImplOptions) }), + new Type[] { typeof(MethodImplOptions) }) + .ThrowIfNull(), new object[] { MethodImplOptions.AggressiveInlining }); } @@ -195,7 +197,7 @@ static Context() /// /// Will be called when a new accelerator has been created. /// - public event EventHandler AcceleratorCreated; + public event EventHandler? AcceleratorCreated; #endregion @@ -241,7 +243,7 @@ internal Context( IntrinsicManager = builder.IntrinsicManager; // Create frontend - DebugInformationManager frontendDebugInformationManager = + DebugInformationManager? frontendDebugInformationManager = Properties.DebugSymbolsMode > DebugSymbolsMode.Disabled ? DebugInformationManager : null; @@ -613,7 +615,7 @@ internal ContextCodeGenerationPhase( /// /// Returns the exception from code generation failure. /// - public Exception LastException => Context.ILFrontend.LastException; + public Exception? LastException => Context.ILFrontend.LastException; #endregion diff --git a/Src/ILGPU/ContextProperties.cs b/Src/ILGPU/ContextProperties.cs index db3729e4b..7f2159f3b 100644 --- a/Src/ILGPU/ContextProperties.cs +++ b/Src/ILGPU/ContextProperties.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: ContextProperties.cs @@ -403,12 +403,12 @@ private ContextProperties(Dictionary sourceProperties) /// /// Returns the path to LibNVVM DLL. /// - public string LibNvvmPath { get; protected set; } + public string? LibNvvmPath { get; protected set; } /// /// Returns the path to LibDevice bitcode. /// - public string LibDevicePath { get; protected set; } + public string? LibDevicePath { get; protected set; } #endregion diff --git a/Src/ILGPU/Frontend/Block.CFGBuilder.cs b/Src/ILGPU/Frontend/Block.CFGBuilder.cs index eae38d733..a293f40c4 100644 --- a/Src/ILGPU/Frontend/Block.CFGBuilder.cs +++ b/Src/ILGPU/Frontend/Block.CFGBuilder.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Block.CFGBuilder.cs @@ -130,7 +130,7 @@ internal CFGBuilder( [MethodImpl(MethodImplOptions.AggressiveInlining)] private Block AppendBasicBlock(Location location, int target) { - if (!blockMapping.TryGetValue(target, out Block block)) + if (!blockMapping.TryGetValue(target, out Block? block)) { var basicBlock = Builder.CreateBasicBlock(location); block = new Block(CodeGenerator, basicBlock); @@ -177,7 +177,7 @@ private void BuildBasicBlocks() [MethodImpl(MethodImplOptions.AggressiveInlining)] private void AddSuccessor(Block current, Block successor) { - if (!successorMapping.TryGetValue(current, out List successors)) + if (!successorMapping.TryGetValue(current, out List? successors)) { successors = new List(); successorMapping.Add(current, successors); @@ -230,7 +230,7 @@ private void SetupBasicBlocks( { var instruction = disassembledMethod[instructionIdx]; // Handle implicit cases: jumps to blocks without a jump instruction - if (blockMapping.TryGetValue(instruction.Offset, out Block other) && + if (blockMapping.TryGetValue(instruction.Offset, out Block? other) && current != other) { // Wire current and new block diff --git a/Src/ILGPU/Frontend/Block.cs b/Src/ILGPU/Frontend/Block.cs index bebd412e3..8bdec1167 100644 --- a/Src/ILGPU/Frontend/Block.cs +++ b/Src/ILGPU/Frontend/Block.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Block.cs @@ -83,7 +83,7 @@ private Block(CodeGenerator codeGenerator, BasicBlock.Builder builder) /// /// Returns the current terminator. /// - public TerminatorValue Terminator => BasicBlock.Terminator; + public TerminatorValue? Terminator => BasicBlock.Terminator; /// /// Returns the current stack counter. @@ -134,7 +134,7 @@ public Value GetValue(VariableRef var) => [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan GetBuilderTerminator(int count) { - var targets = ((BuilderTerminator)Terminator).Targets; + var targets = Terminator.AsNotNullCast().Targets; Terminator.Assert(targets.Length == count); return targets; } @@ -257,7 +257,7 @@ public Value PopInt(Location location, ConvertFlags flags) public ValueList PopMethodArgs( Location location, MethodBase methodBase, - Value instanceValue) + Value? instanceValue) { var parameters = methodBase.GetParameters(); var parameterOffset = methodBase.GetParameterOffset(); @@ -279,8 +279,9 @@ public ValueList PopMethodArgs( { if (instanceValue == null) { - var declaringType = Builder.CreateType(methodBase.DeclaringType); - if (!Intrinsics.IsIntrinsicArrayType(methodBase.DeclaringType)) + var baseDeclaringType = methodBase.DeclaringType.AsNotNull(); + var declaringType = Builder.CreateType(baseDeclaringType); + if (!Intrinsics.IsIntrinsicArrayType(baseDeclaringType)) { declaringType = Builder.CreatePointerType( declaringType, diff --git a/Src/ILGPU/Frontend/CodeGenerator/Arithmetic.cs b/Src/ILGPU/Frontend/CodeGenerator/Arithmetic.cs index b15d9ca74..6b5fcf2d7 100644 --- a/Src/ILGPU/Frontend/CodeGenerator/Arithmetic.cs +++ b/Src/ILGPU/Frontend/CodeGenerator/Arithmetic.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Arithmetic.cs @@ -13,6 +13,7 @@ using ILGPU.IR.Types; using ILGPU.IR.Values; using ILGPU.Util; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace ILGPU.Frontend @@ -58,7 +59,7 @@ shiftValue is null private bool TryConvertIntoLoadElementAddress( Value left, BinaryArithmeticValue baseAddress, - out Value result) + [NotNullWhen(true)] out Value? result) { if ( // Check multiplications diff --git a/Src/ILGPU/Frontend/CodeGenerator/Calls.cs b/Src/ILGPU/Frontend/CodeGenerator/Calls.cs index 374b10f91..ababdbb7c 100644 --- a/Src/ILGPU/Frontend/CodeGenerator/Calls.cs +++ b/Src/ILGPU/Frontend/CodeGenerator/Calls.cs @@ -104,7 +104,7 @@ private void MakeCall(MethodBase target) /// The resolved call target. private MethodInfo ResolveVirtualCallTarget( MethodInfo target, - Type constrainedType) + Type? constrainedType) { const BindingFlags ConstraintMethodFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; @@ -127,7 +127,7 @@ private MethodInfo ResolveVirtualCallTarget( // However, there are two special cases that are supported: // x.GetHashCode(), x.ToString() // where GetHashCode and ToString are defined in Object. - MethodInfo actualTarget = null; + MethodInfo? actualTarget = null; if (target.DeclaringType == typeof(object)) { var @params = target.GetParameters(); @@ -146,7 +146,7 @@ private MethodInfo ResolveVirtualCallTarget( throw Location.GetNotSupportedException( ErrorMessages.NotSupportedVirtualMethodCallToObject, target.Name, - actualTarget.DeclaringType, + actualTarget.DeclaringType.AsNotNull(), constrainedType); } } @@ -156,7 +156,7 @@ private MethodInfo ResolveVirtualCallTarget( if (sourceGenerics.Length > 0) target = target.GetGenericMethodDefinition(); var interfaceMapping = constrainedType.GetInterfaceMap( - target.DeclaringType); + target.DeclaringType.AsNotNull()); for ( int i = 0, e = interfaceMapping.InterfaceMethods.Length; i < e; @@ -207,7 +207,7 @@ private void MakeVirtualCall(ILInstruction instruction) /// /// The target type on which to invoke the method. /// - private void MakeVirtualCall(MethodInfo target, Type constrainedType) + private void MakeVirtualCall(MethodInfo target, Type? constrainedType) { target = ResolveVirtualCallTarget(target, constrainedType); MakeCall(target); diff --git a/Src/ILGPU/Frontend/CodeGenerator/CodeGenerator.cs b/Src/ILGPU/Frontend/CodeGenerator/CodeGenerator.cs index d1b70fcf1..d443a04e1 100644 --- a/Src/ILGPU/Frontend/CodeGenerator/CodeGenerator.cs +++ b/Src/ILGPU/Frontend/CodeGenerator/CodeGenerator.cs @@ -71,6 +71,9 @@ public CodeGenerator( cfgBuilder.Blocks); SetupVariables(); + + // NB: Initialized during GenerateCode. + Block = Utilities.InitNotNullable(); } /// @@ -103,7 +106,7 @@ private void SetupVariables() // Initialize params if (!Method.IsStatic && !Method.IsNotCapturingLambda()) { - var declaringType = builder.CreateType(Method.DeclaringType); + var declaringType = builder.CreateType(Method.DeclaringType.AsNotNull()); declaringType = builder.CreatePointerType( declaringType, MemoryAddressSpace.Generic); @@ -142,7 +145,7 @@ private void SetupVariables() } // Initialize locals - var localVariables = Method.GetMethodBody().LocalVariables; + var localVariables = Method.GetMethodBody().AsNotNull().LocalVariables; for (int i = 0, e = localVariables.Count; i < e; ++i) { var variable = localVariables[i]; @@ -384,7 +387,8 @@ private void GenerateCodeForBlock() [MethodImpl(MethodImplOptions.AggressiveInlining)] private void VerifyNotRuntimeMethod(MethodBase method) { - Debug.Assert(method != null, "Invalid method"); + if (method.DeclaringType == null || method.DeclaringType.FullName == null) + return; var @namespace = method.DeclaringType.FullName; // Internal unsafe intrinsic methods if (@namespace.StartsWith( diff --git a/Src/ILGPU/Frontend/CodeGenerator/Convert.cs b/Src/ILGPU/Frontend/CodeGenerator/Convert.cs index bbc2a1473..163659e0d 100644 --- a/Src/ILGPU/Frontend/CodeGenerator/Convert.cs +++ b/Src/ILGPU/Frontend/CodeGenerator/Convert.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Convert.cs @@ -59,7 +59,7 @@ public Value CreateConversion( { if (value.Type is AddressSpaceType) { - var otherType = targetType as AddressSpaceType; + var otherType = targetType.AsNotNullCast(); value = Builder.CreateAddressSpaceCast( Location, value, diff --git a/Src/ILGPU/Frontend/CodeGenerator/Fields.cs b/Src/ILGPU/Frontend/CodeGenerator/Fields.cs index 5d529f93e..722ee848e 100644 --- a/Src/ILGPU/Frontend/CodeGenerator/Fields.cs +++ b/Src/ILGPU/Frontend/CodeGenerator/Fields.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Fields.cs @@ -28,7 +28,7 @@ partial class CodeGenerator private FieldSpan ComputeFieldSpan(TypeNode type, FieldInfo field) { var typeInfo = TypeContext.GetTypeInfo(field.FieldType); - var parentInfo = TypeContext.GetTypeInfo(field.DeclaringType); + var parentInfo = TypeContext.GetTypeInfo(field.DeclaringType.AsNotNull()); var fieldIndex = parentInfo.GetAbsoluteIndex(field); if (type.IsStructureType) @@ -93,7 +93,7 @@ private void MakeLoadFieldAddress(FieldInfo field) if (field == null) throw Location.GetInvalidOperationException(); var targetPointerType = Builder.CreatePointerType( - Builder.CreateType(field.DeclaringType), + Builder.CreateType(field.DeclaringType.AsNotNull()), MemoryAddressSpace.Generic); var address = Block.Pop( targetPointerType, diff --git a/Src/ILGPU/Frontend/CodeGenerator/Objects.cs b/Src/ILGPU/Frontend/CodeGenerator/Objects.cs index 595168d24..887a7854a 100644 --- a/Src/ILGPU/Frontend/CodeGenerator/Objects.cs +++ b/Src/ILGPU/Frontend/CodeGenerator/Objects.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Objects.cs @@ -60,7 +60,7 @@ private void MakeNewObject(MethodBase method) if (constructor == null) throw Location.GetInvalidOperationException(); - var type = constructor.DeclaringType; + var type = constructor.DeclaringType.AsNotNull(); var typeNode = Builder.CreateType(type); var alloca = CreateTempAlloca(typeNode); diff --git a/Src/ILGPU/Frontend/DebugInformation/AssemblyDebugInformation.cs b/Src/ILGPU/Frontend/DebugInformation/AssemblyDebugInformation.cs index 8b1053dab..b6d97698c 100644 --- a/Src/ILGPU/Frontend/DebugInformation/AssemblyDebugInformation.cs +++ b/Src/ILGPU/Frontend/DebugInformation/AssemblyDebugInformation.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: AssemblyDebugInformation.cs @@ -12,6 +12,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; using System.Reflection.Metadata; @@ -52,6 +53,10 @@ internal AssemblyDebugInformation(Assembly assembly) { Assembly = assembly; Modules = ImmutableArray.Empty; + + readerProvider = + MetadataReaderProvider.FromPortablePdbImage(ImmutableArray.Empty); + MetadataReader = readerProvider.GetMetadataReader(); } /// @@ -75,7 +80,7 @@ internal AssemblyDebugInformation(Assembly assembly, Stream pdbStream) { var definitionHandle = methodHandle.ToDefinitionHandle(); var metadataToken = MetadataTokens.GetToken(definitionHandle); - if (TryResolveMethod(metadataToken, out MethodBase method)) + if (TryResolveMethod(metadataToken, out MethodBase? method)) { debugInformation.Add( method, @@ -129,7 +134,9 @@ MetadataReaderOperation IMetadataReaderOperationProvider.BeginOperation() => /// The resolved method (or null). /// True, if the given token could be resolved. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryResolveMethod(int metadataToken, out MethodBase method) + public bool TryResolveMethod( + int metadataToken, + [NotNullWhen(true)] out MethodBase? method) { foreach (var module in Modules) { @@ -151,7 +158,7 @@ public bool TryResolveMethod(int metadataToken, out MethodBase method) /// True, if the requested debug information could be loaded. public bool TryLoadDebugInformation( MethodBase methodBase, - out MethodDebugInformation methodDebugInformation) + [NotNullWhen(true)] out MethodDebugInformation? methodDebugInformation) { Debug.Assert(methodBase != null, "Invalid method"); Debug.Assert( diff --git a/Src/ILGPU/Frontend/DebugInformation/DebugInformationManager.cs b/Src/ILGPU/Frontend/DebugInformation/DebugInformationManager.cs index ce3c3f136..d667c3cf0 100644 --- a/Src/ILGPU/Frontend/DebugInformation/DebugInformationManager.cs +++ b/Src/ILGPU/Frontend/DebugInformation/DebugInformationManager.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: DebugInformationManager.cs @@ -58,7 +58,8 @@ private interface ILoader /// bool Load( Assembly assembly, - out AssemblyDebugInformation assemblyDebugInformation); + [NotNullWhen(true)] + out AssemblyDebugInformation? assemblyDebugInformation); } /// @@ -104,7 +105,7 @@ public bool Load( Assembly assembly, out AssemblyDebugInformation assemblyDebugInformation) { - if (Parent.pdbFiles.TryGetValue(PDBFileName, out string fileName)) + if (Parent.pdbFiles.TryGetValue(PDBFileName, out string? fileName)) { try { @@ -152,20 +153,21 @@ public AutoFileLoader(DebugInformationManager parent) /// public DebugInformationManager Parent { get; } - /// + /// public bool Load( Assembly assembly, - out AssemblyDebugInformation assemblyDebugInformation) + [NotNullWhen(true)] + out AssemblyDebugInformation? assemblyDebugInformation) { assemblyDebugInformation = null; if (assembly.IsDynamic || string.IsNullOrEmpty(assembly.Location)) return false; var debugDir = Path.GetDirectoryName(assembly.Location); - if (!Parent.lookupDirectories.Contains(debugDir)) + if (debugDir != null && !Parent.lookupDirectories.Contains(debugDir)) Parent.RegisterLookupDirectory(debugDir); - var pdbFileName = assembly.GetName().Name; + var pdbFileName = assembly.GetName().Name.AsNotNull(); var loader = new FileLoader(Parent, pdbFileName); return loader.Load(assembly, out assemblyDebugInformation); } @@ -199,7 +201,7 @@ public StreamLoader(DebugInformationManager parent, Stream pdbStream) /// public Stream PDBStream { get; } - /// + /// [SuppressMessage( "Design", "CA1031:Do not catch general exception types", @@ -208,7 +210,8 @@ public StreamLoader(DebugInformationManager parent, Stream pdbStream) "of an invalid/incompatible/broken PDB file.")] public bool Load( Assembly assembly, - out AssemblyDebugInformation assemblyDebugInformation) + [NotNullWhen(true)] + out AssemblyDebugInformation? assemblyDebugInformation) { try { @@ -268,7 +271,7 @@ public DebugInformationManager() /// True, if the debug information could be loaded. public bool TryLoadSymbols( Assembly assembly, - out AssemblyDebugInformation assemblyDebugInformation) => + [NotNullWhen(true)] out AssemblyDebugInformation? assemblyDebugInformation) => TryLoadSymbolsInternal( assembly, new AutoFileLoader(this), @@ -287,7 +290,7 @@ public bool TryLoadSymbols( public bool TryLoadSymbols( Assembly assembly, string pdbFileName, - out AssemblyDebugInformation assemblyDebugInformation) + [NotNullWhen(true)] out AssemblyDebugInformation? assemblyDebugInformation) { if (pdbFileName == null) throw new ArgumentNullException(nameof(pdbFileName)); @@ -312,7 +315,7 @@ public bool TryLoadSymbols( public bool TryLoadSymbols( Assembly assembly, Stream pdbStream, - out AssemblyDebugInformation assemblyDebugInformation) + [NotNullWhen(true)] out AssemblyDebugInformation? assemblyDebugInformation) { if (pdbStream == null) throw new ArgumentNullException(nameof(pdbStream)); @@ -336,7 +339,7 @@ public bool TryLoadSymbols( private bool TryLoadSymbolsInternal( Assembly assembly, in TLoader loader, - out AssemblyDebugInformation assemblyDebugInformation) + [NotNullWhen(true)] out AssemblyDebugInformation? assemblyDebugInformation) where TLoader : struct, ILoader { if (assembly == null) @@ -371,7 +374,9 @@ private bool TryLoadSymbolsInternal( /// The name of the debug-information file. /// The resolved filename (or null). /// True, if the given debug-information file could be found. - public bool TryFindPbdFile(string pdbFileName, out string fileName) + public bool TryFindPbdFile( + string pdbFileName, + [NotNullWhen(true)] out string? fileName) { cacheLock.EnterReadLock(); try @@ -432,7 +437,7 @@ public void RegisterLookupDirectory(string directory) /// True, if debug information could be loaded. public bool TryLoadDebugInformation( MethodBase methodBase, - out MethodDebugInformation methodDebugInformation) + [NotNullWhen(true)] out MethodDebugInformation? methodDebugInformation) { Debug.Assert(methodBase != null, "Invalid method"); methodDebugInformation = null; @@ -458,7 +463,7 @@ public bool TryLoadDebugInformation( public SequencePointEnumerator LoadSequencePoints(MethodBase methodBase) => TryLoadDebugInformation( methodBase, - out MethodDebugInformation methodDebugInformation) + out MethodDebugInformation? methodDebugInformation) ? methodDebugInformation.CreateSequencePointEnumerator() : SequencePointEnumerator.Empty; @@ -479,11 +484,12 @@ public void ClearCache(ClearCacheMode mode) { // Do not dispose system assemblies var assembliesToRemove = new List(assemblies.Count); - foreach (var assembly in assemblies.Keys) + foreach (Assembly assembly in assemblies.Keys) { - if (assembly.FullName.StartsWith( - Context.AssemblyName, - StringComparison.OrdinalIgnoreCase)) + if (assembly.FullName != null && + assembly.FullName.StartsWith( + Context.AssemblyName, + StringComparison.OrdinalIgnoreCase)) { continue; } diff --git a/Src/ILGPU/Frontend/DebugInformation/LocalVariable.cs b/Src/ILGPU/Frontend/DebugInformation/LocalVariable.cs index be2dc6f73..e711cf390 100644 --- a/Src/ILGPU/Frontend/DebugInformation/LocalVariable.cs +++ b/Src/ILGPU/Frontend/DebugInformation/LocalVariable.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: LocalVariable.cs @@ -73,7 +73,7 @@ public LocalVariable(int index, string name) /// /// True, if the given object is equal to the current local variable. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is LocalVariable localVariable && Equals(localVariable); /// diff --git a/Src/ILGPU/Frontend/DebugInformation/MethodScope.cs b/Src/ILGPU/Frontend/DebugInformation/MethodScope.cs index d3de4bdab..61e2a52bf 100644 --- a/Src/ILGPU/Frontend/DebugInformation/MethodScope.cs +++ b/Src/ILGPU/Frontend/DebugInformation/MethodScope.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: MethodScope.cs @@ -21,15 +21,6 @@ namespace ILGPU.Frontend.DebugInformation /// public sealed class MethodScope : IEquatable { - #region Constants - - /// - /// Represents an invalid method scope. - /// - public static readonly MethodScope Invalid; - - #endregion - #region Static /// @@ -121,7 +112,7 @@ public ImmutableArray.Enumerator GetEnumerator() => /// /// The other scope. /// True, if the given scope is equal to the current scope. - public bool Equals(MethodScope other) => + public bool Equals(MethodScope? other) => other != null && StartOffset == other.StartOffset && Length == other.Length; @@ -135,7 +126,7 @@ public bool Equals(MethodScope other) => /// /// The other sequence object. /// True, if the given object is equal to the current scope. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is MethodScope other && Equals(other); /// diff --git a/Src/ILGPU/Frontend/Disassembler.cs b/Src/ILGPU/Frontend/Disassembler.cs index f71592774..107c066f2 100644 --- a/Src/ILGPU/Frontend/Disassembler.cs +++ b/Src/ILGPU/Frontend/Disassembler.cs @@ -62,7 +62,7 @@ public sealed partial class Disassembler : ILocation /// /// The current flags argument. /// - private object flagsArgument; + private object? flagsArgument; /// /// Represents the current list of instructions. @@ -77,7 +77,7 @@ public sealed partial class Disassembler : ILocation /// /// Returns the source location. /// - private readonly CompilationStackLocation compilationStackLocation; + private readonly CompilationStackLocation? compilationStackLocation; /// /// Constructs a new disassembler. @@ -90,22 +90,20 @@ public sealed partial class Disassembler : ILocation public Disassembler( MethodBase methodBase, SequencePointEnumerator sequencePointEnumerator, - CompilationStackLocation compilationStackLocation = null) + CompilationStackLocation? compilationStackLocation = null) { MethodBase = methodBase ?? throw new ArgumentNullException(nameof(methodBase)); MethodGenericArguments = MethodBase is MethodInfo ? MethodBase.GetGenericArguments() : Array.Empty(); - TypeGenericArguments = MethodBase.DeclaringType.GetGenericArguments(); - MethodBody = MethodBase.GetMethodBody(); - if (MethodBody == null) - { - throw new NotSupportedException(string.Format( + TypeGenericArguments = + MethodBase.DeclaringType.AsNotNull().GetGenericArguments(); + MethodBody = MethodBase.GetMethodBody() + ?? throw new NotSupportedException(string.Format( ErrorMessages.NativeMethodNotSupported, MethodBase.Name)); - } - il = MethodBody.GetILAsByteArray(); + il = MethodBody.GetILAsByteArray() ?? Array.Empty(); instructions = ImmutableArray.CreateBuilder(il.Length); debugInformationEnumerator = sequencePointEnumerator; this.compilationStackLocation = compilationStackLocation; @@ -129,7 +127,7 @@ public Disassembler( /// /// Returns the declaring type of the method. /// - public Type DeclaringType => MethodBase.DeclaringType; + public Type DeclaringType => MethodBase.DeclaringType.AsNotNull(); /// /// Returns the associated managed module. @@ -225,7 +223,7 @@ public DisassembledMethod Disassemble() /// The token of the method to be disassembled. private void DisassembleCall(ILInstructionType type, int methodToken) { - var method = ResolveMethod(methodToken); + var method = ResolveMethod(methodToken).AsNotNull(); var popCount = method.GetParameters().Length; var methodInfo = method as MethodInfo; int pushCount = 0; @@ -273,7 +271,7 @@ private void AppendInstruction( ILInstructionType type, ushort popCount, ushort pushCount, - object argument = null) => + object? argument = null) => AppendInstructionWithFlags( type, popCount, @@ -298,7 +296,7 @@ private void AppendInstructionWithFlags( ushort popCount, ushort pushCount, ILInstructionFlags additionalFlags, - object argument = null) => + object? argument = null) => // Merge with current flags instructions.Add(new ILInstruction( instructionOffset, @@ -331,7 +329,7 @@ private Type ResolveType(int token) => /// /// The token of the method to resolve. /// The resolved method. - private MethodBase ResolveMethod(int token) => + private MethodBase? ResolveMethod(int token) => AssociatedModule.ResolveMethod( token, TypeGenericArguments, @@ -343,7 +341,7 @@ private MethodBase ResolveMethod(int token) => /// /// The token of the field to resolve. /// The resolved field. - private FieldInfo ResolveField(int token) => + private FieldInfo? ResolveField(int token) => AssociatedModule.ResolveField( token, TypeGenericArguments, @@ -409,7 +407,7 @@ private Type ReadTypeArg() /// Reads a field reference from the current instruction data. /// /// The decoded field reference. - private FieldInfo ReadFieldArg() + private FieldInfo? ReadFieldArg() { var token = ReadIntArg(); return ResolveField(token); diff --git a/Src/ILGPU/Frontend/ILFrontend.cs b/Src/ILGPU/Frontend/ILFrontend.cs index cb0aa9cbd..657924f98 100644 --- a/Src/ILGPU/Frontend/ILFrontend.cs +++ b/Src/ILGPU/Frontend/ILFrontend.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: ILFrontend.cs @@ -37,7 +37,7 @@ private readonly struct ProcessingEntry public ProcessingEntry( MethodBase method, CompilationStackLocation compilationStackLocation, - CodeGenerationResult result) + CodeGenerationResult? result) { Method = method; CompilationStackLocation = compilationStackLocation; @@ -57,7 +57,7 @@ public ProcessingEntry( /// /// Returns the processing future. /// - public CodeGenerationResult Result { get; } + public CodeGenerationResult? Result { get; } /// /// Returns true if this is an external processing request. @@ -88,7 +88,7 @@ public void SetResult(Method irFunction) private readonly Stack processing = new Stack(1 << 6); - private volatile CodeGenerationPhase codeGenerationPhase; + private volatile CodeGenerationPhase? codeGenerationPhase; /// /// Constructs a new frontend with two threads. @@ -99,7 +99,7 @@ public void SetResult(Method irFunction) /// public ILFrontend( Context context, - DebugInformationManager debugInformationManager) + DebugInformationManager? debugInformationManager) : this(context, debugInformationManager, 2) { } @@ -114,7 +114,7 @@ public ILFrontend( /// The number of threads. public ILFrontend( Context context, - DebugInformationManager debugInformationManager, + DebugInformationManager? debugInformationManager, int numThreads) { if (numThreads < 1) @@ -141,7 +141,7 @@ public ILFrontend( /// /// Returns the associated debug information manager (if any). /// - public DebugInformationManager DebugInformationManager { get; } + public DebugInformationManager? DebugInformationManager { get; } /// /// Returns true if the code generation has failed. @@ -151,7 +151,7 @@ public ILFrontend( /// /// Returns the exception from code generation failure. /// - public Exception LastException { get; private set; } + public Exception? LastException { get; private set; } #endregion @@ -291,7 +291,7 @@ internal void FinishCodeGeneration(CodeGenerationPhase phase) "This code generation phase had nothing to do"); if (phase.HadWorkToDo) driverNotifier.Wait(); - LastException = codeGenerationPhase.FirstException; + LastException = codeGenerationPhase?.FirstException; if (Interlocked.CompareExchange( ref codeGenerationPhase, @@ -335,7 +335,6 @@ public sealed class CodeGenerationResult /// The associated method. internal CodeGenerationResult(MethodBase method) { - Debug.Assert(method != null, "Invalid method"); Method = method; } @@ -347,12 +346,7 @@ internal CodeGenerationResult(MethodBase method) /// /// The associated function result. /// - public Method Result { get; internal set; } - - /// - /// Returns the associated function handle. - /// - public MethodHandle ResultHandle => Result.Handle; + public Method? Result { get; internal set; } /// /// Returns true if this result has a function value. @@ -362,7 +356,7 @@ internal CodeGenerationResult(MethodBase method) /// /// The first exception during code generation, if any. /// - public Exception FirstException { get; internal set; } + public Exception? FirstException { get; internal set; } } @@ -376,7 +370,7 @@ public sealed class CodeGenerationPhase : DisposeBase private volatile bool isFinished; private volatile bool hadWorkToDo; - private volatile Exception firstException; + private volatile Exception? firstException; /// /// Constructs a new generation phase. @@ -412,7 +406,7 @@ internal CodeGenerationPhase( /// /// Returns the associated debug information manager (if any). /// - public DebugInformationManager DebugInformationManager { get; } + public DebugInformationManager? DebugInformationManager { get; } /// /// Returns the associated verifier instance. @@ -432,7 +426,7 @@ internal CodeGenerationPhase( /// /// Returns the first exception recorded during code-generation. /// - public Exception FirstException => firstException; + public Exception? FirstException => firstException; #endregion @@ -455,7 +449,7 @@ internal void GenerateCodeInternal( Dictionary detectedMethods, out Method generatedMethod) { - ILocation location = null; + ILocation? location = null; try { generatedMethod = Context.Declare(method, out bool created); diff --git a/Src/ILGPU/Frontend/ILInstruction.cs b/Src/ILGPU/Frontend/ILInstruction.cs index 6a20ea554..3400d4a47 100644 --- a/Src/ILGPU/Frontend/ILInstruction.cs +++ b/Src/ILGPU/Frontend/ILInstruction.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: ILInstruction.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.IR; +using ILGPU.Util; using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; @@ -515,7 +516,7 @@ public struct ILInstructionFlagsContext : IEquatable /// The flags argument. public ILInstructionFlagsContext( ILInstructionFlags flags, - object argument) + object? argument) { Flags = flags; Argument = argument; @@ -533,7 +534,7 @@ public ILInstructionFlagsContext( /// /// Returns the flag argument. /// - public object Argument { get; } + public object? Argument { get; } #endregion @@ -556,7 +557,7 @@ public bool Equals(ILInstructionFlagsContext other) => /// /// The other object. /// True, if the current object is equal to the given one. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is ILInstructionFlagsContext context && context == this; /// @@ -595,15 +596,9 @@ public override string ToString() => ILInstructionFlagsContext first, ILInstructionFlagsContext second) { - if (first.Flags != second.Flags || - first.Argument == null && second.Argument != null || - first.Argument != null && second.Argument == null) - { + if (first.Flags != second.Flags) return false; - } - return - first.Argument == null && second.Argument == null || - first.Argument.Equals(second.Argument); + return Equals(first.Argument, second.Argument); } /// @@ -663,7 +658,7 @@ public ILInstruction( ILInstructionFlagsContext flagsContext, ushort popCount, ushort pushCount, - object argument, + object? argument, Location location) { Offset = offset; @@ -714,7 +709,7 @@ public ILInstruction( /// /// Returns the instruction argument. /// - public object Argument { get; } + public object? Argument { get; } /// /// Returns true if the instruction is a call instruction. @@ -759,7 +754,7 @@ public bool IsCall /// /// The target type T. /// The instruction argument T. - public T GetArgumentAs() => (T)Argument; + public T GetArgumentAs() => (T)Argument.AsNotNull(); /// /// Returns true if current instruction has the given flags. @@ -817,21 +812,15 @@ public void ForEachOffset(TOperation operation) "Style", "IDE0046:Convert to conditional expression", Justification = "Avoid nested if conditionals")] - public bool Equals(ILInstruction other) + public bool Equals(ILInstruction? other) { if (other == null) return false; if (InstructionType != other.InstructionType || - FlagsContext != other.FlagsContext || - Argument == null && other.Argument != null || - Argument != null && other.Argument == null) - { + FlagsContext != other.FlagsContext) return false; - } - return - Argument == null && other.Argument == null || - Argument.Equals(other.Argument); + return Equals(Argument, other.Argument); } #endregion @@ -843,7 +832,7 @@ public bool Equals(ILInstruction other) /// /// The other object. /// True, if the current object is equal to the given one. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is ILInstruction otherObj && otherObj == this; /// diff --git a/Src/ILGPU/Frontend/Intrinsic/ArrayIntrinsics.cs b/Src/ILGPU/Frontend/Intrinsic/ArrayIntrinsics.cs index 3a4560643..e5088e4c0 100644 --- a/Src/ILGPU/Frontend/Intrinsic/ArrayIntrinsics.cs +++ b/Src/ILGPU/Frontend/Intrinsic/ArrayIntrinsics.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: ArrayIntrinsics.cs @@ -12,6 +12,7 @@ using ILGPU.IR; using ILGPU.IR.Values; using ILGPU.Resources; +using ILGPU.Util; using System; namespace ILGPU.Frontend.Intrinsic @@ -78,7 +79,8 @@ private static ValueReference CreateNewArray(ref InvocationContext context) } // Create an array view type of the appropriate dimension - var managedElementType = context.Method.DeclaringType.GetElementType(); + var managedElementType = + context.Method.DeclaringType.AsNotNull().GetElementType().AsNotNull(); var elementType = builder.CreateType(managedElementType); var arrayType = builder.CreateArrayType(elementType, dimension); diff --git a/Src/ILGPU/Frontend/Intrinsic/InteropIntrinsics.cs b/Src/ILGPU/Frontend/Intrinsic/InteropIntrinsics.cs index b4e07b99c..93d48536d 100644 --- a/Src/ILGPU/Frontend/Intrinsic/InteropIntrinsics.cs +++ b/Src/ILGPU/Frontend/Intrinsic/InteropIntrinsics.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: InteropIntrinsics.cs @@ -90,7 +90,7 @@ private static ValueReference CreateOffsetOf(ref InvocationContext context) var builder = context.Builder; var typeInfo = builder.TypeContext.GetTypeInfo( context.GetMethodGenericArguments()[0]); - var fieldName = context[0].ResolveAs(); + var fieldName = context[0].ResolveAs().AsNotNull(); int fieldIndex = 0; foreach (var field in typeInfo.Fields) { diff --git a/Src/ILGPU/Frontend/Intrinsic/Intrinsics.cs b/Src/ILGPU/Frontend/Intrinsic/Intrinsics.cs index 3d31e7453..d3f2e91eb 100644 --- a/Src/ILGPU/Frontend/Intrinsic/Intrinsics.cs +++ b/Src/ILGPU/Frontend/Intrinsic/Intrinsics.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Intrinsics.cs @@ -94,49 +94,64 @@ private static readonly DeviceFunctionHandler[] { (ref InvocationContext context, IntrinsicAttribute attribute) => HandleAcceleratorOperation( - ref context, attribute as AcceleratorIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleAtomicOperation( - ref context, attribute as AtomicIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleCompareOperation( - ref context, attribute as CompareIntriniscAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleConvertOperation( - ref context, attribute as ConvertIntriniscAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleGridOperation( - ref context, attribute as GridIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleGroupOperation( - ref context, attribute as GroupIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleInterop( - ref context, attribute as InteropIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleMathOperation( - ref context, attribute as MathIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleMemoryBarrierOperation( - ref context, attribute as MemoryBarrierIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleSharedMemoryOperation( - ref context, attribute as SharedMemoryIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleLocalMemoryOperation( - ref context, attribute as LocalMemoryIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleViewOperation( - ref context, attribute as ViewIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleWarpOperation( - ref context, attribute as WarpIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleUtilityOperation( - ref context, attribute as UtilityIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), (ref InvocationContext context, IntrinsicAttribute attribute) => HandleLanguageOperation( - ref context, attribute as LanguageIntrinsicAttribute), + ref context, + attribute.AsNotNullCast()), }; #endregion @@ -163,15 +178,15 @@ public static bool HandleIntrinsic( if (intrinsic != null) result = IntrinsicHandlers[(int)intrinsic.Type](ref context, intrinsic); - if (IsIntrinsicArrayType(method.DeclaringType)) + if (IsIntrinsicArrayType(method.DeclaringType.AsNotNull())) { result = HandleArrays(ref context); // All array operations will be handled by the ILGPU intrinsic handlers return true; } else if (FunctionHandlers.TryGetValue( - method.DeclaringType, - out DeviceFunctionHandler handler)) + method.DeclaringType.AsNotNull(), + out DeviceFunctionHandler? handler)) { result = handler(ref context); } @@ -265,8 +280,8 @@ private static unsafe void InitializeArray(ref InvocationContext context) var location = context.Location; // Resolve the array data - var handle = context[1].ResolveAs(); - var value = handle.GetHandle().GetValue(null); + var handle = context[1].ResolveAs().AsNotNull(); + var value = handle.GetHandle().GetValue(null).AsNotNull(); int valueSize = Marshal.SizeOf(value); // Load the associated array data @@ -284,7 +299,8 @@ private static unsafe void InitializeArray(ref InvocationContext context) for (int i = 0, e = valueSize / elementSize; i < e; ++i) { byte* address = data + elementSize * i; - var instance = Marshal.PtrToStructure(new IntPtr(address), elementType); + var instance = + Marshal.PtrToStructure(new IntPtr(address), elementType).AsNotNull(); // Convert element to IR value var irValue = builder.CreateValue(location, instance, elementType); diff --git a/Src/ILGPU/Frontend/Intrinsic/SharedMemoryIntrinsics.cs b/Src/ILGPU/Frontend/Intrinsic/SharedMemoryIntrinsics.cs index bf332953e..0759ebb2c 100644 --- a/Src/ILGPU/Frontend/Intrinsic/SharedMemoryIntrinsics.cs +++ b/Src/ILGPU/Frontend/Intrinsic/SharedMemoryIntrinsics.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: SharedMemoryIntrinsics.cs @@ -12,6 +12,7 @@ using ILGPU.IR; using ILGPU.IR.Values; using ILGPU.Resources; +using ILGPU.Util; using System; namespace ILGPU.Frontend.Intrinsic @@ -79,7 +80,9 @@ private static ValueReference HandleSharedMemoryOperation( var alloca = builder.CreateDynamicAllocaArray( location, allocationType, - MemoryAddressSpace.Shared).ResolveAs(); + MemoryAddressSpace.Shared) + .ResolveAs() + .AsNotNull(); return builder.CreateNewView( location, alloca, diff --git a/Src/ILGPU/Frontend/Intrinsic/ViewIntrinsics.cs b/Src/ILGPU/Frontend/Intrinsic/ViewIntrinsics.cs index 62fe83045..60cf51a13 100644 --- a/Src/ILGPU/Frontend/Intrinsic/ViewIntrinsics.cs +++ b/Src/ILGPU/Frontend/Intrinsic/ViewIntrinsics.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: ViewIntrinsics.cs @@ -13,6 +13,7 @@ using ILGPU.IR.Types; using ILGPU.IR.Values; using ILGPU.Resources; +using ILGPU.Util; using System; namespace ILGPU.Frontend.Intrinsic @@ -87,7 +88,7 @@ private static ValueReference HandleViewOperation( builder.CreateGetViewLongLength(location, instanceValue), builder.CreateLongSizeOf( location, - (instanceValue.Type as AddressSpaceType).ElementType), + instanceValue.Type.AsNotNullCast().ElementType), BinaryArithmeticKind.Mul), ViewIntrinsicKind.GetSubView => builder.CreateSubViewValue( location, diff --git a/Src/ILGPU/Frontend/InvocationContext.cs b/Src/ILGPU/Frontend/InvocationContext.cs index 68047eeab..a55ecb975 100644 --- a/Src/ILGPU/Frontend/InvocationContext.cs +++ b/Src/ILGPU/Frontend/InvocationContext.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: InvocationContext.cs @@ -13,6 +13,7 @@ using ILGPU.IR.Construction; using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; using System; using System.Reflection; using System.Runtime.CompilerServices; @@ -153,7 +154,7 @@ public string FormatErrorMessage(string message) => /// /// The generic arguments of the used method. public Type[] GetTypeGenericArguments() => - Method.DeclaringType.GetGenericArguments(); + Method.DeclaringType.AsNotNull().GetGenericArguments(); /// /// Declares a (potentially new) method. diff --git a/Src/ILGPU/Frontend/VariableRef.cs b/Src/ILGPU/Frontend/VariableRef.cs index 9f51d6116..a13d2fd55 100644 --- a/Src/ILGPU/Frontend/VariableRef.cs +++ b/Src/ILGPU/Frontend/VariableRef.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: VariableRef.cs @@ -107,7 +107,7 @@ public VariableRef(int index, VariableRefType refType) /// /// True, if the given variable ref is equal to the current one. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is VariableRef variableRef && variableRef == this; /// diff --git a/Src/ILGPU/Half.cs b/Src/ILGPU/Half.cs index f3a717901..3ba3b695f 100644 --- a/Src/ILGPU/Half.cs +++ b/Src/ILGPU/Half.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2022 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: Half.cs @@ -145,7 +145,7 @@ internal Half(ushort rawValue) /// /// The other object. /// True, if the given object is equal to the current half. - public readonly override bool Equals(object obj) => + public readonly override bool Equals(object? obj) => obj is Half half && Equals(half); /// diff --git a/Src/ILGPU/IIndex.cs b/Src/ILGPU/IIndex.cs index 3e8554b53..1364a736b 100644 --- a/Src/ILGPU/IIndex.cs +++ b/Src/ILGPU/IIndex.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2022 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: IIndex.cs @@ -92,7 +92,7 @@ public static class IndexTypeExtensions /// /// An internal mapping of the values to managed types. /// - private static readonly Type[] ManagedIndexTypes = + private static readonly Type?[] ManagedIndexTypes = { null, typeof(Index1D), diff --git a/Src/ILGPU/ILGPU.csproj b/Src/ILGPU/ILGPU.csproj index 11ab96c71..c294e2dbb 100644 --- a/Src/ILGPU/ILGPU.csproj +++ b/Src/ILGPU/ILGPU.csproj @@ -10,6 +10,14 @@ $(LibraryFileVersion) + + + enable + + + $(NoWarn);nullable + + true en-US diff --git a/Src/ILGPU/IR/Analyses/Allocas.cs b/Src/ILGPU/IR/Analyses/Allocas.cs index 15caa338d..3b410252a 100644 --- a/Src/ILGPU/IR/Analyses/Allocas.cs +++ b/Src/ILGPU/IR/Analyses/Allocas.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Allocas.cs @@ -273,13 +273,13 @@ private static void AddAllocation( Alloca alloca, ImmutableArray.Builder builder, ref int memorySize, - ImmutableArray.Builder dynamicBuilder = null) + ImmutableArray.Builder? dynamicBuilder = null) { var info = new AllocaInformation(builder.Count, alloca); if (info.IsDynamicArray) { - alloca.AssertNotNull(dynamicBuilder); - dynamicBuilder.Add(info); + alloca.AssertNotNull(dynamicBuilder.AsNotNull()); + dynamicBuilder.AsNotNull().Add(info); } else { @@ -358,13 +358,13 @@ public static int GetAllocaTypeAlignment(TypeNode type) => /// The value to get the type information for. /// The type, if the value is supported, null otherwise. [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static TypeNode TryGetAnalysisType(Value value) => + private static TypeNode? TryGetAnalysisType(Value value) => value switch { PhiValue phiValue => phiValue.Type, PointerCast cast => cast.TargetElementType, AddressSpaceCast cast => - (cast.TargetType as AddressSpaceType).ElementType, + cast.TargetType.AsNotNullCast().ElementType, NewView newView => newView.ViewElementType, ViewCast cast => cast.TargetElementType, SubViewValue subView => subView.ElementType, @@ -427,7 +427,7 @@ public readonly int ComputeAllocaAlignment(Alloca alloca) while (toProcess.Count > 0) { var current = toProcess.Pop(); - TypeNode type; + TypeNode? type; // Check whether we have already seen this value if (!visited.Add(current)) diff --git a/Src/ILGPU/IR/Analyses/AnalysisValue.cs b/Src/ILGPU/IR/Analyses/AnalysisValue.cs index f8a79f2b4..07d6909de 100644 --- a/Src/ILGPU/IR/Analyses/AnalysisValue.cs +++ b/Src/ILGPU/IR/Analyses/AnalysisValue.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: AnalysisValue.cs @@ -180,7 +180,7 @@ public readonly bool Equals(AnalysisValue other) /// /// The other object. /// True, if the given object is equal to the current value. - public readonly override bool Equals(object obj) => + public readonly override bool Equals(object? obj) => obj is AnalysisValue value && Equals(value); /// @@ -193,7 +193,7 @@ public readonly override bool Equals(object obj) => /// Returns the string representation of this value. /// /// The string representation of this value. - public readonly override string ToString() => + public readonly override string? ToString() => childData.Length > 0 ? $"{Data} [{string.Join(", ", childData)}]" : Data.ToString(); diff --git a/Src/ILGPU/IR/Analyses/Dominators.cs b/Src/ILGPU/IR/Analyses/Dominators.cs index d8ca2eb3f..951ba9837 100644 --- a/Src/ILGPU/IR/Analyses/Dominators.cs +++ b/Src/ILGPU/IR/Analyses/Dominators.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Dominators.cs @@ -224,7 +224,7 @@ public BasicBlock GetImmediateCommonDominator(ReadOnlySpan blocks) private BasicBlock GetPhiParent(BasicBlock dominatorBlock, UseCollection uses) { // Check for phi-value references - BasicBlock phiParent = null; + BasicBlock? phiParent = null; foreach (Use use in uses) { if (!(use.Resolve() is PhiValue phiValue)) diff --git a/Src/ILGPU/IR/Analyses/FixPointAnalysis.cs b/Src/ILGPU/IR/Analyses/FixPointAnalysis.cs index 45d722c22..3c68d71f0 100644 --- a/Src/ILGPU/IR/Analyses/FixPointAnalysis.cs +++ b/Src/ILGPU/IR/Analyses/FixPointAnalysis.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2022 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: FixPointAnalysis.cs @@ -13,10 +13,12 @@ using ILGPU.IR.Analyses.TraversalOrders; using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace ILGPU.IR.Analyses @@ -81,7 +83,7 @@ protected BaseAnalysisContext(BasicBlockSet onStack) /// The popped block (if any). /// True, if a value could be popped from the stack. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryPop(out BasicBlock block) + public bool TryPop([NotNullWhen(true)] out BasicBlock? block) { block = null; if (Stack.Count < 1) @@ -353,7 +355,10 @@ protected ValueFixPointAnalysis(T defaultValue) protected override bool Update(Value node, TContext context) { var oldValue = context[node]; - var newValue = Merge(oldValue, node, context as ValueAnalysisContext); + var newValue = Merge( + oldValue, + node, + context.AsNotNullCast()); context[node] = newValue; return oldValue != newValue; } @@ -446,8 +451,11 @@ protected override AnalysisValue CreateData(Method method) => valueMapping[value] = CreateData(value); } // Register terminators - if (!valueMapping.ContainsKey(block.Terminator)) - valueMapping[block.Terminator] = CreateData(block.Terminator); + if (!valueMapping.ContainsKey(block.Terminator.AsNotNull())) + { + valueMapping[block.Terminator.AsNotNull()] = + CreateData(block.Terminator.AsNotNull()); + } } // Create the analysis context and perform the analysis @@ -856,7 +864,9 @@ public readonly bool TryGetReturnData( /// The result data (if any). /// True, if return data could be determined. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly bool TryGetData(Method method, out TMethodData result) + public readonly bool TryGetData( + Method method, + [MaybeNullWhen(false)] out TMethodData? result) { result = default; return Mapping?.TryGetValue(method, out result) ?? false; @@ -949,7 +959,7 @@ public readonly bool Equals(GlobalAnalysisEntry other) /// /// True, if the given object is equal to the current entry. /// - public readonly override bool Equals(object obj) => + public readonly override bool Equals(object? obj) => obj is GlobalAnalysisEntry entry && Equals(entry); /// diff --git a/Src/ILGPU/IR/Analyses/Landscape.cs b/Src/ILGPU/IR/Analyses/Landscape.cs index 1d9b6b906..1d76439f1 100644 --- a/Src/ILGPU/IR/Analyses/Landscape.cs +++ b/Src/ILGPU/IR/Analyses/Landscape.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Landscape.cs @@ -9,10 +9,12 @@ // Source License. See LICENSE.txt for details. // --------------------------------------------------------------------------------------- +using ILGPU.Util; using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; namespace ILGPU.IR.Analyses @@ -38,9 +40,9 @@ public sealed class Entry (first, second) => first.Method.Id.CompareTo(second.Method.Id); private readonly HashSet usesSet = new HashSet(); - private List uses; + private List? uses; - internal Entry(Method method, References references, in T data) + internal Entry(Method method, References references, in T? data) { method.AssertNotNull(method); @@ -57,7 +59,7 @@ internal Entry(Method method, References references, in T data) /// /// Returns custom information. /// - public T Data { get; } + public T? Data { get; } /// /// Returns the number of basic block. @@ -67,7 +69,7 @@ internal Entry(Method method, References references, in T data) /// /// Returns the number of uses. /// - public int NumUses => uses.Count; + public int NumUses => usesSet.Count; /// /// Returns true if this function has references. @@ -110,7 +112,8 @@ internal void FinishUses() /// /// An enumerator to enumerate all depending method entries. /// - internal List.Enumerator GetEnumerator() => uses.GetEnumerator(); + internal List.Enumerator GetEnumerator() => + uses.AsNotNull().GetEnumerator(); /// /// Returns the string representation of this entry. @@ -132,7 +135,7 @@ public interface IDataProvider /// All references to other methods. /// /// The resolved custom data. - T GetData(Method method, References methodReferences); + T? GetData(Method method, References methodReferences); } /// @@ -233,7 +236,7 @@ protected Landscape() { } /// The source method. /// The resolved landscape entry. public Entry this[Method method] => - TryGetEntry(method, out Entry entry) + TryGetEntry(method, out Entry? entry) ? entry : throw new KeyNotFoundException(); @@ -252,7 +255,7 @@ protected Landscape() { } /// The method. /// The resolved entry. /// True, if the entry could be resolved. - public bool TryGetEntry(Method method, out Entry entry) => + public bool TryGetEntry(Method method, [NotNullWhen(true)] out Entry? entry) => entries.TryGetValue(method, out entry); /// @@ -283,7 +286,7 @@ protected void Init( { foreach (var reference in entry.References) { - if (entries.TryGetValue(reference, out Entry referenceEntry)) + if (entries.TryGetValue(reference, out Entry? referenceEntry)) referenceEntry.AddUse(entry.Method); } } @@ -381,7 +384,7 @@ public sealed class Landscape : Landscape private readonly struct DataProvider : IDataProvider { /// - public object GetData(Method method, References references) => null; + public object? GetData(Method method, References references) => null; } #endregion diff --git a/Src/ILGPU/IR/Analyses/LoopInfo.cs b/Src/ILGPU/IR/Analyses/LoopInfo.cs index 5be074c08..793436f59 100644 --- a/Src/ILGPU/IR/Analyses/LoopInfo.cs +++ b/Src/ILGPU/IR/Analyses/LoopInfo.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2022 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: LoopInfo.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using static ILGPU.Util.InlineList; @@ -157,7 +158,7 @@ public static LoopInfo Create( /// True, if the resulting loop info object could be resolved. public static bool TryCreate( Loops.Node loop, - out LoopInfo loopInfo) + [NotNullWhen(true)] out LoopInfo? loopInfo) { loopInfo = default; @@ -195,7 +196,7 @@ public static bool TryCreate( /// True, if the given loop body could be resolved. private static bool TryGetLoopBody( Loops.Node loop, - out BasicBlock body, + [NotNullWhen(true)] out BasicBlock? body, out bool isDoWhileLoop) { body = null; @@ -324,8 +325,8 @@ private static bool TryGetPhis( private static bool TryGetPhiOperands( Loops.Node loop, PhiValue phiValue, - out Value insideOperand, - out Value outsideOperand) + [NotNullWhen(true)] out Value? insideOperand, + [NotNullWhen(true)] out Value? outsideOperand) { insideOperand = null; outsideOperand = null; @@ -355,7 +356,9 @@ private static bool TryGetPhiOperands( /// The value to test. /// The resolved induction-variable phi (if any).. /// True, if the given node is an induction-variable branch. - private static bool IsInductionVariable(Value value, out PhiValue phiValue) + private static bool IsInductionVariable( + Value value, + [NotNullWhen(true)] out PhiValue? phiValue) { phiValue = null; if (!(value is CompareValue compareValue)) @@ -632,7 +635,7 @@ private LoopInfos(Loops loops) /// True, if a loop information instance could be found. public readonly bool TryGetInfo( Loops.Node loop, - out LoopInfo value) => + [NotNullWhen(true)] out LoopInfo? value) => mapping.TryGetValue(loop, out value); #endregion @@ -654,7 +657,7 @@ public static class LoopInfos /// The created loop analysis. public static bool TryGetLoopInfo( this Loops.Node loop, - out LoopInfo loopInfo) + [NotNullWhen(true)] out LoopInfo? loopInfo) where TOrder : struct, ITraversalOrder where TDirection : struct, IControlFlowDirection => LoopInfo.TryCreate(loop, out loopInfo); diff --git a/Src/ILGPU/IR/Analyses/Loops.cs b/Src/ILGPU/IR/Analyses/Loops.cs index 101436452..89cf2b932 100644 --- a/Src/ILGPU/IR/Analyses/Loops.cs +++ b/Src/ILGPU/IR/Analyses/Loops.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: Loops.cs @@ -18,6 +18,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; // @@ -170,7 +171,7 @@ public sealed class Node /// All entry block that jump into this loop. /// All exit block that this loop can jump to. internal Node( - Node parent, + Node? parent, ref InlineList headerBlocks, ref InlineList breakerBlocks, ref InlineList backEdgeBlocks, @@ -227,7 +228,7 @@ internal Node( /// /// Returns the parent loop. /// - public Node Parent { get; } + public Node? Parent { get; } /// /// Returns all child loops. @@ -706,7 +707,7 @@ private Loops(CFG cfg) /// The current index value. private void StrongConnect( List stack, - Node parent, + Node? parent, ref BasicBlockMap nodeMapping, NodeData v, ref int index) @@ -756,7 +757,7 @@ private void StrongConnect( /// The current node. private void RegisterLoop( List stack, - Node parent, + Node? parent, ref BasicBlockMap nodeMapping, NodeData v) { @@ -851,7 +852,7 @@ private void RegisterLoop( /// The block to map to a loop. /// The resulting loop. /// True, if the node could be resolved to a loop. - public bool TryGetLoops(BasicBlock block, out Node loop) => + public bool TryGetLoops(BasicBlock block, [NotNullWhen(true)] out Node? loop) => loopMapping.TryGetValue(block, out loop); /// diff --git a/Src/ILGPU/IR/Analyses/Movement.cs b/Src/ILGPU/IR/Analyses/Movement.cs index 19948e744..95c1e55ac 100644 --- a/Src/ILGPU/IR/Analyses/Movement.cs +++ b/Src/ILGPU/IR/Analyses/Movement.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2022 ILGPU Project +// Copyright (c) 2022-2023 ILGPU Project // www.ilgpu.net // // File: Movement.cs @@ -9,17 +9,17 @@ // Source License. See LICENSE.txt for details. // --------------------------------------------------------------------------------------- +using ILGPU.IR.Analyses.ControlFlowDirection; +using ILGPU.IR.Analyses.TraversalOrders; using ILGPU.IR.Values; +using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using PreDominators = ILGPU.IR.Analyses.Dominators< - ILGPU.IR.Analyses.ControlFlowDirection.Forwards>; +using System.Runtime.CompilerServices; using PostDominators = ILGPU.IR.Analyses.Dominators< ILGPU.IR.Analyses.ControlFlowDirection.Backwards>; -using System; -using ILGPU.IR.Analyses.TraversalOrders; -using ILGPU.IR.Analyses.ControlFlowDirection; -using System.Runtime.CompilerServices; +using PreDominators = ILGPU.IR.Analyses.Dominators< + ILGPU.IR.Analyses.ControlFlowDirection.Forwards>; namespace ILGPU.IR.Analyses { diff --git a/Src/ILGPU/IR/Analyses/PointerAddressSpaces.cs b/Src/ILGPU/IR/Analyses/PointerAddressSpaces.cs index d81595e97..a03983c1f 100644 --- a/Src/ILGPU/IR/Analyses/PointerAddressSpaces.cs +++ b/Src/ILGPU/IR/Analyses/PointerAddressSpaces.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: PointerAddressSpaces.cs @@ -160,7 +160,7 @@ public static AddressSpaceInfo FromType(TypeNode type) return addressSpaceType.AddressSpace; // Unify all address space flags from each dependent field - var structureType = type as StructureType; + var structureType = type.AsNotNullCast(); var result = new AddressSpaceInfo(); foreach (var (fieldType, _) in structureType) result = Merge(result, FromType(fieldType)); @@ -302,7 +302,7 @@ public readonly bool Equals(AddressSpaceInfo other) => /// /// True, if the given object is equal to the current instance. /// - public override readonly bool Equals(object obj) => + public override readonly bool Equals(object? obj) => obj is AddressSpaceInfo info && Equals(info); /// diff --git a/Src/ILGPU/IR/Analyses/PointerAlignments.cs b/Src/ILGPU/IR/Analyses/PointerAlignments.cs index e305065d1..67cd36352 100644 --- a/Src/ILGPU/IR/Analyses/PointerAlignments.cs +++ b/Src/ILGPU/IR/Analyses/PointerAlignments.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: PointerAlignments.cs @@ -360,7 +360,7 @@ private static AnalysisValue MergeLoadElementAddress( int baseAlignment = context[lea.Source].Data; // Determine the alignment of the referenced element type (used for indexing) - var elementType = (lea.Type as AddressSpaceType).ElementType; + var elementType = lea.Type.AsNotNullCast().ElementType; int typeAlignment = AllocaAlignments.GetAllocaTypeAlignment(elementType); // Check whether we have found a power of 2 != 0 diff --git a/Src/ILGPU/IR/Analyses/Uniforms.cs b/Src/ILGPU/IR/Analyses/Uniforms.cs index 6c38e29bd..27b0fa434 100644 --- a/Src/ILGPU/IR/Analyses/Uniforms.cs +++ b/Src/ILGPU/IR/Analyses/Uniforms.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2022 ILGPU Project +// Copyright (c) 2022-2023 ILGPU Project // www.ilgpu.net // // File: Uniforms.cs @@ -88,7 +88,7 @@ public bool Equals(ValueInfo other) => /// /// True, if the given object is equal to the current instance. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is ValueInfo other && Equals(other); /// diff --git a/Src/ILGPU/IR/BasicBlock.cs b/Src/ILGPU/IR/BasicBlock.cs index c33d80397..c02d7fc84 100644 --- a/Src/ILGPU/IR/BasicBlock.cs +++ b/Src/ILGPU/IR/BasicBlock.cs @@ -58,7 +58,7 @@ readonly string InlineList.IFormatter.Format(BasicBlock item) => /// Returns true if both blocks represent the same block. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public readonly bool Equals(BasicBlock x, BasicBlock y) => + public readonly bool Equals(BasicBlock? x, BasicBlock? y) => x == y; /// @@ -257,7 +257,7 @@ void IDisposable.Dispose() { } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public ReadOnlySpan GetSuccessors(BasicBlock basicBlock) => - basicBlock.Terminator.Targets; + basicBlock.CurrentSuccessors; } /// @@ -290,7 +290,7 @@ public ReadOnlySpan GetSuccessors(BasicBlock basicBlock) => private List values = new List(); [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private Builder builder = null; + private Builder? builder = null; /// /// Constructs a new basic block. @@ -298,7 +298,7 @@ public ReadOnlySpan GetSuccessors(BasicBlock basicBlock) => /// The parent method. /// The current location. /// The name of the block (or null). - internal BasicBlock(Method method, Location location, string name) + internal BasicBlock(Method method, Location location, string? name) : base(location) { Method = method; @@ -338,7 +338,7 @@ internal BasicBlock(Method method, Location location, string name) /// /// Returns the current terminator. /// - public TerminatorValue Terminator { get; private set; } + public TerminatorValue? Terminator { get; private set; } /// /// The current list of successor blocks. @@ -436,7 +436,7 @@ internal void BeginControlFlowUpdate(int index) [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void PropagateSuccessors() { - foreach (var successor in Terminator.Targets) + foreach (var successor in CurrentSuccessors) { successors.Add(successor); successor.predecessors.Add(this); @@ -468,7 +468,7 @@ public T GetTerminatorAs() where T : TerminatorValue { this.Assert(Terminator is T); - return Terminator as T; + return Terminator.AsNotNullCast(); } /// @@ -482,9 +482,11 @@ internal bool GetOrCreateBuilder( Method.Builder functionBuilder, out Builder resolvedBuilder) { - resolvedBuilder = builder; - if (resolvedBuilder != null) + if (builder != null) + { + resolvedBuilder = builder; return false; + } this.AssertNotNull(functionBuilder); this.Assert(functionBuilder.Method == Method); resolvedBuilder = builder = new Builder(functionBuilder, this); @@ -500,7 +502,7 @@ internal void ReleaseBuilder(Builder otherBuilder) { this.AssertNotNull(otherBuilder); this.Assert(otherBuilder == builder); - this.AssertNotNull(Terminator); + this.AssertNotNull(Terminator.AsNotNull()); builder = null; } @@ -508,7 +510,7 @@ internal void ReleaseBuilder(Builder otherBuilder) /// Compacts the terminator. /// /// - private TerminatorValue CompactTerminator() => + private TerminatorValue? CompactTerminator() => Terminator = Terminator?.ResolveAs(); /// @@ -527,7 +529,7 @@ public override void Dump(TextWriter textWriter) textWriter.WriteLine(value.ToString()); } textWriter.Write("\t"); - textWriter.WriteLine(Terminator.ToString()); + textWriter.WriteLine(Terminator?.ToString()); } /// @@ -537,7 +539,7 @@ public override void Dump(TextWriter textWriter) internal void GC() { var newTerminator = CompactTerminator(); - newTerminator.GC(); + newTerminator?.GC(); var newValues = new List(Count); foreach (Value value in values) diff --git a/Src/ILGPU/IR/BasicBlockCollection.cs b/Src/ILGPU/IR/BasicBlockCollection.cs index 29c4e842e..b0737f0a4 100644 --- a/Src/ILGPU/IR/BasicBlockCollection.cs +++ b/Src/ILGPU/IR/BasicBlockCollection.cs @@ -248,7 +248,7 @@ public BasicBlockCollection( [Conditional("DEBUG")] public void AssertUniqueExitBlock() { - BasicBlock exitBlock = null; + BasicBlock? exitBlock = null; // Traverse all blocks to find a block without a successor foreach (var block in this) @@ -279,7 +279,7 @@ public BasicBlock FindExitBlock() // Unreachable EntryBlock.Assert(false); - return null; + return Utilities.InitNotNullable(); } /// @@ -294,7 +294,7 @@ public readonly void ForEachTerminator( { foreach (var block in this) { - if (block.Terminator.Resolve() is TTerminatorValue terminator) + if (block.Terminator?.Resolve() is TTerminatorValue terminator) visitor(terminator); } } diff --git a/Src/ILGPU/IR/BasicBlockMapping.cs b/Src/ILGPU/IR/BasicBlockMapping.cs index d6ffa9897..d34e5ce0f 100644 --- a/Src/ILGPU/IR/BasicBlockMapping.cs +++ b/Src/ILGPU/IR/BasicBlockMapping.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2022 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: BasicBlockMapping.cs @@ -640,7 +640,7 @@ public bool TryAdd(BasicBlock block, T value) /// The stored value (if any). /// True, if the block could be found. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryGetValue(BasicBlock block, out T value) + public bool TryGetValue(BasicBlock block, [NotNullWhen(true)] out T? value) { value = default; int index = block.BlockIndex; @@ -745,6 +745,7 @@ partial struct BasicBlockSet private HashSet blockSet; /// + [MemberNotNull(nameof(blockSet))] partial void InitBlockSet() => blockSet = new HashSet(); #endregion @@ -783,6 +784,7 @@ partial struct BasicBlockMap private Dictionary blockMap; /// + [MemberNotNull(nameof(blockMap))] partial void InitBlockMap() => blockMap = new Dictionary(); #endregion @@ -808,7 +810,7 @@ readonly partial void AssertContained( bool found = blockMap.TryGetValue(block, out var storedValue); EntryBlock.Assert(contained == found); if (contained) - EntryBlock.Assert(value.Equals(storedValue)); + EntryBlock.Assert(Equals(value, storedValue)); } /// diff --git a/Src/ILGPU/IR/Construction/Arithmetic.cs b/Src/ILGPU/IR/Construction/Arithmetic.cs index 47557639e..103445227 100644 --- a/Src/ILGPU/IR/Construction/Arithmetic.cs +++ b/Src/ILGPU/IR/Construction/Arithmetic.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Arithmetic.cs @@ -152,7 +152,7 @@ public ValueReference CreateArithmetic( { VerifyBinaryArithmeticOperands(location, left, right, kind); - Value simplified; + Value? simplified; if (right is PrimitiveValue rightValue) { // Check for constants diff --git a/Src/ILGPU/IR/Construction/ArithmeticOperations.tt b/Src/ILGPU/IR/Construction/ArithmeticOperations.tt index 97fd63b9d..e812ca2e5 100644 --- a/Src/ILGPU/IR/Construction/ArithmeticOperations.tt +++ b/Src/ILGPU/IR/Construction/ArithmeticOperations.tt @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2016-2022 ILGPU Project +// Copyright (c) 2016-2023 ILGPU Project // www.ilgpu.net // // File: ArithmeticOperations.tt/ArithmeticOperations.cs @@ -127,7 +127,7 @@ namespace ILGPU.IR.Construction <# } #> [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Value UnaryArithmeticSimplify( + private Value? UnaryArithmeticSimplify( Location location, Value value, UnaryArithmeticKind kind, @@ -199,7 +199,7 @@ namespace ILGPU.IR.Construction /// Simplifies the <#= settings.Name #> of a binary expression. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Value BinaryArithmeticSimplify_<#= settings.Name #>( + private Value? BinaryArithmeticSimplify_<#= settings.Name #>( Location location, <#= settings.Left #> left, <#= settings.Right #> right, @@ -230,7 +230,7 @@ namespace ILGPU.IR.Construction /// Simplifies the <#= settings.Name #> of a binary expression. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - private Value BinaryArithmeticSimplify_<#= settings.Name #>( + private Value? BinaryArithmeticSimplify_<#= settings.Name #>( Location location, BinaryArithmeticValue arithmeticValue, PrimitiveValue firstValue, diff --git a/Src/ILGPU/IR/Construction/BasicBlock.Builder.cs b/Src/ILGPU/IR/Construction/BasicBlock.Builder.cs index 4823dd743..d696c7d64 100644 --- a/Src/ILGPU/IR/Construction/BasicBlock.Builder.cs +++ b/Src/ILGPU/IR/Construction/BasicBlock.Builder.cs @@ -82,7 +82,7 @@ internal Builder(Method.Builder methodBuilder, BasicBlock block) /// /// Gets or sets the current terminator. /// - public TerminatorValue Terminator + public TerminatorValue? Terminator { get => BasicBlock.Terminator; set @@ -213,7 +213,8 @@ public void Clear() { foreach (var reference in Values) toRemove.Add(reference.DirectTarget); - toRemove.Add(Terminator); + if (Terminator != null) + toRemove.Add(Terminator); } /// @@ -510,7 +511,7 @@ public bool TryFindFirstValueOf( protected override T CreateTerminator(T node) { Terminator?.Replace(node); - return (Terminator = node) as T; + return (Terminator = node).AsNotNullCast(); } /// diff --git a/Src/ILGPU/IR/Construction/IRRebuilder.cs b/Src/ILGPU/IR/Construction/IRRebuilder.cs index e9a306f71..42348f049 100644 --- a/Src/ILGPU/IR/Construction/IRRebuilder.cs +++ b/Src/ILGPU/IR/Construction/IRRebuilder.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: IRRebuilder.cs @@ -10,8 +10,10 @@ // --------------------------------------------------------------------------------------- using ILGPU.IR.Values; +using ILGPU.Util; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using static ILGPU.IR.Values.TerminatorValue; using BlockCollection = ILGPU.IR.BasicBlockCollection< @@ -385,7 +387,7 @@ private void InitPhiValues(in BlockCollection blocks) /// /// Gets or sets the current block builder. /// - private BasicBlock.Builder CurrentBlock { get; set; } + private BasicBlock.Builder? CurrentBlock { get; set; } /// /// Lookups the given block in the internal rebuilder remapping. @@ -417,7 +419,7 @@ private void InitPhiValues(in BlockCollection blocks) /// The exit block and the associated return value. public (BasicBlock.Builder, Value) Rebuild() { - (BasicBlock.Builder, Value) exitBlock = (null, null); + (BasicBlock.Builder?, Value?) exitBlock = (null, null); // Rebuild all instructions foreach (var block in Blocks) @@ -428,7 +430,7 @@ private void InitPhiValues(in BlockCollection blocks) foreach (Value value in block) Rebuild(value); - var terminator = block.Terminator.Resolve(); + var terminator = block.Terminator?.Resolve(); if (terminator is ReturnTerminator returnValue) { var newReturnValue = Rebuild(returnValue.ReturnValue); @@ -459,7 +461,7 @@ private void InitPhiValues(in BlockCollection blocks) targetPhiBuilder.Seal(); } - return exitBlock; + return (exitBlock.Item1.AsNotNull(), exitBlock.Item2.AsNotNull()); } /// @@ -468,7 +470,9 @@ private void InitPhiValues(in BlockCollection blocks) /// The old node. /// The new node. /// True, if a corresponding new node could be found. - public bool TryGetNewNode(Value oldNode, out Value newNode) => + public bool TryGetNewNode( + Value oldNode, + [NotNullWhen(true)] out Value? newNode) => valueMapping.TryGetValue(oldNode, out newNode); /// @@ -544,7 +548,7 @@ public Value Rebuild(Value source) // Verify that we are not rebuilding a replaced node source.Assert(!source.IsReplaced); - if (TryGetNewNode(source, out Value node)) + if (TryGetNewNode(source, out Value? node)) return node; // Preserve values from to already defined parts of the program @@ -558,7 +562,7 @@ public Value Rebuild(Value source) // Verify that we are not rebuilding a parameter source.Assert(!(source is Parameter)); - node = source.Rebuild(CurrentBlock, this); + node = source.Rebuild(CurrentBlock.AsNotNull(), this); Map(source, node); return node; } @@ -570,7 +574,7 @@ public Value Rebuild(Value source) /// The target type to cast the new node to. /// The source node. /// The new node. - public T RebuildAs(Value source) + public T? RebuildAs(Value source) where T : Value => Rebuild(source) as T; diff --git a/Src/ILGPU/IR/Construction/Memory.cs b/Src/ILGPU/IR/Construction/Memory.cs index 32a601d99..b4ea42fef 100644 --- a/Src/ILGPU/IR/Construction/Memory.cs +++ b/Src/ILGPU/IR/Construction/Memory.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Memory.cs @@ -11,6 +11,7 @@ using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; namespace ILGPU.IR.Construction { @@ -205,7 +206,7 @@ public ValueReference CreateLoadElementAddress( // Assert a valid indexing type from here on location.Assert( IRTypeContext.IsViewIndexType(elementIndex.BasicValueType)); - var addressSpaceType = source.Type as AddressSpaceType; + var addressSpaceType = source.Type.AsNotNullCast(); location.AssertNotNull(addressSpaceType); // Fold nested conversion operations that do not change the semantics diff --git a/Src/ILGPU/IR/Construction/Method.Builder.cs b/Src/ILGPU/IR/Construction/Method.Builder.cs index 7f62286f8..cf5213d7a 100644 --- a/Src/ILGPU/IR/Construction/Method.Builder.cs +++ b/Src/ILGPU/IR/Construction/Method.Builder.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Method.Builder.cs @@ -121,8 +121,8 @@ public void Visit(BasicBlock block) /// [MethodImpl(MethodImplOptions.AggressiveInlining)] private static bool RequiresControlFlowUpdate( - TerminatorValue oldTerminator, - TerminatorValue newTerminator) + TerminatorValue? oldTerminator, + TerminatorValue? newTerminator) { if (oldTerminator == newTerminator) return false; @@ -280,8 +280,8 @@ public BasicBlock.Builder this[BasicBlock basicBlock] /// changed by setting a new terminator. /// public void ScheduleControlFlowUpdate( - TerminatorValue oldTerminator, - TerminatorValue newTerminator) + TerminatorValue? oldTerminator, + TerminatorValue? newTerminator) { if (RequiresControlFlowUpdate(oldTerminator, newTerminator)) ScheduleControlFlowUpdate(); @@ -393,7 +393,7 @@ public Parameter AddParameter(TypeNode type) => /// The parameter type. /// The parameter name (for debugging purposes). /// The created parameter. - public Parameter AddParameter(TypeNode type, string name) + public Parameter AddParameter(TypeNode type, string? name) { var param = CreateParam(type, name); parameters.Add(param); @@ -414,7 +414,7 @@ public Parameter InsertParameter(TypeNode type) => /// The parameter type. /// The parameter name (for debugging purposes). /// The created parameter. - public Parameter InsertParameter(TypeNode type, string name) + public Parameter InsertParameter(TypeNode type, string? name) { var param = CreateParam(type, name); parameters.Insert(0, param); @@ -427,7 +427,7 @@ public Parameter InsertParameter(TypeNode type, string name) /// The parameter type. /// The parameter name (for debugging purposes). /// The created parameter. - private Parameter CreateParam(TypeNode type, string name) => + private Parameter CreateParam(TypeNode type, string? name) => new Parameter( new ValueInitializer( BaseContext, @@ -451,7 +451,7 @@ public BasicBlock.Builder CreateBasicBlock(Location location) => /// The block name. /// The created basic block. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public BasicBlock.Builder CreateBasicBlock(Location location, string name) + public BasicBlock.Builder CreateBasicBlock(Location location, string? name) { var block = new BasicBlock(Method, location, name); block.BeginControlFlowUpdate(blockCounter++); diff --git a/Src/ILGPU/IR/Construction/Predicate.cs b/Src/ILGPU/IR/Construction/Predicate.cs index 8d7592dc4..7573334d6 100644 --- a/Src/ILGPU/IR/Construction/Predicate.cs +++ b/Src/ILGPU/IR/Construction/Predicate.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: Predicate.cs @@ -11,6 +11,7 @@ using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; namespace ILGPU.IR.Construction { @@ -37,7 +38,7 @@ public ValueReference CreatePredicate( falseValue = CreateConvert( location, falseValue, - trueValue.Type as PrimitiveType); + trueValue.Type.AsNotNullCast()); } // Match simple constant predicates diff --git a/Src/ILGPU/IR/Construction/SSABuilder.cs b/Src/ILGPU/IR/Construction/SSABuilder.cs index 0eb69c806..abb2c71f1 100644 --- a/Src/ILGPU/IR/Construction/SSABuilder.cs +++ b/Src/ILGPU/IR/Construction/SSABuilder.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: SSABuilder.cs @@ -11,6 +11,7 @@ using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; using System; using System.Collections; using System.Collections.Generic; @@ -164,7 +165,7 @@ public IncompletePhi( /// /// Represents the current block builder. /// - private BasicBlock.Builder blockBuilder; + private BasicBlock.Builder? blockBuilder; /// /// Value cache for SSA GetValue and SetValue functionality. @@ -211,8 +212,7 @@ public BasicBlock.Builder Builder { get { - if (blockBuilder == null) - blockBuilder = Parent.MethodBuilder[Block]; + blockBuilder ??= Parent.MethodBuilder[Block]; return blockBuilder; } } @@ -279,7 +279,7 @@ public void SetValue(TVariable var, Value value) => /// A provider of new marker values. /// The value of the given variable. public Value GetValue(TVariable var, ref MarkerProvider markerProvider) => - values.TryGetValue(var, out Value value) + values.TryGetValue(var, out Value? value) ? value : GetValueRecursive(var, ref markerProvider); @@ -296,16 +296,16 @@ public Value GetValue(TVariable var, ref MarkerProvider markerProvider) => /// The variable reference. /// The current marker to break cycles. /// - private Value PeekValue(TVariable var, int marker) + private Value? PeekValue(TVariable var, int marker) { if (!IsProcessed || !Mark(marker)) return null; - if (values.TryGetValue(var, out Value value)) + if (values.TryGetValue(var, out Value? value)) return value; foreach (var predecessor in Block.Predecessors) { var valueContainer = Parent[predecessor]; - Value result; + Value? result; if ((result = valueContainer.PeekValue(var, marker)) != null) return result; } @@ -338,10 +338,11 @@ private Value GetValueRecursive( else { // Insert the actual phi value - var peekedValue = PeekValue(var, markerProvider.CreateMarker()); + var peekedValue = + PeekValue(var, markerProvider.CreateMarker()).AsNotNull(); // Let the phi point to the beginning of the current block var phiBuilder = Builder.CreatePhi( - blockBuilder.BasicBlock.Location, + Builder.BasicBlock.Location, peekedValue.Type); value = phiBuilder.PhiValue; diff --git a/Src/ILGPU/IR/Construction/Structures.cs b/Src/ILGPU/IR/Construction/Structures.cs index 1c4d0c141..f2db18b18 100644 --- a/Src/ILGPU/IR/Construction/Structures.cs +++ b/Src/ILGPU/IR/Construction/Structures.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Structures.cs @@ -47,8 +47,8 @@ public ValueReference CreateObjectValue( { return CreateArrayValue( location, - instance as Array, - managedType.GetElementType(), + instance.AsNotNullCast(), + managedType.GetElementType().AsNotNull(), force: false); } // Check whether this type is an immutable array which might require special @@ -79,14 +79,14 @@ public ValueReference CreateObjectValue( return typeInfo.NumFields > 0 ? CreateObjectValue( location, - typeInfo.Fields[0].GetValue(instance)) + typeInfo.Fields[0].GetValue(instance).AsNotNull()) : CreateNull(location, type); } var instanceBuilder = CreateStructure(location, structureType); for (int i = 0, e = typeInfo.NumFields; i < e; ++i) { var field = typeInfo.Fields[i]; - var rawFieldValue = field.GetValue(instance); + var rawFieldValue = field.GetValue(instance).AsNotNull(); Value fieldValue = CreateObjectValue( location, rawFieldValue); @@ -152,7 +152,7 @@ private unsafe ValueReference CreateArrayValue( { throw location.GetNotSupportedException( ErrorMessages.NotSupportedLoadFromStaticArray, - array.ToString()); + array.ToString().AsNotNull()); } // Prepare element type and check of empty arrays @@ -184,7 +184,8 @@ private unsafe ValueReference CreateArrayValue( var source = baseAddr + elementSize * i; var instance = Marshal.PtrToStructure( new IntPtr(source), - managedElementType); + managedElementType) + .AsNotNull(); var irValue = CreateValue(location, instance, managedElementType); // Store element @@ -227,7 +228,7 @@ private ValueReference CreateImmutableArrayValue( return CreateArrayValue( location, - arrayInstance as Array, + arrayInstance.AsNotNullCast(), managedElementType, force: true); } @@ -427,11 +428,12 @@ public ValueReference CreateGetField( Value objectValue, FieldSpan fieldSpan) { - var structureType = objectValue.Type as StructureType; - if (structureType == null && fieldSpan.Span < 2) + StructureType? nullableStructureType = objectValue.Type as StructureType; + if (nullableStructureType == null && fieldSpan.Span < 2) return objectValue; // Must be a structure type + var structureType = nullableStructureType.AsNotNull(); location.AssertNotNull(structureType); // Try to combine different get and set operations operating on similar spans diff --git a/Src/ILGPU/IR/Construction/Types.cs b/Src/ILGPU/IR/Construction/Types.cs index dd1475a21..9143157c1 100644 --- a/Src/ILGPU/IR/Construction/Types.cs +++ b/Src/ILGPU/IR/Construction/Types.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Types.cs @@ -11,6 +11,7 @@ using ILGPU.IR.Types; using System; +using System.Diagnostics.CodeAnalysis; namespace ILGPU.IR.Construction { @@ -116,7 +117,7 @@ public AddressSpaceType SpecializeAddressSpaceType( public bool TrySpecializeAddressSpaceType( TypeNode type, MemoryAddressSpace addressSpace, - out TypeNode specializedType) => + [NotNullWhen(true)] out TypeNode? specializedType) => TypeContext.TrySpecializeAddressSpaceType( type, addressSpace, diff --git a/Src/ILGPU/IR/Construction/Values.cs b/Src/ILGPU/IR/Construction/Values.cs index d5e905808..0890d4229 100644 --- a/Src/ILGPU/IR/Construction/Values.cs +++ b/Src/ILGPU/IR/Construction/Values.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Values.cs @@ -323,7 +323,10 @@ public ValueReference CreateValue( ArithmeticBasicValueType.UInt64 => CreatePrimitiveValue(location, Convert.ToUInt64(value)), ArithmeticBasicValueType.Float16 => - CreatePrimitiveValue(location, (Half)value), + CreatePrimitiveValue(location, + value == null + ? Half.Zero + : (Half)value), ArithmeticBasicValueType.Float32 => CreatePrimitiveValue(location, Convert.ToSingle(value)), ArithmeticBasicValueType.Float64 => diff --git a/Src/ILGPU/IR/ILocation.cs b/Src/ILGPU/IR/ILocation.cs index 83ed8a3f8..d79c2dfd5 100644 --- a/Src/ILGPU/IR/ILocation.cs +++ b/Src/ILGPU/IR/ILocation.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: ILocation.cs @@ -47,7 +47,7 @@ public static class Locations /// the current source location at which this exception has been created. /// public static InternalCompilerException GetException( - this ILocation location, + this ILocation? location, Exception exception) { var message = (location?.FormatErrorMessage( @@ -67,7 +67,7 @@ public static InternalCompilerException GetException( /// . /// public static InternalCompilerException GetArgumentException( - this ILocation location, + this ILocation? location, string paramName) => location.GetException(new ArgumentOutOfRangeException(paramName)); @@ -82,7 +82,7 @@ public static InternalCompilerException GetArgumentException( /// . /// public static InternalCompilerException GetArgumentNullException( - this ILocation location, + this ILocation? location, string paramName) => location.GetException(new ArgumentNullException(paramName)); @@ -98,7 +98,7 @@ public static InternalCompilerException GetArgumentNullException( /// . /// public static InternalCompilerException GetNotSupportedException( - this ILocation location, + this ILocation? location, string message, params object[] args) => location.GetException(new NotSupportedException( @@ -114,7 +114,7 @@ public static InternalCompilerException GetNotSupportedException( /// . /// public static InternalCompilerException GetInvalidOperationException( - this ILocation location) => + this ILocation? location) => location.GetException(new InvalidOperationException( ErrorMessages.InternalCompilerError)); @@ -129,7 +129,7 @@ public static InternalCompilerException GetInvalidOperationException( /// . /// public static InternalCompilerException GetInvalidOperationException( - this ILocation location, + this ILocation? location, string message) => location.GetException(new InvalidOperationException(message)); @@ -143,7 +143,7 @@ public static InternalCompilerException GetInvalidOperationException( /// The value to be not null. [Conditional("DEBUG")] [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void AssertNotNull(this ILocation location, TValue value) + internal static void AssertNotNull(this ILocation? location, TValue value) where TValue : class { if (value == null) @@ -165,7 +165,7 @@ internal static void AssertNotNull(this ILocation location, TValue value /// The condition to hold. [Conditional("DEBUG")] [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void Assert(this ILocation location, bool condition) + internal static void Assert(this ILocation? location, bool condition) { if (!condition) { diff --git a/Src/ILGPU/IR/IRContext.cs b/Src/ILGPU/IR/IRContext.cs index 59cc3fd48..90002d8ce 100644 --- a/Src/ILGPU/IR/IRContext.cs +++ b/Src/ILGPU/IR/IRContext.cs @@ -21,6 +21,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; @@ -169,7 +170,9 @@ private MethodCollection GetMethodCollection_Sync( /// The method to resolve. /// The resolved function reference (if any). /// True, if the requested function could be resolved. - public bool TryGetMethodHandle(MethodBase method, out MethodHandle handle) + public bool TryGetMethodHandle( + MethodBase method, + [NotNullWhen(true)] out MethodHandle? handle) { if (method == null) throw new ArgumentNullException(nameof(method)); @@ -186,7 +189,9 @@ public bool TryGetMethodHandle(MethodBase method, out MethodHandle handle) /// The function handle to resolve. /// The resolved function (if any). /// True, if the requested function could be resolved. - public bool TryGetMethod(MethodHandle handle, out Method function) + public bool TryGetMethod( + MethodHandle handle, + [NotNullWhen(true)] out Method? function) { if (handle.IsEmpty) { @@ -206,7 +211,9 @@ public bool TryGetMethod(MethodHandle handle, out Method function) /// The method to resolve. /// The resolved function (if any). /// True, if the requested function could be resolved. - public bool TryGetMethod(MethodBase method, out Method function) + public bool TryGetMethod( + MethodBase method, + [NotNullWhen(true)] out Method? function) { if (method == null) throw new ArgumentNullException(nameof(method)); @@ -215,8 +222,8 @@ public bool TryGetMethod(MethodBase method, out Method function) using var readScope = irLock.EnterUpgradeableReadScope(); function = null; - return methods.TryGetHandle(method, out MethodHandle handle) - && methods.TryGetData(handle, out function); + return methods.TryGetHandle(method, out MethodHandle? handle) + && methods.TryGetData(handle.Value, out function); } /// @@ -225,7 +232,7 @@ public bool TryGetMethod(MethodBase method, out Method function) /// The method to resolve. /// The resolved function. public Method GetMethod(MethodHandle method) => - TryGetMethod(method, out Method function) + TryGetMethod(method, out Method? function) ? function : throw new InvalidOperationException(string.Format( ErrorMessages.CouldNotFindCorrespondingIRMethod, @@ -245,17 +252,17 @@ public Method Declare(MethodBase methodBase, out bool created) using var readScope = irLock.EnterUpgradeableReadScope(); // Check for existing method - if (methods.TryGetHandle(methodBase, out MethodHandle handle)) + if (methods.TryGetHandle(methodBase, out MethodHandle? handle)) { created = false; - return methods[handle]; + return methods[handle.Value]; } var externalAttribute = methodBase.GetCustomAttribute(); var methodName = externalAttribute?.Name ?? methodBase.Name; handle = MethodHandle.Create(methodName); var declaration = new MethodDeclaration( - handle, + handle.Value, CreateType(methodBase.GetReturnType()), methodBase); @@ -291,7 +298,7 @@ private Method Declare_Sync(in MethodDeclaration declaration, out bool created) Debug.Assert(declaration.ReturnType != null, "Invalid return type"); created = false; - if (methods.TryGetData(declaration.Handle, out Method method)) + if (methods.TryGetData(declaration.Handle, out Method? method)) return method; created = true; @@ -315,7 +322,7 @@ private Method DeclareNewMethod_Sync( { var methodId = Context.CreateMethodHandle(); var methodName = declaration.Handle.Name ?? - (declaration.HasSource ? declaration.Source.Name : "Func"); + (declaration.HasSource ? declaration.Source.AsNotNull().Name : "Func"); handle = new MethodHandle(methodId, methodName); var specializedDeclaration = declaration.Specialize(handle); @@ -377,7 +384,7 @@ public Method Import(Method source) throw source.GetArgumentException(nameof(source)); // Determine the actual source context reference - var sourceContext = source.BaseContext as IRContext; + var sourceContext = (source.BaseContext as IRContext).AsNotNull(); if (sourceContext == this) throw source.GetInvalidOperationException(); @@ -385,7 +392,7 @@ public Method Import(Method source) using var readScope = irLock.EnterUpgradeableReadScope(); // Check for the requested method handle - if (methods.TryGetData(source.Handle, out Method method)) + if (methods.TryGetData(source.Handle, out Method? method)) return method; // CAUTION: we have to acquire the current irLock in write mode and have diff --git a/Src/ILGPU/IR/Intrinsics/IntrinsicImplementation.cs b/Src/ILGPU/IR/Intrinsics/IntrinsicImplementation.cs index ef714edf5..ef258b05c 100644 --- a/Src/ILGPU/IR/Intrinsics/IntrinsicImplementation.cs +++ b/Src/ILGPU/IR/Intrinsics/IntrinsicImplementation.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: IntrinsicImplementation.cs @@ -11,6 +11,7 @@ using ILGPU.Backends; using ILGPU.Resources; +using ILGPU.Util; using System; using System.Reflection; @@ -70,14 +71,15 @@ protected IntrinsicImplementation( protected IntrinsicImplementation( BackendType backendType, Type handlerType, - string methodName, + string? methodName, IntrinsicImplementationMode mode) : this( backendType, handlerType.GetMethod( - methodName ?? "Invoke", - BindingFlags.Public | BindingFlags.NonPublic | - BindingFlags.Static | BindingFlags.Instance), + methodName ?? "Invoke", + BindingFlags.Public | BindingFlags.NonPublic | + BindingFlags.Static | BindingFlags.Instance) + .AsNotNull(), mode) { } diff --git a/Src/ILGPU/IR/Intrinsics/IntrinsicImplementationManager.cs b/Src/ILGPU/IR/Intrinsics/IntrinsicImplementationManager.cs index a75f122df..e69037413 100644 --- a/Src/ILGPU/IR/Intrinsics/IntrinsicImplementationManager.cs +++ b/Src/ILGPU/IR/Intrinsics/IntrinsicImplementationManager.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: IntrinsicImplementationManager.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.Backends; +using ILGPU.Util; using System; using System.Collections; using System.Collections.Generic; @@ -247,7 +248,7 @@ private TMatcher ResolveMatcher( if (implementation == null) throw new ArgumentNullException(nameof(implementation)); var container = this[implementation.BackendType]; - return container[kind] as TMatcher; + return container[kind].AsNotNullCast(); } /// diff --git a/Src/ILGPU/IR/Intrinsics/IntrinsicImplementationProvider.cs b/Src/ILGPU/IR/Intrinsics/IntrinsicImplementationProvider.cs index c9ab3777f..2a6699bc6 100644 --- a/Src/ILGPU/IR/Intrinsics/IntrinsicImplementationProvider.cs +++ b/Src/ILGPU/IR/Intrinsics/IntrinsicImplementationProvider.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: IntrinsicImplementationProvider.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.CompilerServices; @@ -60,8 +61,8 @@ public ImplementationTransformer(Backend backend) /// - public IntrinsicMapping Transform( - IntrinsicImplementationManager.ImplementationEntry entry) + public IntrinsicMapping? Transform( + IntrinsicImplementationManager.ImplementationEntry? entry) { if (entry != null && CheckImplementations(Backend, entry, out var mainImplementation)) @@ -93,7 +94,7 @@ public IntrinsicMapping Transform( private static bool CheckImplementations( Backend backend, IntrinsicImplementationManager.ImplementationEntry implementations, - out IntrinsicImplementation mainImplementation) + [NotNullWhen(true)] out IntrinsicImplementation? mainImplementation) { mainImplementation = null; foreach (var implementation in implementations) @@ -359,8 +360,9 @@ internal IntrinsicImplementationProvider( var allMatchers = IntrinsicMatcher.CreateMatchers< IntrinsicMapping>(); container.TransformTo(new ImplementationTransformer(backend), allMatchers); - methodMatcher = allMatchers[(int)IntrinsicMatcher.MatcherKind.Method] - as IntrinsicMethodMatcher>; + methodMatcher = (allMatchers[(int)IntrinsicMatcher.MatcherKind.Method] + as IntrinsicMethodMatcher>) + .AsNotNull(); // Build a fast value-kind specific lookup valueMatchers = new BaseIntrinsicValueMatcher< @@ -405,7 +407,7 @@ public IRSpecializationPhase BeginIRSpecialization() => /// True, if the given method could be resolved to a mapping. public bool TryGetMapping( Method method, - out IntrinsicMapping mapping) => + [NotNullWhen(true)] out IntrinsicMapping? mapping) => TryGetMapping(method, out var _, out mapping); /// @@ -419,8 +421,8 @@ public bool TryGetMapping( /// True, if the given method could be resolved to a mapping. public bool TryGetMapping( Method method, - out MethodInfo methodInfo, - out IntrinsicMapping mapping) + [NotNullWhen(true)] out MethodInfo? methodInfo, + [NotNullWhen(true)] out IntrinsicMapping? mapping) { mapping = default; return (methodInfo = method.Source as MethodInfo) != null && @@ -436,7 +438,7 @@ public bool TryGetMapping( /// True, if the given method could be resolved to a mapping. public bool TryGetMapping( MethodInfo method, - out IntrinsicMapping mapping) => + [NotNullWhen(true)] out IntrinsicMapping? mapping) => methodMatcher.TryGetImplementation(method, out mapping); /// @@ -446,7 +448,9 @@ public bool TryGetMapping( /// The resolved mapping. /// True, if the given method could be resolved to a mapping. [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool TryGetMapping(Value value, out IntrinsicMapping mapping) + public bool TryGetMapping( + Value value, + [NotNullWhen(true)] out IntrinsicMapping? mapping) { var matchers = valueMatchers[(int)value.ValueKind]; if (matchers != null) @@ -466,14 +470,16 @@ public bool TryGetMapping(Value value, out IntrinsicMapping mapping) /// True, if the value could be resolved to an intrinsic value. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - private bool TryGetData(Value value, out TResult result) + private bool TryGetData( + Value value, + [NotNullWhen(true)] out TResult? result) where TResult : class where TDataProvider : struct, IDataProvider { result = null; TDataProvider dataProvider = default; - IntrinsicMapping mapping; + IntrinsicMapping? mapping; if (value is MethodCall call) { if (!TryGetMapping(call.Target, out var methodInfo, out mapping) || @@ -506,7 +512,9 @@ private bool TryGetData(Value value, out TResult result) /// /// True, if the given method could be resolved to an IR implementation. /// - public bool TryGetImplementation(Value value, out Method irImplementation) => + public bool TryGetImplementation( + Value value, + [NotNullWhen(true)] out Method? irImplementation) => TryGetData(value, out irImplementation); /// @@ -517,7 +525,9 @@ public bool TryGetImplementation(Value value, out Method irImplementation) => /// /// True, if the given method could be resolved to a code generator. /// - public bool TryGetCodeGenerator(Value value, out TDelegate codeGenerator) => + public bool TryGetCodeGenerator( + Value value, + [NotNullWhen(true)] out TDelegate? codeGenerator) => TryGetData(value, out codeGenerator); /// diff --git a/Src/ILGPU/IR/Intrinsics/IntrinsicMapping.cs b/Src/ILGPU/IR/Intrinsics/IntrinsicMapping.cs index 33e3ee3ab..347c57605 100644 --- a/Src/ILGPU/IR/Intrinsics/IntrinsicMapping.cs +++ b/Src/ILGPU/IR/Intrinsics/IntrinsicMapping.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: IntrinsicMapping.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.Backends; +using ILGPU.Util; using System; using System.Collections.Generic; using System.Diagnostics; @@ -149,7 +150,7 @@ public bool Equals(MappingKey other) /// /// True, if the given object is equal to this mapping key. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is MappingKey entry && Equals(entry); /// @@ -295,8 +296,8 @@ public sealed class IntrinsicMapping : IntrinsicMapping { #region Instance - private readonly Dictionary implementationMapping; - private readonly Dictionary delegateMapping; + private readonly Dictionary? implementationMapping; + private readonly Dictionary? delegateMapping; /// /// Constructs a new intrinsic implementation. @@ -313,8 +314,9 @@ internal IntrinsicMapping(IntrinsicImplementation implementation) case IntrinsicImplementationMode.GenerateCode: if (!TargetMethod.IsGenericMethod) { - CodeGenerator = TargetMethod.CreateDelegate(typeof(TDelegate)) - as TDelegate; + CodeGenerator = (TargetMethod.CreateDelegate(typeof(TDelegate)) + as TDelegate) + .AsNotNull(); } else { @@ -333,7 +335,7 @@ internal IntrinsicMapping(IntrinsicImplementation implementation) /// /// Returns the associated default code generator (if any). /// - private TDelegate CodeGenerator { get; } + private TDelegate? CodeGenerator { get; } #endregion @@ -346,7 +348,7 @@ internal IntrinsicMapping(IntrinsicImplementation implementation) /// The implementation to provide. internal void ProvideImplementation( MappingKey genericMapping, - Method implementation) + Method? implementation) { Debug.Assert( Mode == IntrinsicImplementationMode.Redirect, @@ -355,7 +357,7 @@ internal void ProvideImplementation( implementation != null, "Invalid implementation"); - implementationMapping[genericMapping] = implementation; + implementationMapping.AsNotNull()[genericMapping] = implementation; } /// @@ -371,7 +373,7 @@ public Method ResolveImplementation(TResolver resolver) Debug.Assert(Mode == IntrinsicImplementationMode.Redirect); var genericArguments = resolver.ResolveGenericArguments(); var key = new MappingKey(genericArguments); - return implementationMapping[key]; + return implementationMapping.AsNotNull()[key]; } /// @@ -390,14 +392,14 @@ public TDelegate ResolveCodeGenerator(TResolver resolver) var resolvedMethod = ResolveTarget(resolver, out var genericArguments); Debug.Assert(genericArguments != null, "Invalid generic arguments"); - lock (delegateMapping) + lock (delegateMapping.AsNotNull()) { var key = new MappingKey(genericArguments); - if (!delegateMapping.TryGetValue(key, out var codeGenerator)) + if (!delegateMapping.AsNotNull().TryGetValue(key, out var codeGenerator)) { codeGenerator = resolvedMethod.CreateDelegate(typeof(TDelegate)) - as TDelegate; - delegateMapping.Add(key, codeGenerator); + .AsNotNullCast(); + delegateMapping.AsNotNull().Add(key, codeGenerator); } return codeGenerator; } diff --git a/Src/ILGPU/IR/Intrinsics/IntrinsicMatcher.cs b/Src/ILGPU/IR/Intrinsics/IntrinsicMatcher.cs index 9ac220d9a..73a47d999 100644 --- a/Src/ILGPU/IR/Intrinsics/IntrinsicMatcher.cs +++ b/Src/ILGPU/IR/Intrinsics/IntrinsicMatcher.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: IntrinsicMatcher.cs @@ -9,8 +9,10 @@ // Source License. See LICENSE.txt for details. // --------------------------------------------------------------------------------------- +using ILGPU.Util; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace ILGPU.IR.Intrinsics @@ -49,7 +51,7 @@ public interface IIntrinsicImplementationTransformer /// /// The implementation to transform. /// The transformed implementation. - TSecond Transform(TFirst implementation); + TSecond? Transform(TFirst? implementation); } /// @@ -116,7 +118,7 @@ internal IntrinsicMatcher() { } /// True, if an implementation could be resolved. public abstract bool TryGetImplementation( TMatchedValue value, - out T implementation); + [NotNullWhen(true)] out T? implementation); #endregion } @@ -130,8 +132,8 @@ public sealed class IntrinsicMethodMatcher : IntrinsicMatcher { #region Instance - private readonly Dictionary entries = - new Dictionary(); + private readonly Dictionary entries = + new Dictionary(); /// /// Constructs a new intrinsic matcher. @@ -162,7 +164,9 @@ public void Register(MethodInfo value, T implementation) /// - public override bool TryGetImplementation(MethodInfo value, out T implementation) + public override bool TryGetImplementation( + MethodInfo value, + [NotNullWhen(true)] out T? implementation) { if (value.IsGenericMethod) value = value.GetGenericMethodDefinition(); @@ -175,7 +179,7 @@ public override void TransformTo( TTransformer transformer, IntrinsicMatcher other) { - var otherMatcher = other as IntrinsicMethodMatcher; + var otherMatcher = other.AsNotNullCast>(); foreach (var entry in entries) otherMatcher.entries[entry.Key] = transformer.Transform(entry.Value); } @@ -214,122 +218,6 @@ protected BaseIntrinsicValueMatcher(ValueKind valueKind) #endregion } - /// - /// Represents an intrinsic matcher that matches values. - /// - /// The matcher value type. - public abstract class IntrinsicValueMatcher : BaseIntrinsicValueMatcher - where T : class, IIntrinsicImplementation - { - #region Instance - - /// - /// Constructs a new abstract intrinsic value matcher. - /// - /// The value kind. - protected IntrinsicValueMatcher(ValueKind valueKind) - : base(valueKind) - { } - - #endregion - - #region Properties - - /// - /// Returns the associated implementation. - /// - public T Implementation { get; private set; } - - #endregion - - #region Methods - - /// - /// Registers the given implementation. - /// - /// The implementation to register. - public void Register(T implementation) - { - if (Implementation != null) - throw new InvalidOperationException(); - Implementation = implementation - ?? throw new ArgumentNullException(nameof(implementation)); - } - - /// - public sealed override void TransformTo( - TTransformer transformer, - IntrinsicMatcher other) - { - var otherMatcher = other as IntrinsicValueMatcher; - otherMatcher.Implementation = transformer.Transform(Implementation); - } - - #endregion - } - - /// - /// Represents an intrinsic matcher that matches values. - /// - /// The matcher value type. - /// The type of the value kind. - public abstract class IntrinsicValueMatcher : - BaseIntrinsicValueMatcher - where T : class, IIntrinsicImplementation - where TValueKind : struct - { - #region Instance - - /// - /// All value implementation entries. - /// - private readonly T[] entries; - - /// - /// Constructs a new abstract intrinsic value matcher. - /// - /// The value kind. - protected IntrinsicValueMatcher(ValueKind valueKind) - : base(valueKind) - { - var values = Enum.GetValues(typeof(TValueKind)); - entries = new T[values.Length]; - } - - #endregion - - #region Properties - - /// - /// Returns a reference to the i-th element. - /// - /// The element index. - /// The resolved reference. - protected T this[int index] - { - get => entries[index]; - set => entries[index] = value; - } - - #endregion - - #region Methods - - /// - public sealed override void TransformTo( - TTransformer transformer, - IntrinsicMatcher other) - { - var otherMatcher = other as IntrinsicValueMatcher; - for (int i = 0, e = entries.Length; i < e; ++i) - otherMatcher.entries[i] = transformer.Transform(entries[i]); - } - - #endregion - } - /// /// Represents an intrinsic matcher that matches values. /// @@ -345,7 +233,7 @@ public abstract class TypedIntrinsicValueMatcher : /// /// All value implementation entries. /// - private readonly T[,] entries; + private readonly T?[,] entries; /// /// Constructs a new abstract intrinsic value matcher. @@ -369,7 +257,7 @@ protected TypedIntrinsicValueMatcher(ValueKind valueKind) /// The element index. /// The basic-value type. /// The resolved reference. - protected T this[int index, BasicValueType basicValueType] + protected T? this[int index, BasicValueType basicValueType] { get => entries[index, (int)basicValueType]; set => entries[index, (int)basicValueType] = value; @@ -385,7 +273,8 @@ public sealed override void TransformTo( TTransformer transformer, IntrinsicMatcher other) { - var otherMatcher = other as TypedIntrinsicValueMatcher; + var otherMatcher = + other.AsNotNullCast>(); for (int i = 0, e = entries.GetLength(0); i < e; ++i) { for (int j = 0, e2 = entries.GetLength(1); j < e2; ++j) diff --git a/Src/ILGPU/IR/Intrinsics/IntrinsicMatchers.tt b/Src/ILGPU/IR/Intrinsics/IntrinsicMatchers.tt index 751f7289d..6d325e6c3 100644 --- a/Src/ILGPU/IR/Intrinsics/IntrinsicMatchers.tt +++ b/Src/ILGPU/IR/Intrinsics/IntrinsicMatchers.tt @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2016-2021 ILGPU Project +// Copyright (c) 2016-2023 ILGPU Project // www.ilgpu.net // // File: IntrinsicMatchers.tt/IntrinsicMatchers.cs @@ -31,9 +31,10 @@ var typedMatchers = new (string, string, string)[] var allMatchers = matchers.Concat(typedMatchers); #> -using System; using ILGPU.IR.Values; +using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace ILGPU.IR.Intrinsics { @@ -161,7 +162,9 @@ namespace ILGPU.IR.Intrinsics /// The value kind. /// The resolved implementation (if any). /// True, if an implementation could be resolved. - public bool TryGetImplementation(<#= kind #> kind, out T implementation) + public bool TryGetImplementation( + <#= kind #> kind, + [NotNullWhen(true)] out T? implementation) { implementation = this[(int)kind]; return implementation != null; @@ -169,7 +172,9 @@ namespace ILGPU.IR.Intrinsics /// - public override bool TryGetImplementation(Value value, out T implementation) + public override bool TryGetImplementation( + Value value, + [NotNullWhen(true)] out T? implementation) { var targetValue = value as <#= matcher #>; Debug.Assert(targetValue != null, "Invalid target value"); @@ -215,7 +220,7 @@ namespace ILGPU.IR.Intrinsics public bool TryGetImplementation( <#= kind #> kind, BasicValueType basicValueType, - out T implementation) + [NotNullWhen(true)] out T? implementation) { implementation = this[(int)kind, basicValueType]; return implementation != null; @@ -223,7 +228,9 @@ namespace ILGPU.IR.Intrinsics /// - public override bool TryGetImplementation(Value value, out T implementation) + public override bool TryGetImplementation( + Value value, + [NotNullWhen(true)] out T? implementation) { var targetValue = value as <#= matcher #>; Debug.Assert(targetValue != null, "Invalid target value"); diff --git a/Src/ILGPU/IR/Location.cs b/Src/ILGPU/IR/Location.cs index a5d26897c..c86419779 100644 --- a/Src/ILGPU/IR/Location.cs +++ b/Src/ILGPU/IR/Location.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: Location.cs @@ -240,7 +240,7 @@ protected internal virtual FileLocation Merge(FileLocation other) => /// /// True, if the given object is equal to the current location. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is FileLocation other && FileName == other.FileName && StartColumn == other.StartColumn && @@ -343,7 +343,7 @@ public CompilationStackLocation Append(Location other) => /// /// Filled in with the location found. /// True if this compilation stack has the location type. - public bool TryGetLocation(out T location) + public bool TryGetLocation([NotNullWhen(true)] out T? location) where T : Location { foreach (var loc in Stack.Reverse()) @@ -370,7 +370,7 @@ public bool TryGetLocation(out T location) /// /// True, if the given object is equal to the current location. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is CompilationStackLocation other && Stack == other.Stack; diff --git a/Src/ILGPU/IR/Method.cs b/Src/ILGPU/IR/Method.cs index d846c3871..85ce8ef0b 100644 --- a/Src/ILGPU/IR/Method.cs +++ b/Src/ILGPU/IR/Method.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Method.cs @@ -16,6 +16,7 @@ using ILGPU.IR.Types; using ILGPU.IR.Values; using ILGPU.Resources; +using ILGPU.Util; using System; using System.Collections; using System.Collections.Generic; @@ -280,7 +281,7 @@ public MethodMapping(Dictionary methodMapping) public Method this[Method source] { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => mapping != null && mapping.TryGetValue(source, out Method target) + get => mapping != null && mapping.TryGetValue(source, out Method? target) ? target : source; } @@ -384,7 +385,7 @@ public static MethodFlags ResolveMethodFlags(MethodBase methodBase) private ImmutableArray parameters = ImmutableArray.Empty; [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private volatile Builder builder = null; + private volatile Builder? builder = null; /// /// Creates a new method instance. @@ -399,7 +400,7 @@ internal Method( : base( location.IsKnown ? location - : new MethodLocation(declaration.Source)) + : new MethodLocation(declaration.Source.AsNotNull())) { Location.Assert( declaration.HasHandle && declaration.ReturnType != null); @@ -448,7 +449,7 @@ internal Method( /// /// Returns the original source method (may be null). /// - public MethodBase Source => Declaration.Source; + public MethodBase Source => Declaration.Source.AsNotNull(); /// /// Returns true if the associated source method is not null. diff --git a/Src/ILGPU/IR/MethodHandle.cs b/Src/ILGPU/IR/MethodHandle.cs index 143fc7851..6e41e515f 100644 --- a/Src/ILGPU/IR/MethodHandle.cs +++ b/Src/ILGPU/IR/MethodHandle.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: MethodHandle.cs @@ -122,7 +122,7 @@ internal MethodHandle(long id, string name) /// /// The other object. /// True, if the given object is equal to this handle. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is MethodHandle handle && handle == this; /// @@ -248,7 +248,7 @@ public MethodDeclaration( public MethodDeclaration( MethodHandle handle, TypeNode returnType, - MethodBase source, + MethodBase? source, MethodFlags flags) { Handle = handle; @@ -258,7 +258,7 @@ public MethodDeclaration( Flags = flags; if (flags == MethodFlags.None && Source != null) - Flags = Method.ResolveMethodFlags(source); + Flags = Method.ResolveMethodFlags(Source); } #endregion @@ -298,7 +298,7 @@ public MethodDeclaration( /// /// Returns the managed source method. /// - public MethodBase Source { get; } + public MethodBase? Source { get; } #endregion @@ -368,7 +368,7 @@ public MethodDeclaration RemoveFlags(MethodFlags flags) => /// /// The other object. /// True, if the given object is equal to this declaration. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is MethodDeclaration declaration && declaration == this; /// diff --git a/Src/ILGPU/IR/MethodMapping.cs b/Src/ILGPU/IR/MethodMapping.cs index b675017c0..90fb0f617 100644 --- a/Src/ILGPU/IR/MethodMapping.cs +++ b/Src/ILGPU/IR/MethodMapping.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: MethodMapping.cs @@ -14,6 +14,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace ILGPU.IR @@ -133,7 +134,9 @@ internal ReadOnlyCollection(MethodMapping parent) /// The method to resolve. /// The resolved function handle (if any). /// True, if the requested function could be resolved. - public bool TryGetHandle(MethodBase method, out MethodHandle handle) => + public bool TryGetHandle( + MethodBase method, + [NotNullWhen(true)] out MethodHandle? handle) => Parent.TryGetHandle(method, out handle); /// @@ -142,7 +145,9 @@ public bool TryGetHandle(MethodBase method, out MethodHandle handle) => /// The function handle to resolve. /// The resolved data (if any). /// True, if the requested function could be resolved. - public bool TryGetFunction(MethodHandle handle, out T data) => + public bool TryGetFunction( + MethodHandle handle, + [NotNullWhen(true)] out T? data) => Parent.TryGetData(handle, out data); #endregion @@ -193,7 +198,7 @@ public T this[MethodHandle handle] get { if (handle.IsEmpty) - return default; + throw new ArgumentNullException(nameof(handle)); var index = methods[handle]; return dataList[index]; } @@ -215,8 +220,21 @@ public T this[MethodHandle handle] /// The method to resolve. /// The resolved function handle (if any). /// True, if the requested function could be resolved. - public bool TryGetHandle(MethodBase method, out MethodHandle handle) => - managedMethods.TryGetValue(method, out handle); + public bool TryGetHandle( + MethodBase method, + [NotNullWhen(true)] out MethodHandle? handle) + { + if (managedMethods.TryGetValue(method, out var result)) + { + handle = result; + return true; + } + else + { + handle = default; + return false; + } + } /// /// Tries to resolve the given method to a top-level function. @@ -224,7 +242,7 @@ public bool TryGetHandle(MethodBase method, out MethodHandle handle) => /// The method to resolve. /// The resolved data (if any). /// True, if the requested function could be resolved. - public bool TryGetData(MethodHandle method, out T data) + public bool TryGetData(MethodHandle method, [NotNullWhen(true)] out T? data) { if (!methods.TryGetValue(method, out int index)) { diff --git a/Src/ILGPU/IR/NodeId.cs b/Src/ILGPU/IR/NodeId.cs index 25973f650..7a6d01fec 100644 --- a/Src/ILGPU/IR/NodeId.cs +++ b/Src/ILGPU/IR/NodeId.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: NodeId.cs @@ -92,7 +92,7 @@ private NodeId(InstanceId id) /// /// The other object. /// True, if the given object is equal to this id. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is NodeId nodeId && nodeId == this; /// diff --git a/Src/ILGPU/IR/Rewriting/Rewriter.cs b/Src/ILGPU/IR/Rewriting/Rewriter.cs index 083b81281..8f2911c10 100644 --- a/Src/ILGPU/IR/Rewriting/Rewriter.cs +++ b/Src/ILGPU/IR/Rewriting/Rewriter.cs @@ -386,7 +386,7 @@ protected static bool Process( } // Process terminator (if any) - Value terminator = blockBuilder.Terminator; + Value? terminator = blockBuilder.Terminator; if (terminator == null || !converted.Add(terminator)) continue; @@ -615,7 +615,7 @@ public bool TryBeginRewrite( Method.Builder builder, T data, out RewriterProcess rewriting) => - TryBeginRewrite(blocks, builder, null, data, out rewriting); + TryBeginRewrite(blocks, builder, string.Empty, data, out rewriting); /// /// Rewrites the given scope on-the-fly using the method builder provided. @@ -628,7 +628,7 @@ public bool Rewrite( in BlockCollection blocks, Method.Builder builder, T data) => - Rewrite(blocks, builder, null, data); + Rewrite(blocks, builder, string.Empty, data); } /// @@ -690,7 +690,7 @@ public bool TryBeginRewrite( in BlockCollection blocks, Method.Builder builder, out RewriterProcess rewriting) => - TryBeginRewrite(blocks, builder, null, out rewriting); + TryBeginRewrite(blocks, builder, string.Empty, out rewriting); /// /// Rewrites the given scope on-the-fly using the method builder provided. @@ -699,6 +699,6 @@ public bool TryBeginRewrite( /// The current builder. /// True, if the rewriter could be applied. public bool Rewrite(in BlockCollection blocks, Method.Builder builder) => - Rewrite(blocks, builder, null); + Rewrite(blocks, builder, string.Empty); } } diff --git a/Src/ILGPU/IR/Rewriting/RewriterContext.cs b/Src/ILGPU/IR/Rewriting/RewriterContext.cs index 2ad390c07..b37a8c5eb 100644 --- a/Src/ILGPU/IR/Rewriting/RewriterContext.cs +++ b/Src/ILGPU/IR/Rewriting/RewriterContext.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: RewriterContext.cs @@ -43,7 +43,7 @@ public static RewriterContext FromBuilder(BasicBlock.Builder builder) => /// The set of converted value. internal RewriterContext( BasicBlock.Builder builder, - HashSet converted) + HashSet? converted) { Debug.Assert(builder != null, "Invalid builder"); @@ -68,7 +68,7 @@ internal RewriterContext( /// /// The set of all converted nodes. /// - private HashSet Converted { get; } + private HashSet? Converted { get; } #endregion @@ -88,14 +88,16 @@ public readonly RewriterContext SpecializeBuilder( /// /// The value to check. /// True, if the given value has been converted. - public readonly bool IsConverted(Value value) => Converted.Contains(value); + public readonly bool IsConverted(Value value) => + Converted != null && Converted.Contains(value); /// /// Marks the given value as converted. /// /// The value to mark. /// True, if the element has been added to the set of value. - public readonly bool MarkConverted(Value value) => Converted.Add(value); + public readonly bool MarkConverted(Value value) => + Converted != null && Converted.Add(value); /// /// Replaces the given value with the new value. diff --git a/Src/ILGPU/IR/Rewriting/SSARewriter.cs b/Src/ILGPU/IR/Rewriting/SSARewriter.cs index 24f6a2204..0a779d206 100644 --- a/Src/ILGPU/IR/Rewriting/SSARewriter.cs +++ b/Src/ILGPU/IR/Rewriting/SSARewriter.cs @@ -280,7 +280,7 @@ protected static bool ProcessSSA( } // Process terminator (if any) - Value terminator = blockBuilder.Terminator; + Value? terminator = blockBuilder.Terminator; if (terminator != null && converted.Add(terminator)) { // Move insert position to the end of the block @@ -364,7 +364,7 @@ public class SSARewriter : SSARewriter public bool TryBeginRewrite( SSABuilder ssaBuilder, out RewriterProcess rewriting) => - TryBeginRewrite(ssaBuilder, null, out rewriting); + TryBeginRewrite(ssaBuilder, string.Empty, out rewriting); /// /// Rewrites the given SSA builder on-the-fly using the method builder provided. @@ -372,6 +372,6 @@ public bool TryBeginRewrite( /// The parent SSA builder. /// True, if the rewriter could be applied. public bool Rewrite(SSABuilder ssaBuilder) => - Rewrite(ssaBuilder, null); + Rewrite(ssaBuilder, string.Empty); } } diff --git a/Src/ILGPU/IR/Transformations/CleanupBlocks.cs b/Src/ILGPU/IR/Transformations/CleanupBlocks.cs index ba6d18173..51325b4e2 100644 --- a/Src/ILGPU/IR/Transformations/CleanupBlocks.cs +++ b/Src/ILGPU/IR/Transformations/CleanupBlocks.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: CleanupBlocks.cs @@ -124,7 +124,7 @@ protected override bool PerformTransformation(Method.Builder builder) var successor = block.Successors[0]; foreach (var pred in block.Predecessors) { - pred.Terminator.RemapTargets( + pred.Terminator.AsNotNull().RemapTargets( builder[pred], new Remapper(block, successor)); } diff --git a/Src/ILGPU/IR/Transformations/CodePlacement.cs b/Src/ILGPU/IR/Transformations/CodePlacement.cs index c9073f264..252536240 100644 --- a/Src/ILGPU/IR/Transformations/CodePlacement.cs +++ b/Src/ILGPU/IR/Transformations/CodePlacement.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2022 ILGPU Project +// Copyright (c) 2022-2023 ILGPU Project // www.ilgpu.net // // File: CodePlacement.cs @@ -12,13 +12,12 @@ using ILGPU.IR.Analyses; using ILGPU.IR.Analyses.TraversalOrders; using ILGPU.IR.Values; +using ILGPU.Util; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using Dominators = ILGPU.IR.Analyses.Dominators< ILGPU.IR.Analyses.ControlFlowDirection.Forwards>; -using PostDominators = ILGPU.IR.Analyses.Dominators< - ILGPU.IR.Analyses.ControlFlowDirection.Backwards>; namespace ILGPU.IR.Transformations { @@ -698,7 +697,8 @@ protected override bool PerformTransformation( var appendMode = new AppendMode(blockMapping); foreach (var block in blocks) { - var terminatorEntry = new PlacementEntry(block.Terminator, block); + var terminatorEntry = + new PlacementEntry(block.Terminator.AsNotNull(), block); placer.PlaceRecursive(terminatorEntry, appendMode); } diff --git a/Src/ILGPU/IR/Transformations/DeadCodeElimination.cs b/Src/ILGPU/IR/Transformations/DeadCodeElimination.cs index 801df460e..0bcaf1746 100644 --- a/Src/ILGPU/IR/Transformations/DeadCodeElimination.cs +++ b/Src/ILGPU/IR/Transformations/DeadCodeElimination.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: DeadCodeElimination.cs @@ -54,7 +54,7 @@ protected override bool PerformTransformation(Method.Builder builder) } // Register all terminator value dependencies - foreach (Value node in block.Terminator) + foreach (Value node in block.Terminator.AsNotNull()) toProcess.Add(node); } diff --git a/Src/ILGPU/IR/Transformations/IfConversion.cs b/Src/ILGPU/IR/Transformations/IfConversion.cs index edb930235..3515eff6a 100644 --- a/Src/ILGPU/IR/Transformations/IfConversion.cs +++ b/Src/ILGPU/IR/Transformations/IfConversion.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2022 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: IfConversion.cs @@ -16,6 +16,7 @@ using ILGPU.Util; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using BlockCollection = ILGPU.IR.BasicBlockCollection< ILGPU.IR.Analyses.TraversalOrders.ReversePostOrder, @@ -272,7 +273,7 @@ public ConditionalAnalyzer( /// /// Gets or sets the current set of gathered blocks. /// - private HashSet Gathered { get; set; } + private HashSet? Gathered { get; set; } #endregion @@ -380,7 +381,7 @@ private readonly bool GatherNodes( // Reject blocks with side effects and check whether this is a node // that has been referenced by another region - if (current.HasSideEffects() || !Gathered.Add(current)) + if (current.HasSideEffects() || !Gathered.AsNotNull().Add(current)) return false; // Adjust the current region size @@ -412,7 +413,7 @@ private readonly bool GatherNodes( private readonly HashSet GatherPhis(Method method) { var phiValues = new HashSet(); - var gathered = Gathered; + var gathered = Gathered.AsNotNull(); method.Blocks.ForEachValue(phiValue => { foreach (var block in phiValue.Sources) @@ -688,7 +689,7 @@ private static IfBranch GetIfBranch(BasicBlock block) => /// The case value to merge. /// True, if both case values are compatible. [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool MergePhiCaseValue(ref Value currentValue, Value caseValue) + private static bool MergePhiCaseValue(ref Value? currentValue, Value caseValue) { var oldCaseValue = currentValue; currentValue = caseValue; @@ -886,7 +887,7 @@ public SuccessorsProvider( [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool IsCompatibleBlock( BasicBlock basicBlock, - out IfBranch terminator) => + [NotNullWhen(true)] out IfBranch? terminator) => // The current block must have an IfBranch terminator (terminator = basicBlock.Terminator as IfBranch) != null && // It must be dominated by the entry block in order to avoid rare cases @@ -1194,7 +1195,8 @@ private readonly bool GatherPhiValues( var innerBlocksSet = blocks.ToSet( new BlockKindPredicate(kinds, BlockKind.Inner)); - Value trueValue = null, falseValue = null; + Value? trueValue = null; + Value? falseValue = null; foreach (var phi in exitPhis) { // The phi must be located in one of our exit blocks @@ -1341,13 +1343,13 @@ public void Convert() BlockBuilder.SetupInsertPositionToEnd(); // Emit the actual condition - CreateInnerCondition(terminator, null, null, out Value condition); - EntryBlock.AssertNotNull(condition); + CreateInnerCondition(terminator, null, null, out Value? condition); + EntryBlock.AssertNotNull(condition.AsNotNull()); // Create the actual branch condition BlockBuilder.CreateIfBranch( terminator.Location, - condition, + condition.AsNotNull(), CaseBlocks.TrueBlock, CaseBlocks.FalseBlock); @@ -1386,7 +1388,7 @@ private void MergeBlocks() /// The merged condition or . /// private Value MergeCondition( - Value condition, + Value? condition, Value newCondition, BinaryArithmeticKind kind) => condition is null @@ -1408,10 +1410,10 @@ condition is null /// The exit condition to be updated. private void CreateMergedCondition( BasicBlock current, - Value condition, + Value? condition, Value newCondition, - Value initialExitCondition, - out Value exitCondition) + Value? initialExitCondition, + out Value? exitCondition) { var merged = MergeCondition( condition, @@ -1437,8 +1439,8 @@ private void CreateMergedCondition( private void CreateExitCondition( BasicBlock current, Value condition, - Value initialExitCondition, - out Value exitCondition) + Value? initialExitCondition, + out Value? exitCondition) { current.Assert(IsExit(current)); @@ -1467,9 +1469,9 @@ private void CreateExitCondition( /// The exit condition to be updated. private void CreateInnerCondition( IfBranch terminator, - Value condition, - Value initialExitCondition, - out Value exitCondition) + Value? condition, + Value? initialExitCondition, + out Value? exitCondition) { // Determine the true and false conditions, as well as the different // branch targets @@ -1533,8 +1535,8 @@ private void CreateInnerCondition( private void CreateCondition( BasicBlock current, Value condition, - Value initialExitCondition, - out Value exitCondition) + Value? initialExitCondition, + out Value? exitCondition) { if (IsExit(current)) { diff --git a/Src/ILGPU/IR/Transformations/InferAddressSpaces.cs b/Src/ILGPU/IR/Transformations/InferAddressSpaces.cs index 76506197b..f21adfcdb 100644 --- a/Src/ILGPU/IR/Transformations/InferAddressSpaces.cs +++ b/Src/ILGPU/IR/Transformations/InferAddressSpaces.cs @@ -13,7 +13,9 @@ using ILGPU.IR.Rewriting; using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using static ILGPU.IR.Analyses.PointerAddressSpaces; using static ILGPU.IR.Transformations.InferAddressSpaces; using static ILGPU.IR.Types.AddressSpaceType; @@ -116,7 +118,7 @@ internal ProcessingData(TProvider provider) /// /// Tries to pop a value from the current processing stack. /// - public readonly bool TryPop(out Value value) + public readonly bool TryPop([NotNullWhen(true)] out Value? value) { value = default; if (ToProcess.Count < 1) @@ -522,7 +524,7 @@ public sealed class MethodDataProvider /// /// The collection of methods. /// The target address space. - public static MethodDataProvider CreateProvider( + public static MethodDataProvider? CreateProvider( in MethodCollection methods, MemoryAddressSpace kernelAddressSpace) { @@ -657,7 +659,7 @@ private static Value ConvertToAddressSpace( return type == targetType ? value : context.AssembleStructure( - targetType as StructureType, + (targetType as StructureType).AsNotNull(), value, (ctx, val, access) => { @@ -866,7 +868,7 @@ public InferKernelAddressSpaces(MemoryAddressSpace kernelAddressSpace) /// Creates a new instance based on the main /// entry-point method. /// - protected override MethodDataProvider CreateIntermediate( + protected override MethodDataProvider? CreateIntermediate( in MethodCollection methods) => MethodDataProvider.CreateProvider(methods, KernelAddressSpace); @@ -876,7 +878,7 @@ protected override MethodDataProvider CreateIntermediate( protected override bool PerformTransformation( IRContext context, Method.Builder builder, - in MethodDataProvider intermediate, + in MethodDataProvider? intermediate, Landscape landscape, Landscape.Entry current) { @@ -919,7 +921,7 @@ protected override bool PerformTransformation( /// /// Performs no operation. /// - protected override void FinishProcessing(in MethodDataProvider intermediate) { } + protected override void FinishProcessing(in MethodDataProvider? intermediate) { } #endregion } diff --git a/Src/ILGPU/IR/Transformations/Inliner.cs b/Src/ILGPU/IR/Transformations/Inliner.cs index a8a38d455..2bc8a0527 100644 --- a/Src/ILGPU/IR/Transformations/Inliner.cs +++ b/Src/ILGPU/IR/Transformations/Inliner.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Inliner.cs @@ -142,7 +142,7 @@ protected override bool PerformTransformation( continue; } - var successors = currentBlock.Terminator.Targets; + var successors = currentBlock.CurrentSuccessors; if (successors.Length > 0) { currentBlock = successors[0]; diff --git a/Src/ILGPU/IR/Transformations/IntrinsicSpecializer.cs b/Src/ILGPU/IR/Transformations/IntrinsicSpecializer.cs index 33d5d8d64..4f0e02b06 100644 --- a/Src/ILGPU/IR/Transformations/IntrinsicSpecializer.cs +++ b/Src/ILGPU/IR/Transformations/IntrinsicSpecializer.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: IntrinsicSpecializer.cs @@ -41,7 +41,7 @@ private static void ImportDependencies( for (int i = 0, e = dependencies.Count; i < e; ++i) { var (node, intrinsic) = dependencies[i]; - if (!importedFunctions.TryGetValue(intrinsic, out Method imported)) + if (!importedFunctions.TryGetValue(intrinsic, out Method? imported)) { imported = targetContext.Import(intrinsic); importedFunctions.Add(intrinsic, imported); diff --git a/Src/ILGPU/IR/Transformations/LoopUnrolling.cs b/Src/ILGPU/IR/Transformations/LoopUnrolling.cs index a213d9e36..f992c4c0d 100644 --- a/Src/ILGPU/IR/Transformations/LoopUnrolling.cs +++ b/Src/ILGPU/IR/Transformations/LoopUnrolling.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2022 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: LoopUnrolling.cs @@ -59,7 +59,7 @@ public sealed class LoopUnrolling : UnorderedTransformation public LoopRemapper( BasicBlock source, BasicBlock target, - Value targetValue = null) + Value? targetValue = null) { Source = source; Target = target; @@ -79,7 +79,7 @@ public LoopRemapper( /// /// Returns the target value to map phi operands to (if any). /// - public Value TargetValue { get; } + public Value? TargetValue { get; } /// /// Returns true if the given span contains the loop entry. @@ -120,7 +120,9 @@ public readonly Value RemapValue( PhiValue phiValue, BasicBlock updatedBlock, Value value) => - updatedBlock == Target ? TargetValue : value; + updatedBlock == Target && TargetValue != null + ? TargetValue + : value; } /// @@ -169,7 +171,7 @@ public LoopSpecializer( loopInfo.Exit, out var loopBody); variable.BreakBranch.Assert(hasOtherTarget); - LoopBody = loopBody; + LoopBody = loopBody.AsNotNull(); BackEdge = loopInfo.BackEdge; // Determine all values in the body of the loop that require value @@ -315,7 +317,7 @@ private readonly Dictionary CreateValueRebuilderMapping( foreach (var (phi, _) in phiValues) { // Get the corresponding phi value for the back-edge predecessor - var backEdgeValue = phi.GetValue(BackEdge); + var backEdgeValue = phi.GetValue(BackEdge).AsNotNull(); phi.AssertNotNull(backEdgeValue); phiMapping[phi] = rebuilder[backEdgeValue]; } @@ -332,7 +334,7 @@ private readonly Dictionary CreateValueRebuilderMapping( // straight-line piece of code var backEdgeBlock = rebuilder[BackEdge]; backEdgeBlock.CreateBranch( - backEdgeBlock.Terminator.Location, + backEdgeBlock.Terminator.AsNotNull().Location, currentExit); return (rebuilder.EntryBlock, currentExit); diff --git a/Src/ILGPU/IR/Transformations/LowerArrays.cs b/Src/ILGPU/IR/Transformations/LowerArrays.cs index 7ca7bdd53..503ddc5d2 100644 --- a/Src/ILGPU/IR/Transformations/LowerArrays.cs +++ b/Src/ILGPU/IR/Transformations/LowerArrays.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: LowerArrays.cs @@ -14,6 +14,7 @@ using ILGPU.IR.Types; using ILGPU.IR.Values; using ILGPU.Resources; +using ILGPU.Util; using System.Diagnostics.CodeAnalysis; namespace ILGPU.IR.Transformations @@ -110,6 +111,7 @@ private static void Lower( var builder = context.Builder; var location = value.Location; var targetAddressSpace = (typeLowering as ArrayTypeLowering) + .AsNotNull() .TargetAddressSpace; // Compute array length diff --git a/Src/ILGPU/IR/Transformations/LowerStructures.cs b/Src/ILGPU/IR/Transformations/LowerStructures.cs index 191ef30e4..2fe62b61d 100644 --- a/Src/ILGPU/IR/Transformations/LowerStructures.cs +++ b/Src/ILGPU/IR/Transformations/LowerStructures.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: LowerStructures.cs @@ -13,6 +13,7 @@ using ILGPU.IR.Rewriting; using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; using System; using System.Collections.Generic; @@ -98,7 +99,7 @@ private static void LowerThreadValue( var newValue = implementation.Lower( context.Builder, value, - variable).ResolveAs(); + variable).ResolveAs().AsNotNull(); // Disassemble the resulting structure value DisassembleStructure(context, structureType, newValue); @@ -199,7 +200,7 @@ private static void Keep( Load load) => DisassembleStructure( context, - load.Type as StructureType, + load.Type.AsNotNullCast(), load); /// @@ -211,7 +212,7 @@ private static void Lower( Load load) { var builder = context.Builder; - foreach (var (_, fieldAccess) in load.Type as StructureType) + foreach (var (_, fieldAccess) in load.Type.AsNotNullCast()) { // Update source address var address = builder.CreateLoadFieldAddress( @@ -240,7 +241,7 @@ private static void Keep( { var newValue = AssembleStructure( context, - store.Value.Type as StructureType, + store.Value.Type.AsNotNullCast(), store.Value); var newStore = context.Builder.CreateStore( store.Location, @@ -258,7 +259,8 @@ private static void Lower( Store store) { var builder = context.Builder; - foreach (var (_, fieldAccess) in store.Value.Type as StructureType) + var structureType = store.Value.Type.AsNotNullCast(); + foreach (var (_, fieldAccess) in structureType) { // Update target address var address = builder.CreateLoadFieldAddress( @@ -287,7 +289,8 @@ private static void Lower( LoweringData _, NullValue nullValue) { - foreach (var (fieldType, fieldAccess) in nullValue.Type as StructureType) + var structureType = nullValue.Type.AsNotNullCast(); + foreach (var (fieldType, fieldAccess) in structureType) { // Build the new target value var value = context.Builder.CreateNull( @@ -369,7 +372,7 @@ private static void Lower( LoweringData _, SetField setField) { - foreach (var (_, fieldAccess) in setField.Type as StructureType) + foreach (var (_, fieldAccess) in setField.Type.AsNotNullCast()) { Value value; if (setField.FieldSpan.Contains(fieldAccess)) @@ -410,7 +413,8 @@ private static void Lower( LoweringData data, PhiValue phi) { - foreach (var (fieldType, fieldAccess) in phi.Type as StructureType) + var structureType = phi.Type.AsNotNullCast(); + foreach (var (fieldType, fieldAccess) in structureType) { // Build a new phi which might become dead in the future var phiBuilder = context.Builder.CreatePhi( @@ -437,7 +441,8 @@ private static void Lower( LoweringData _, Predicate predicate) { - foreach (var (_, fieldAccess) in predicate.Type as StructureType) + var structureType = predicate.Type.AsNotNullCast(); + foreach (var (_, fieldAccess) in structureType) { // Build a new if predicate which might become dead in the future var trueValue = context.GetValue( @@ -508,7 +513,7 @@ private static void Lower( Broadcast, LowerThreadIntrinsics.BroadcastLowering>( context, - value.Type as StructureType, + value.Type.AsNotNullCast(), value); /// @@ -522,7 +527,7 @@ private static void Lower( WarpShuffle, LowerThreadIntrinsics.WarpShuffleLowering>( context, - value.Type as StructureType, + value.Type.AsNotNullCast(), value); /// @@ -536,7 +541,7 @@ private static void Lower( SubWarpShuffle, LowerThreadIntrinsics.SubWarpShuffleLowering>( context, - value.Type as StructureType, + value.Type.AsNotNullCast(), value); /// diff --git a/Src/ILGPU/IR/Transformations/LowerThreadIntrinsics.cs b/Src/ILGPU/IR/Transformations/LowerThreadIntrinsics.cs index caae572ca..9ecd90142 100644 --- a/Src/ILGPU/IR/Transformations/LowerThreadIntrinsics.cs +++ b/Src/ILGPU/IR/Transformations/LowerThreadIntrinsics.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: LowerThreadIntrinsics.cs @@ -12,6 +12,7 @@ using ILGPU.IR.Rewriting; using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; using System.Runtime.CompilerServices; namespace ILGPU.IR.Transformations @@ -127,7 +128,7 @@ private static Value LowerPrimitive( where TLoweringImplementation : struct, ILoweringImplementation { var builder = context.Builder; - var primitiveType = variable.Type as PrimitiveType; + var primitiveType = variable.Type.AsNotNullCast(); Value value = variable; if (primitiveType.BasicValueType < BasicValueType.Int32) { diff --git a/Src/ILGPU/IR/Transformations/LowerTypes.cs b/Src/ILGPU/IR/Transformations/LowerTypes.cs index 6bb97c626..e43f7ea18 100644 --- a/Src/ILGPU/IR/Transformations/LowerTypes.cs +++ b/Src/ILGPU/IR/Transformations/LowerTypes.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: LowerTypes.cs @@ -12,6 +12,7 @@ using ILGPU.IR.Rewriting; using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; using System.Runtime.CompilerServices; namespace ILGPU.IR.Transformations @@ -54,10 +55,10 @@ protected static void Lower( var builder = context.Builder; var location = value.Location; - var sourceType = typeConverter[value] as StructureType; + var sourceType = typeConverter[value].AsNotNullCast(); var instance = builder.CreateStructure( location, - typeConverter.ConvertType(sourceType) as StructureType); + typeConverter.ConvertType(sourceType).AsNotNullCast()); for (int i = 0, e = sourceType.NumFields; i < e; ++i) { diff --git a/Src/ILGPU/IR/Transformations/LowerViews.cs b/Src/ILGPU/IR/Transformations/LowerViews.cs index 7d072e4b1..60565f59b 100644 --- a/Src/ILGPU/IR/Transformations/LowerViews.cs +++ b/Src/ILGPU/IR/Transformations/LowerViews.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: LowerViews.cs @@ -26,11 +26,6 @@ public abstract class LowerViews : LowerTypes /// protected abstract class ViewTypeLowering : TypeLowering { - /// - /// Constructs a new type lowering without a parent type context. - /// - protected ViewTypeLowering() { } - /// /// Constructs a new type lowering. /// diff --git a/Src/ILGPU/IR/Transformations/SSAConstruction.cs b/Src/ILGPU/IR/Transformations/SSAConstruction.cs index f01590560..b2227f7a8 100644 --- a/Src/ILGPU/IR/Transformations/SSAConstruction.cs +++ b/Src/ILGPU/IR/Transformations/SSAConstruction.cs @@ -13,6 +13,7 @@ using ILGPU.IR.Rewriting; using ILGPU.IR.Types; using ILGPU.IR.Values; +using ILGPU.Util; using System; using System.Collections.Generic; using System.Diagnostics; @@ -747,7 +748,8 @@ private static void Convert( // Get the builder and the associated array length value var builder = context.Builder; - var arrayLengthValue = alloca.ArrayLength.ResolveAs(); + var arrayLengthValue = + alloca.ArrayLength.ResolveAs().AsNotNull(); alloca.AssertNotNull(arrayLengthValue); int arrayLength = arrayLengthValue.Int32Value; @@ -845,7 +847,8 @@ private static void Convert( return; // Get the primitive constant field offset - var fieldOffset = loadElementAddress.Offset.ResolveAs(); + var fieldOffset = + loadElementAddress.Offset.ResolveAs().AsNotNull(); loadElementAddress.AssertNotNull(fieldOffset); var fieldAccess = new FieldAccess( fieldOffset.Int32Value * leaData.NumElementFields); diff --git a/Src/ILGPU/IR/Transformations/Transformation.cs b/Src/ILGPU/IR/Transformations/Transformation.cs index 04f427790..b223f2f0c 100644 --- a/Src/ILGPU/IR/Transformations/Transformation.cs +++ b/Src/ILGPU/IR/Transformations/Transformation.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Transformation.cs @@ -458,7 +458,7 @@ public abstract class OrderedTransformation : Transformation public Executor( OrderedTransformation parent, IRContext context, - TIntermediate intermediate, + TIntermediate? intermediate, Landscape landscape, Landscape.Entry entry) { @@ -482,7 +482,7 @@ public Executor( /// /// Returns the associated intermediate value. /// - public TIntermediate Intermediate { get; } + public TIntermediate? Intermediate { get; } /// /// Returns the current landscape. @@ -526,13 +526,13 @@ protected OrderedTransformation() { } /// Creates a new intermediate value. /// /// The resulting intermediate value. - protected abstract TIntermediate CreateIntermediate(in MethodCollection methods); + protected abstract TIntermediate? CreateIntermediate(in MethodCollection methods); /// /// Is invoked after all methods have been transformed. /// /// The current intermediate value. - protected abstract void FinishProcessing(in TIntermediate intermediate); + protected abstract void FinishProcessing(in TIntermediate? intermediate); /// /// Transforms all methods in the given context. @@ -573,7 +573,7 @@ public sealed override void Transform(in MethodCollection methods) protected abstract bool PerformTransformation( IRContext context, Method.Builder builder, - in TIntermediate intermediate, + in TIntermediate? intermediate, Landscape landscape, Landscape.Entry current); @@ -601,14 +601,14 @@ protected OrderedTransformation() { } /// Creates a new intermediate value. /// /// The resulting intermediate value. - protected sealed override object CreateIntermediate( + protected sealed override object? CreateIntermediate( in MethodCollection methods) => null; /// /// Is invoked after all methods have been transformed. /// /// The current intermediate value. - protected sealed override void FinishProcessing(in object intermediate) { } + protected sealed override void FinishProcessing(in object? intermediate) { } /// /// Transforms the given method using the provided builder. @@ -621,7 +621,7 @@ protected sealed override void FinishProcessing(in object intermediate) { } protected sealed override bool PerformTransformation( IRContext context, Method.Builder builder, - in object intermediate, + in object? intermediate, Landscape landscape, Landscape.Entry current) => PerformTransformation(context, builder, landscape, current); diff --git a/Src/ILGPU/IR/Types/ArrayType.cs b/Src/ILGPU/IR/Types/ArrayType.cs index 8dd6e042f..77bd17f91 100644 --- a/Src/ILGPU/IR/Types/ArrayType.cs +++ b/Src/ILGPU/IR/Types/ArrayType.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2022 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: ArrayType.cs @@ -81,8 +81,8 @@ protected override Type GetManagedType() => public override int GetHashCode() => base.GetHashCode() ^ 0x3C11A78B ^ NumDimensions; - /// - public override bool Equals(object obj) => + /// + public override bool Equals(object? obj) => obj is ArrayType arrayType && arrayType.ElementType == ElementType && arrayType.NumDimensions == NumDimensions && diff --git a/Src/ILGPU/IR/Types/HandleType.cs b/Src/ILGPU/IR/Types/HandleType.cs index 1ae2a986d..cb0e01486 100644 --- a/Src/ILGPU/IR/Types/HandleType.cs +++ b/Src/ILGPU/IR/Types/HandleType.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: HandleType.cs @@ -48,8 +48,8 @@ internal HandleType(IRTypeContext typeContext) public override int GetHashCode() => base.GetHashCode() ^ 0xAA713C3; - /// - public override bool Equals(object obj) => + /// + public override bool Equals(object? obj) => obj is HandleType && base.Equals(obj); #endregion diff --git a/Src/ILGPU/IR/Types/IIRTypeContext.cs b/Src/ILGPU/IR/Types/IIRTypeContext.cs index a4aaac849..db995801c 100644 --- a/Src/ILGPU/IR/Types/IIRTypeContext.cs +++ b/Src/ILGPU/IR/Types/IIRTypeContext.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: IIRTypeContext.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using System; +using System.Diagnostics.CodeAnalysis; namespace ILGPU.IR.Types { @@ -106,7 +107,7 @@ AddressSpaceType SpecializeAddressSpaceType( bool TrySpecializeAddressSpaceType( TypeNode type, MemoryAddressSpace addressSpace, - out TypeNode specializedType); + [NotNullWhen(true)] out TypeNode? specializedType); } /// diff --git a/Src/ILGPU/IR/Types/IRBaseContext.Types.cs b/Src/ILGPU/IR/Types/IRBaseContext.Types.cs index e3b2c4547..e56abe511 100644 --- a/Src/ILGPU/IR/Types/IRBaseContext.Types.cs +++ b/Src/ILGPU/IR/Types/IRBaseContext.Types.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: IRBaseContext.Types.cs @@ -11,6 +11,7 @@ using ILGPU.IR.Types; using System; +using System.Diagnostics.CodeAnalysis; namespace ILGPU.IR { @@ -117,7 +118,7 @@ public AddressSpaceType SpecializeAddressSpaceType( public bool TrySpecializeAddressSpaceType( TypeNode type, MemoryAddressSpace addressSpace, - out TypeNode specializedType) => + [NotNullWhen(true)] out TypeNode? specializedType) => TypeContext.TrySpecializeAddressSpaceType( type, addressSpace, diff --git a/Src/ILGPU/IR/Types/IRTypeContext.cs b/Src/ILGPU/IR/Types/IRTypeContext.cs index 2659e2ec1..328e5ad27 100644 --- a/Src/ILGPU/IR/Types/IRTypeContext.cs +++ b/Src/ILGPU/IR/Types/IRTypeContext.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: IRTypeContext.cs @@ -166,11 +166,6 @@ public IRTypeContext(Context context) /// public PaddingType Padding64Type { get; } - /// - /// Returns a dense 1D stride type (). - /// - public TypeNode Dense1DStrideType { get; } - #endregion #region Methods @@ -373,7 +368,7 @@ private TypeNode CreateType_Sync(Type type, MemoryAddressSpace addressSpace) else if (type.IsArray) { var arrayElementType = CreateType_Sync( - type.GetElementType(), + type.GetElementType().AsNotNull(), addressSpace); var dimension = type.GetArrayRank(); return Map( @@ -381,7 +376,7 @@ private TypeNode CreateType_Sync(Type type, MemoryAddressSpace addressSpace) addressSpace, CreateArrayType(arrayElementType, dimension)); } - else if (type.IsArrayViewType(out Type elementType)) + else if (type.IsArrayViewType(out Type? elementType)) { return Map( type, @@ -403,7 +398,7 @@ private TypeNode CreateType_Sync(Type type, MemoryAddressSpace addressSpace) type, addressSpace, CreatePointerType( - CreateType_Sync(type.GetElementType(), addressSpace), + CreateType_Sync(type.GetElementType().AsNotNull(), addressSpace), addressSpace)); } else if (type.IsClass) @@ -459,7 +454,7 @@ public AddressSpaceType SpecializeAddressSpaceType( } else { - var viewType = addressSpaceType as ViewType; + var viewType = addressSpaceType.AsNotNullCast(); return CreateViewType( viewType.ElementType, addressSpace); @@ -476,7 +471,7 @@ public AddressSpaceType SpecializeAddressSpaceType( public bool TrySpecializeAddressSpaceType( TypeNode type, MemoryAddressSpace addressSpace, - out TypeNode specializedType) + [NotNullWhen(true)] out TypeNode? specializedType) { Debug.Assert(type != null, "Invalid type"); @@ -498,8 +493,8 @@ private T UnifyType(T type) // Synchronize all accesses below using a read/write scope using var readWriteScope = typeLock.EnterUpgradeableReadScope(); - if (unifiedTypes.TryGetValue(type, out TypeNode result)) - return result as T; + if (unifiedTypes.TryGetValue(type, out TypeNode? result)) + return result.AsNotNullCast(); // Synchronize all accesses below using a write scope using var writeScope = typeLock.EnterWriteScope(); diff --git a/Src/ILGPU/IR/Types/PaddingType.cs b/Src/ILGPU/IR/Types/PaddingType.cs index 9612a5e99..65ee5d45f 100644 --- a/Src/ILGPU/IR/Types/PaddingType.cs +++ b/Src/ILGPU/IR/Types/PaddingType.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2022 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: PaddingType.cs @@ -58,7 +58,8 @@ internal PaddingType(IRTypeContext typeContext, PrimitiveType primitiveType) /// /// Returns the corresponding managed basic value type. /// - protected override Type GetManagedType() => BasicValueType.GetManagedType(); + protected override Type GetManagedType() => + BasicValueType.GetManagedType().AsNotNull(); #endregion @@ -72,8 +73,8 @@ protected override string ToPrefixString() => public override int GetHashCode() => base.GetHashCode() ^ 0x2AB11613 ^ (int)BasicValueType; - /// - public override bool Equals(object obj) => + /// + public override bool Equals(object? obj) => obj is PaddingType paddingType && paddingType.BasicValueType == BasicValueType; diff --git a/Src/ILGPU/IR/Types/PointerTypes.cs b/Src/ILGPU/IR/Types/PointerTypes.cs index 7e86feabf..00f8c165d 100644 --- a/Src/ILGPU/IR/Types/PointerTypes.cs +++ b/Src/ILGPU/IR/Types/PointerTypes.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: PointerTypes.cs @@ -132,8 +132,8 @@ protected AddressSpaceType( public override int GetHashCode() => base.GetHashCode() ^ (int)AddressSpace; - /// - public override bool Equals(object obj) => + /// + public override bool Equals(object? obj) => obj is AddressSpaceType type && type.AddressSpace == AddressSpace && type.ElementType == ElementType && @@ -211,8 +211,8 @@ protected override Type GetManagedType() => public override int GetHashCode() => base.GetHashCode() ^ 0x2FE10E2A; - /// - public override bool Equals(object obj) => + /// + public override bool Equals(object? obj) => obj is PointerType && base.Equals(obj); #endregion @@ -270,8 +270,8 @@ protected override Type GetManagedType() => public override int GetHashCode() => base.GetHashCode() ^ 0x11A34102; - /// - public override bool Equals(object obj) => + /// + public override bool Equals(object? obj) => obj is ViewType && base.Equals(obj); #endregion diff --git a/Src/ILGPU/IR/Types/PrimitiveTypes.cs b/Src/ILGPU/IR/Types/PrimitiveTypes.cs index 649ff5ed8..0b6d0f805 100644 --- a/Src/ILGPU/IR/Types/PrimitiveTypes.cs +++ b/Src/ILGPU/IR/Types/PrimitiveTypes.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: PrimitiveTypes.cs @@ -118,7 +118,8 @@ internal PrimitiveType(IRTypeContext typeContext, BasicValueType basicValueType) /// /// Returns the corresponding managed basic value type. /// - protected override Type GetManagedType() => BasicValueType.GetManagedType(); + protected override Type GetManagedType() => + BasicValueType.GetManagedType().AsNotNull(); #endregion @@ -132,8 +133,8 @@ protected override string ToPrefixString() => public override int GetHashCode() => base.GetHashCode() ^ 0x2AB11613 ^ (int)BasicValueType; - /// - public override bool Equals(object obj) => + /// + public override bool Equals(object? obj) => obj is PrimitiveType primitiveType && primitiveType.BasicValueType == BasicValueType; @@ -182,8 +183,8 @@ internal StringType(IRTypeContext typeContext) public override int GetHashCode() => base.GetHashCode() ^ 0x3D12C251; - /// - public override bool Equals(object obj) => + /// + public override bool Equals(object? obj) => obj is StringType && base.Equals(obj); #endregion diff --git a/Src/ILGPU/IR/Types/StructureType.cs b/Src/ILGPU/IR/Types/StructureType.cs index 30e9558d2..60c99c9dc 100644 --- a/Src/ILGPU/IR/Types/StructureType.cs +++ b/Src/ILGPU/IR/Types/StructureType.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: StructureType.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.IR.Values; +using ILGPU.Util; using System; using System.Collections; using System.Collections.Generic; @@ -889,7 +890,7 @@ private void SliceRecursive( else if (nestedSpan.Contains(span)) { // This must be a nested structure - (type as StructureType).SliceRecursive( + type.AsNotNullCast().SliceRecursive( ref builder, ref index, span); @@ -954,8 +955,8 @@ protected override Type GetManagedType() /// public override int GetHashCode() => hashCode; - /// - public override bool Equals(object obj) + /// + public override bool Equals(object? obj) { if (!(obj is StructureType structureType) || structureType.NumFields != NumFields) diff --git a/Src/ILGPU/IR/Types/TypeConverter.cs b/Src/ILGPU/IR/Types/TypeConverter.cs index 6e1ae6cec..696f62f9e 100644 --- a/Src/ILGPU/IR/Types/TypeConverter.cs +++ b/Src/ILGPU/IR/Types/TypeConverter.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: TypeConverter.cs @@ -11,6 +11,7 @@ using ILGPU.IR.Construction; using ILGPU.IR.Values; +using ILGPU.Util; using System.Collections.Generic; using System.Diagnostics; @@ -116,11 +117,6 @@ public abstract class TypeLowering : TypeConverter private readonly Dictionary typeMapping = new Dictionary(); - /// - /// Constructs a new type lowering without a parent type context. - /// - protected TypeLowering() { } - /// /// Constructs a new type lowering. /// @@ -186,7 +182,7 @@ public TypeNode ConvertType(TypeNode type) /// The target field span. public FieldSpan ComputeSpan(Value value, FieldSpan fieldSpan) { - var sourceType = this[value] as StructureType; + var sourceType = this[value].AsNotNullCast(); int sourceIndex = fieldSpan.Index; int index = 0; for (int i = 0; i < sourceIndex; ++i) diff --git a/Src/ILGPU/IR/Types/TypeInformationManager.cs b/Src/ILGPU/IR/Types/TypeInformationManager.cs index 67991ea2e..a68b7b3bb 100644 --- a/Src/ILGPU/IR/Types/TypeInformationManager.cs +++ b/Src/ILGPU/IR/Types/TypeInformationManager.cs @@ -15,6 +15,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Runtime.InteropServices; using System.Threading; @@ -147,7 +148,9 @@ public TypeInformation GetFieldTypeInfo(int index) => /// The target index. /// The resolved field. /// True, if the field could be resolved. - public bool TryResolveField(int index, out FieldInfo field) + public bool TryResolveField( + int index, + [NotNullWhen(true)] out FieldInfo? field) { field = default; if (index < 0 || index >= NumFields) @@ -241,7 +244,7 @@ public TypeInformation GetTypeInfo(Type type) // Synchronize all accesses below using a read/write scope using var readWriteScope = cachingLock.EnterUpgradeableReadScope(); - if (!typeInfoMapping.TryGetValue(type, out TypeInformation typeInfo)) + if (!typeInfoMapping.TryGetValue(type, out TypeInformation? typeInfo)) { // Synchronize all accesses below using a write scope using var writeScope = readWriteScope.EnterWriteScope(); @@ -258,7 +261,7 @@ public TypeInformation GetTypeInfo(Type type) /// The resolved type information. private TypeInformation GetTypeInfoInternal(Type type) { - if (!typeInfoMapping.TryGetValue(type, out TypeInformation typeInfo)) + if (!typeInfoMapping.TryGetValue(type, out TypeInformation? typeInfo)) typeInfo = CreateTypeInfo(type); return typeInfo; } @@ -315,7 +318,7 @@ private TypeInformation CreateTypeInfo(Type type) // Check for pointers and arrays if (type.IsPointer || type.IsByRef || type.IsArray) { - var elementInfo = GetTypeInfoInternal(type.GetElementType()); + var elementInfo = GetTypeInfoInternal(type.GetElementType().AsNotNull()); result = AddTypeInfo(type, elementInfo.IsBlittable); } // Check for enum types @@ -325,7 +328,7 @@ private TypeInformation CreateTypeInfo(Type type) result = AddTypeInfo(type, baseInfo.IsBlittable); } // Check for opaque view types - else if (type.IsArrayViewType(out Type elementType)) + else if (type.IsArrayViewType(out Type? elementType)) { var elementInfo = GetTypeInfoInternal(elementType); result = AddTypeInfo(type, false, elementInfo.IsBlittable); diff --git a/Src/ILGPU/IR/Types/TypeNode.cs b/Src/ILGPU/IR/Types/TypeNode.cs index 0c1887759..a52d3a32d 100644 --- a/Src/ILGPU/IR/Types/TypeNode.cs +++ b/Src/ILGPU/IR/Types/TypeNode.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: TypeNode.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.Resources; +using ILGPU.Util; using System; using System.Runtime.CompilerServices; @@ -101,7 +102,7 @@ public static int Align(int offset, int fieldAlignment) => /// /// The managed type representation of this IR type. /// - private Type managedType; + private Type? managedType; /// /// Constructs a new type. @@ -257,7 +258,7 @@ public bool HasFlags(TypeFlags typeFlags) => public T As(ILocation location) where T : TypeNode { - var result = this as T; + var result = this.AsNotNullCast(); location.AssertNotNull(result); return result; } @@ -291,7 +292,7 @@ public override string FormatErrorMessage(string message) => /// /// The other object. /// True, if the given object is equal to the current type. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is TypeNode; /// diff --git a/Src/ILGPU/IR/Types/ValueTuples.tt b/Src/ILGPU/IR/Types/ValueTuples.tt index 7bc085da8..303b49e27 100644 --- a/Src/ILGPU/IR/Types/ValueTuples.tt +++ b/Src/ILGPU/IR/Types/ValueTuples.tt @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2016-2021 ILGPU Project +// Copyright (c) 2016-2023 ILGPU Project // www.ilgpu.net // // File: ValueTuples.tt/ValueTuples.cs @@ -12,6 +12,7 @@ <#@ assembly name="System.Core" #> <#@ import namespace="System.Linq" #> <#@ output extension=".cs" #> +using ILGPU.Util; using System; using System.Reflection; <# @@ -52,7 +53,7 @@ namespace ILGPU.IR.Types _ => throw new NotImplementedException() }; var method = methodInfo.MakeGenericMethod(types); - return (int[])method.Invoke(null, null); + return method.Invoke(null, null).AsNotNullCast(); } private static unsafe int CalculateOffset(byte* current, byte* baseline) => @@ -83,7 +84,8 @@ namespace ILGPU.IR.Types private static readonly MethodInfo GetOffsetsMethod<#= type.NumParams #> = typeof(ValueTuples).GetMethod( nameof(GetOffsets<#= type.NumParams #>), - BindingFlags.NonPublic | BindingFlags.Static); + BindingFlags.NonPublic | BindingFlags.Static) + .ThrowIfNull(); <# } #> #endregion diff --git a/Src/ILGPU/IR/Types/VoidType.cs b/Src/ILGPU/IR/Types/VoidType.cs index ce31f0aee..931379e89 100644 --- a/Src/ILGPU/IR/Types/VoidType.cs +++ b/Src/ILGPU/IR/Types/VoidType.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: VoidType.cs @@ -55,8 +55,8 @@ internal VoidType(IRTypeContext typeContext) public override int GetHashCode() => base.GetHashCode() ^ 0x3F671AC4; - /// - public override bool Equals(object obj) => + /// + public override bool Equals(object? obj) => obj is VoidType && base.Equals(obj); #endregion diff --git a/Src/ILGPU/IR/ValueBuilder.cs b/Src/ILGPU/IR/ValueBuilder.cs index 6fc9dd66b..f89fef0a3 100644 --- a/Src/ILGPU/IR/ValueBuilder.cs +++ b/Src/ILGPU/IR/ValueBuilder.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: ValueBuilder.cs @@ -11,6 +11,7 @@ using ILGPU.IR.Construction; using ILGPU.IR.Values; +using ILGPU.Util; namespace ILGPU.IR { @@ -137,6 +138,6 @@ public ValueBuilder(TBuilder builder) /// /// The resulting value reference. public T SealAs() - where T : Value => Seal().ResolveAs(); + where T : Value => Seal().ResolveAs().AsNotNull(); } } diff --git a/Src/ILGPU/IR/Values/Arithmetic.cs b/Src/ILGPU/IR/Values/Arithmetic.cs index 484ddbe9e..c2b26a726 100644 --- a/Src/ILGPU/IR/Values/Arithmetic.cs +++ b/Src/ILGPU/IR/Values/Arithmetic.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Arithmetic.cs @@ -71,7 +71,7 @@ internal ArithmeticValue(in ValueInitializer initializer, ArithmeticFlags flags) /// /// Returns the associated type. /// - public PrimitiveType PrimitiveType => Type as PrimitiveType; + public PrimitiveType PrimitiveType => Type.AsNotNullCast(); /// /// Returns the operation flags. diff --git a/Src/ILGPU/IR/Values/ArrayValues.cs b/Src/ILGPU/IR/Values/ArrayValues.cs index bd63810fc..795e24980 100644 --- a/Src/ILGPU/IR/Values/ArrayValues.cs +++ b/Src/ILGPU/IR/Values/ArrayValues.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2022 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: ArrayValues.cs @@ -11,6 +11,7 @@ using ILGPU.IR.Construction; using ILGPU.IR.Types; +using ILGPU.Util; using System.Runtime.CompilerServices; using ValueList = ILGPU.Util.InlineList; @@ -127,7 +128,7 @@ internal NewArray( /// /// Returns the array type of this value. /// - public new ArrayType Type => base.Type as ArrayType; + public new ArrayType Type => base.Type.AsNotNullCast(); /// /// Returns the array's element type. diff --git a/Src/ILGPU/IR/Values/Atomic.cs b/Src/ILGPU/IR/Values/Atomic.cs index b62f35d6f..090546364 100644 --- a/Src/ILGPU/IR/Values/Atomic.cs +++ b/Src/ILGPU/IR/Values/Atomic.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Atomic.cs @@ -166,7 +166,8 @@ internal GenericAtomic( AtomicFlags flags) : base(initializer, flags) { - Debug.Assert(value.Type == (target.Type as PointerType).ElementType); + Debug.Assert(value.Type == + target.Type.AsNotNullCast().ElementType); Kind = kind; Seal(target, value); @@ -239,7 +240,8 @@ internal AtomicCAS( AtomicFlags flags) : base(initializer, flags) { - Debug.Assert(value.Type == (target.Type as PointerType).ElementType); + Debug.Assert(value.Type == + target.Type.AsNotNullCast().ElementType); Debug.Assert(value.Type == compareValue.Type); Seal(target, value, compareValue); diff --git a/Src/ILGPU/IR/Values/Cast.cs b/Src/ILGPU/IR/Values/Cast.cs index 334dff87c..12ddf48a1 100644 --- a/Src/ILGPU/IR/Values/Cast.cs +++ b/Src/ILGPU/IR/Values/Cast.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Cast.cs @@ -248,12 +248,13 @@ internal BaseAddressSpaceCast( /// /// Returns the associated type. /// - public new AddressSpaceType Type => base.Type as AddressSpaceType; + public new AddressSpaceType Type => base.Type.AsNotNullCast(); /// /// Returns the source type. /// - public new AddressSpaceType SourceType => base.SourceType as AddressSpaceType; + public new AddressSpaceType SourceType => + base.SourceType.AsNotNullCast(); #endregion } @@ -291,7 +292,8 @@ internal PointerCast( /// /// Returns the source element type. /// - public TypeNode SourceElementType => (Value.Type as PointerType).ElementType; + public TypeNode SourceElementType => + Value.Type.AsNotNullCast().ElementType; /// /// Returns the target element type. @@ -359,7 +361,8 @@ internal AddressSpaceCast( TargetAddressSpace = targetAddressSpace; initializer.Assert( value.Type.IsViewOrPointerType && - (value.Type as AddressSpaceType).AddressSpace != targetAddressSpace); + value.Type.AsNotNullCast().AddressSpace != + targetAddressSpace); } #endregion @@ -399,7 +402,7 @@ protected override TypeNode ComputeType(in ValueInitializer initializer) } else { - var pointerType = SourceType as PointerType; + var pointerType = SourceType.AsNotNullCast(); return initializer.Context.CreatePointerType( pointerType.ElementType, TargetAddressSpace); @@ -464,7 +467,8 @@ internal ViewCast( /// /// Returns the source element type. /// - public TypeNode SourceElementType => (SourceType as ViewType).ElementType; + public TypeNode SourceElementType => + SourceType.AsNotNullCast().ElementType; /// /// Returns the target element type. @@ -540,7 +544,7 @@ internal ArrayToViewCast( /// /// Returns the array type of the source value. /// - public new ArrayType SourceType => base.SourceType as ArrayType; + public new ArrayType SourceType => base.SourceType.AsNotNullCast(); /// /// Returns the array element type. diff --git a/Src/ILGPU/IR/Values/ClassValues.cs b/Src/ILGPU/IR/Values/ClassValues.cs index 19a94a67a..0f4314208 100644 --- a/Src/ILGPU/IR/Values/ClassValues.cs +++ b/Src/ILGPU/IR/Values/ClassValues.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: ClassValues.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.IR.Types; +using ILGPU.Util; namespace ILGPU.IR.Values { @@ -58,7 +59,7 @@ internal ClassOperationValue(in ValueInitializer initializer) /// /// Returns the object type. /// - public ObjectType ObjectType => ObjectValue.Type as ObjectType; + public ObjectType ObjectType => ObjectValue.Type.AsNotNullCast(); #endregion } diff --git a/Src/ILGPU/IR/Values/Constants.cs b/Src/ILGPU/IR/Values/Constants.cs index 1ec644b32..b88a8d8c5 100644 --- a/Src/ILGPU/IR/Values/Constants.cs +++ b/Src/ILGPU/IR/Values/Constants.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Constants.cs @@ -137,7 +137,7 @@ internal PrimitiveValue( /// /// Returns the associated primitive type. /// - public PrimitiveType PrimitiveType => Type as PrimitiveType; + public PrimitiveType PrimitiveType => Type.AsNotNullCast(); /// /// Returns the value as i1. @@ -351,7 +351,7 @@ internal StringValue( /// /// Returns the associated type. /// - public StringType StringType => Type as StringType; + public StringType StringType => Type.AsNotNullCast(); /// /// Returns the associated string constant. diff --git a/Src/ILGPU/IR/Values/Debug.cs b/Src/ILGPU/IR/Values/Debug.cs index bb02a8361..ec55aae1c 100644 --- a/Src/ILGPU/IR/Values/Debug.cs +++ b/Src/ILGPU/IR/Values/Debug.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Debug.cs @@ -65,18 +65,26 @@ internal DebugAssertOperation( public (string FileName, int Line, string Method) GetLocationInfo() { const string KernelName = "Kernel"; - if (Location.IsKnown && - (Location is FileLocation fileLocation || - Location is CompilationStackLocation compilationStackLocation && - compilationStackLocation.TryGetLocation(out fileLocation))) - { - // Return information based on the current file location - return ( + + // Return information based on the current file location + static (string FileName, int Line, string Method) MakeLocation( + FileLocation fileLocation) => ( string.IsNullOrWhiteSpace(fileLocation.FileName) ? KernelName : fileLocation.FileName, fileLocation.StartLine, string.Empty); + + if (Location.IsKnown && Location is FileLocation fileLocation) + { + return MakeLocation(fileLocation); + } + else if (Location.IsKnown && + Location is CompilationStackLocation compilationStackLocation && + compilationStackLocation.TryGetLocation( + out FileLocation? innerFileLocation)) + { + return MakeLocation(innerFileLocation); } else { diff --git a/Src/ILGPU/IR/Values/HandleValue.cs b/Src/ILGPU/IR/Values/HandleValue.cs index eead04d52..84571842e 100644 --- a/Src/ILGPU/IR/Values/HandleValue.cs +++ b/Src/ILGPU/IR/Values/HandleValue.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: HandleValue.cs @@ -81,7 +81,7 @@ protected internal override Value Rebuild( protected override string ToPrefixString() => "handle"; /// - protected override string ToArgString() => Handle.ToString(); + protected override string ToArgString() => $"{Handle}"; #endregion } diff --git a/Src/ILGPU/IR/Values/IOValues.cs b/Src/ILGPU/IR/Values/IOValues.cs index 4b713d534..2a98bd7d0 100644 --- a/Src/ILGPU/IR/Values/IOValues.cs +++ b/Src/ILGPU/IR/Values/IOValues.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2022 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: IOValues.cs @@ -74,7 +74,7 @@ internal Enumerator(WriteToOutput writeToOutput) { WriteToOutput = writeToOutput; enumerator = writeToOutput.Expressions.GetEnumerator(); - Current = default; + Current = Utilities.InitNotNullable(); } /// @@ -298,7 +298,7 @@ public string ToPrintFExpression() { // Append the underlying expression string and escape % characters result.Append( - expression.String.Replace( + expression.String.AsNotNull().Replace( "%", PrintFPercentFormat)); } diff --git a/Src/ILGPU/IR/Values/Memory.cs b/Src/ILGPU/IR/Values/Memory.cs index 31da8d001..d564da72d 100644 --- a/Src/ILGPU/IR/Values/Memory.cs +++ b/Src/ILGPU/IR/Values/Memory.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Memory.cs @@ -11,6 +11,8 @@ using ILGPU.IR.Construction; using ILGPU.IR.Types; +using ILGPU.Util; +using System.Diagnostics.CodeAnalysis; namespace ILGPU.IR.Values { @@ -115,7 +117,7 @@ internal Alloca( /// /// Returns true if this allocation is an array allocation. /// - public bool IsArrayAllocation(out PrimitiveValue primitive) + public bool IsArrayAllocation([NotNullWhen(true)] out PrimitiveValue? primitive) { primitive = ArrayLength.ResolveAs(); return primitive != null; @@ -287,7 +289,7 @@ internal Load( /// protected override TypeNode ComputeType(in ValueInitializer initializer) => - (Source.Type as PointerType).ElementType; + Source.Type.AsNotNullCast().ElementType; /// protected internal override Value Rebuild( diff --git a/Src/ILGPU/IR/Values/Parameter.cs b/Src/ILGPU/IR/Values/Parameter.cs index 2b4462f30..7b64b24cf 100644 --- a/Src/ILGPU/IR/Values/Parameter.cs +++ b/Src/ILGPU/IR/Values/Parameter.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Parameter.cs @@ -32,7 +32,7 @@ public sealed class Parameter : Value internal Parameter( in ValueInitializer initializer, TypeNode type, - string name) + string? name) : base(initializer) { ParameterType = type; diff --git a/Src/ILGPU/IR/Values/PhiValue.cs b/Src/ILGPU/IR/Values/PhiValue.cs index 36cfb7c05..b4cd9e399 100644 --- a/Src/ILGPU/IR/Values/PhiValue.cs +++ b/Src/ILGPU/IR/Values/PhiValue.cs @@ -241,7 +241,7 @@ public static Value TryRemoveTrivialPhi( // See also: SSABuilder.cs Debug.Assert(phiValue != null, "Invalid phi value to remove"); - Value same = null; + Value? same = null; foreach (Value argument in phiValue.Nodes) { if (same == argument || argument == phiValue) @@ -318,7 +318,7 @@ internal PhiValue(in ValueInitializer initializer, TypeNode type) /// /// The source block. /// The value for the given source block (if any). - public Value GetValue(BasicBlock source) + public Value? GetValue(BasicBlock source) { var index = sourceBlocks.IndexOf(source, new BasicBlock.Comparer()); return index >= 0 ? this[index].Resolve() : null; diff --git a/Src/ILGPU/IR/Values/PointerValues.cs b/Src/ILGPU/IR/Values/PointerValues.cs index 148a0b768..c3d4e1985 100644 --- a/Src/ILGPU/IR/Values/PointerValues.cs +++ b/Src/ILGPU/IR/Values/PointerValues.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: PointerValues.cs @@ -11,6 +11,7 @@ using ILGPU.IR.Construction; using ILGPU.IR.Types; +using ILGPU.Util; using System; using System.Runtime.CompilerServices; using ValueList = ILGPU.Util.InlineList; @@ -59,7 +60,8 @@ internal PointerValue(in ValueInitializer initializer) /// /// Returns the view element type. /// - public AddressSpaceType AddressSpaceType => Type as AddressSpaceType; + public AddressSpaceType AddressSpaceType => + Type.AsNotNullCast(); /// /// Returns the pointer address space. @@ -197,7 +199,7 @@ internal LoadElementAddress( /// protected override TypeNode ComputeType(in ValueInitializer initializer) { - var sourceType = Source.Type as AddressSpaceType; + var sourceType = Source.Type.AsNotNullCast(); Location.AssertNotNull(sourceType); return sourceType is PointerType @@ -442,12 +444,13 @@ internal LoadFieldAddress( /// Returns the structure type. /// public StructureType StructureType => - (Source.Type as PointerType).ElementType as StructureType; + (Source.Type.AsNotNullCast().ElementType as StructureType) + .AsNotNull(); /// /// Returns the managed field information. /// - public TypeNode FieldType => (Type as PointerType).ElementType; + public TypeNode FieldType => Type.AsNotNullCast().ElementType; /// /// Returns the field span. diff --git a/Src/ILGPU/IR/Values/StructureValues.cs b/Src/ILGPU/IR/Values/StructureValues.cs index 85de343f1..f11664dd1 100644 --- a/Src/ILGPU/IR/Values/StructureValues.cs +++ b/Src/ILGPU/IR/Values/StructureValues.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: StructureValues.cs @@ -11,6 +11,7 @@ using ILGPU.IR.Construction; using ILGPU.IR.Types; +using ILGPU.Util; using System; using System.Collections.Immutable; using System.Diagnostics; @@ -97,7 +98,7 @@ public FieldAccess Subtract(int offset) /// /// True, if the given field access is equal to the current one. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is FieldAccess other && Equals(other); /// @@ -286,7 +287,7 @@ public bool Equals(FieldSpan other) => /// /// True, if the given field access is equal to the current one. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is FieldSpan other && Equals(other); /// @@ -495,7 +496,7 @@ public bool Equals(FieldAccessChain other) /// /// True, if the given field ref is equal to the current one. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is FieldAccessChain other && Equals(other); /// @@ -600,7 +601,7 @@ public FieldRef(Value source, FieldSpan fieldSpan) /// /// Returns the field span. /// - public FieldSpan FieldSpan => span.Value; + public FieldSpan FieldSpan => span.GetValueOrDefault(); /// /// Returns true if this instances references the whole source object. @@ -654,7 +655,7 @@ public bool Equals(FieldRef other) /// /// True, if the given field ref is equal to the current one. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is FieldRef other && Equals(other); /// @@ -800,7 +801,7 @@ public ValueReference this[FieldAccess access] /// /// Returns the next expected type to be added. /// - public TypeNode NextExpectedType => + public TypeNode? NextExpectedType => Count < Parent.NumFields ? Parent[Count] : null; #endregion @@ -1081,7 +1082,8 @@ internal StructureOperationValue( /// /// Returns the structure type. /// - public StructureType StructureType => ObjectValue.Type as StructureType; + public StructureType StructureType => + ObjectValue.Type.AsNotNullCast(); /// ( /// Returns the field span. @@ -1134,7 +1136,9 @@ internal GetField( /// protected override TypeNode ComputeType(in ValueInitializer initializer) => - (ObjectValue.Type as StructureType).Get(initializer.Context, FieldSpan); + (ObjectValue.Type as StructureType) + .AsNotNull() + .Get(initializer.Context, FieldSpan); /// protected internal override Value Rebuild( diff --git a/Src/ILGPU/IR/Values/Terminators.cs b/Src/ILGPU/IR/Values/Terminators.cs index ee5f061a5..95e264379 100644 --- a/Src/ILGPU/IR/Values/Terminators.cs +++ b/Src/ILGPU/IR/Values/Terminators.cs @@ -13,6 +13,7 @@ using ILGPU.IR.Types; using ILGPU.Util; using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Text; using BlockList = ILGPU.Util.InlineList; @@ -392,7 +393,9 @@ protected ConditionalBranch(in ValueInitializer initializer) /// /// The branch target to exclude. /// The other branch target (if any). - public bool TryGetOtherBranchTarget(BasicBlock block, out BasicBlock otherBlock) + public bool TryGetOtherBranchTarget( + BasicBlock block, + [NotNullWhen(true)] out BasicBlock? otherBlock) { otherBlock = null; if (NumTargets != 2) diff --git a/Src/ILGPU/IR/Values/Use.cs b/Src/ILGPU/IR/Values/Use.cs index 38fd7ef8a..d6ac13ecf 100644 --- a/Src/ILGPU/IR/Values/Use.cs +++ b/Src/ILGPU/IR/Values/Use.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2022 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Use.cs @@ -75,7 +75,7 @@ internal Use(Value target, int index) /// /// The target type. /// The actual value. - public T ResolveAs() where T : Value => Resolve() as T; + public T? ResolveAs() where T : Value => Resolve() as T; #endregion @@ -97,7 +97,7 @@ internal Use(Value target, int index) /// /// The other object. /// True, if the given object is equal to this use. - public override bool Equals(object obj) => obj is Use use && use == this; + public override bool Equals(object? obj) => obj is Use use && use == this; /// /// Returns the hash code of this use. diff --git a/Src/ILGPU/IR/Values/Value.cs b/Src/ILGPU/IR/Values/Value.cs index 515013ce2..863e0b00d 100644 --- a/Src/ILGPU/IR/Values/Value.cs +++ b/Src/ILGPU/IR/Values/Value.cs @@ -69,7 +69,7 @@ public interface IValue : INode /// /// The target type. /// The actual value. - T ResolveAs() where T : Value; + T? ResolveAs() where T : Value; /// /// Accepts a value visitor. @@ -187,7 +187,7 @@ public enum ValueFlags : int [MethodImpl(MethodImplOptions.AggressiveInlining)] public ValueInitializer( IRBaseContext context, - ValueParent parent, + ValueParent? parent, Location location) { // Enforce a valid location in all cases @@ -210,7 +210,7 @@ public ValueInitializer( /// /// Returns the associated parent. /// - public ValueParent Parent { get; } + public ValueParent? Parent { get; } /// /// Returns the associated location. @@ -251,13 +251,13 @@ public abstract class Value : Node, IValue, IEquatable /// The current parent container. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private ValueParent parent; + private ValueParent? parent; /// /// The current node type. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private TypeNode type; + private TypeNode? type; /// /// The list of all values. @@ -314,7 +314,7 @@ protected Value( protected Value( in ValueInitializer initializer, ValueFlags valueFlags, - TypeNode staticType) + TypeNode? staticType) : base(initializer.Location) { parent = initializer.Parent; @@ -343,14 +343,14 @@ protected Value( public Method Method => parent is BasicBlock basicBlock ? basicBlock.Method - : parent as Method; + : parent.AsNotNullCast(); /// /// Returns the parent basic block. /// public BasicBlock BasicBlock { - get => parent as BasicBlock; + get => parent.AsNotNullCast(); internal set { this.Assert(value.IsBasicBlock); @@ -682,7 +682,7 @@ public Value Resolve() /// /// The target type. /// The actual value. - public T ResolveAs() where T : Value => Resolve() as T; + public T? ResolveAs() where T : Value => Resolve() as T; #endregion @@ -693,7 +693,7 @@ public Value Resolve() /// /// The other value. /// True, if the given value is the same value. - public bool Equals(Value other) => other == this; + public bool Equals(Value? other) => other == this; #endregion @@ -736,7 +736,7 @@ public sealed override string ToString() /// /// The other object. /// True, if the given object is equal to the current value. - public override bool Equals(object obj) => obj == this; + public override bool Equals(object? obj) => obj == this; /// /// Returns the hash code of this value. diff --git a/Src/ILGPU/IR/Values/ValueKind.cs b/Src/ILGPU/IR/Values/ValueKind.cs index 8e309ef0a..d8ef863f6 100644 --- a/Src/ILGPU/IR/Values/ValueKind.cs +++ b/Src/ILGPU/IR/Values/ValueKind.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2022 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: ValueKind.cs @@ -9,6 +9,7 @@ // Source License. See LICENSE.txt for details. // --------------------------------------------------------------------------------------- +using ILGPU.Util; using System; using System.Reflection; @@ -405,7 +406,7 @@ public static class ValueKinds /// The determined value kind. public static ValueKind GetValueKind() where TValue : Value => - typeof(TValue).GetCustomAttribute().Kind; + typeof(TValue).GetCustomAttribute().AsNotNull().Kind; /// /// Gets the value kind of the type specified. diff --git a/Src/ILGPU/IR/Values/ValueReference.cs b/Src/ILGPU/IR/Values/ValueReference.cs index 24d85ac85..1d8adcedd 100644 --- a/Src/ILGPU/IR/Values/ValueReference.cs +++ b/Src/ILGPU/IR/Values/ValueReference.cs @@ -174,7 +174,7 @@ public Value Resolve() /// /// The target type. /// The actual node. - public T ResolveAs() where T : Value => Resolve() as T; + public T? ResolveAs() where T : Value => Resolve() as T; /// /// Dumps this node to the given text writer. @@ -214,7 +214,7 @@ string ILocation.FormatErrorMessage(string message) => /// /// The other object. /// True, if the given object points to the same node. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is ValueReference other && Equals(other); /// diff --git a/Src/ILGPU/IR/Values/View.cs b/Src/ILGPU/IR/Values/View.cs index a4fecc852..af498848a 100644 --- a/Src/ILGPU/IR/Values/View.cs +++ b/Src/ILGPU/IR/Values/View.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: View.cs @@ -11,6 +11,7 @@ using ILGPU.IR.Construction; using ILGPU.IR.Types; +using ILGPU.Util; namespace ILGPU.IR.Values { @@ -52,12 +53,13 @@ internal NewView( /// /// Returns the view's element type. /// - public TypeNode ViewElementType => (Type as ViewType).ElementType; + public TypeNode ViewElementType => Type.AsNotNullCast().ElementType; /// /// Returns the view's address space. /// - public MemoryAddressSpace ViewAddressSpace => (Type as ViewType).AddressSpace; + public MemoryAddressSpace ViewAddressSpace => + Type.AsNotNullCast().AddressSpace; /// /// Returns the length of the view. diff --git a/Src/ILGPU/IR/Verifier.cs b/Src/ILGPU/IR/Verifier.cs index 9df1ebea5..9c18e0a47 100644 --- a/Src/ILGPU/IR/Verifier.cs +++ b/Src/ILGPU/IR/Verifier.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: Verifier.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.IR.Values; +using ILGPU.Util; using System; using System.Collections.Generic; using System.Diagnostics; @@ -377,12 +378,14 @@ private void VerifyValues() } // Check the terminator value - Assert(block.Terminator, values.Add(block.Terminator)); - foreach (Value node in block.Terminator.Nodes) + Assert( + block.Terminator.AsNotNull(), + values.Add(block.Terminator.AsNotNull())); + foreach (Value node in block.Terminator.AsNotNull().Nodes) { if (node is UndefinedValue) continue; - Assert(block.Terminator, values.Contains(node)); + Assert(block.Terminator.AsNotNull(), values.Contains(node)); } } @@ -417,7 +420,9 @@ private void VerifyValueBlockAssociations() Assert(value, foundBlock); if (!foundBlock) continue; - Assert(value.BasicBlock, blockValues.Contains(value)); + Assert( + value.BasicBlock, + blockValues != null && blockValues.Contains(value)); } } @@ -548,8 +553,9 @@ public static VerificationResult ApplyVerification(Method method) void Verify() where T : VerifierBase { - var instance = Activator.CreateInstance(typeof(T), method, result) - as VerifierBase; + var instance = (Activator.CreateInstance(typeof(T), method, result) + as VerifierBase + ).AsNotNull(); instance.Verify(); } diff --git a/Src/ILGPU/IndexTypes.tt b/Src/ILGPU/IndexTypes.tt index a4884671b..026bb4ce3 100644 --- a/Src/ILGPU/IndexTypes.tt +++ b/Src/ILGPU/IndexTypes.tt @@ -65,7 +65,8 @@ namespace ILGPU new Type[] { <#= def.Expression(", ", p => $"typeof({baseType})") #> - }); + }) + .AsNotNull(); /// /// Computes min(first, second). @@ -330,7 +331,7 @@ namespace ILGPU /// /// The other object. /// True, if the given object is equal to the current index. - public readonly override bool Equals(object obj) => + public readonly override bool Equals(object? obj) => obj is <#= name #> other && Equals(other); /// diff --git a/Src/ILGPU/InstanceId.cs b/Src/ILGPU/InstanceId.cs index deccaafbe..7c29b446d 100644 --- a/Src/ILGPU/InstanceId.cs +++ b/Src/ILGPU/InstanceId.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: InstanceId.cs @@ -100,7 +100,7 @@ internal InstanceId(long id) /// /// The other object. /// True, if the given object is equal to this id. - public readonly override bool Equals(object obj) => + public readonly override bool Equals(object? obj) => obj is InstanceId id && id == this; /// diff --git a/Src/ILGPU/Interop.cs b/Src/ILGPU/Interop.cs index dab8bef6f..49cd8b862 100644 --- a/Src/ILGPU/Interop.cs +++ b/Src/ILGPU/Interop.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: Interop.cs @@ -98,13 +98,17 @@ public static int SizeOf(T structure) /// Only supports unmanaged types. [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int SizeOf(Type type) => - (int)InteropSizeOfMethod.MakeGenericMethod(type).Invoke(null, null); + (int)InteropSizeOfMethod + .MakeGenericMethod(type) + .Invoke(null, null) + .AsNotNull(); private static readonly MethodInfo InteropSizeOfMethod = typeof(Interop).GetMethod( nameof(SizeOf), Type.EmptyTypes, - null); + null) + .ThrowIfNull(); /// /// Computes number of elements of type diff --git a/Src/ILGPU/KernelConfig.cs b/Src/ILGPU/KernelConfig.cs index e64ea4562..1c2723bbc 100644 --- a/Src/ILGPU/KernelConfig.cs +++ b/Src/ILGPU/KernelConfig.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2022 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: KernelConfig.cs @@ -37,7 +37,8 @@ namespace ILGPU { typeof(Index3D), typeof(Index3D) - }); + }) + .ThrowIfNull(); #endregion @@ -501,7 +502,8 @@ public readonly struct RuntimeKernelConfig { typeof(KernelConfig), typeof(SharedMemorySpecification) - }); + }) + .ThrowIfNull(); #endregion diff --git a/Src/ILGPU/Runtime/Accelerator.GC.cs b/Src/ILGPU/Runtime/Accelerator.GC.cs index 80d506bd7..50b6dfcc9 100644 --- a/Src/ILGPU/Runtime/Accelerator.GC.cs +++ b/Src/ILGPU/Runtime/Accelerator.GC.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: Accelerator.GC.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Threading; @@ -34,6 +35,7 @@ partial class Accelerator /// /// Initializes the GC functionality. /// + [MemberNotNull(nameof(gcThread))] private void InitGC() { gcActivated = true; diff --git a/Src/ILGPU/Runtime/Accelerator.Launchers.cs b/Src/ILGPU/Runtime/Accelerator.Launchers.cs index 3c67b113f..f9c733cb7 100644 --- a/Src/ILGPU/Runtime/Accelerator.Launchers.cs +++ b/Src/ILGPU/Runtime/Accelerator.Launchers.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: Accelerator.Launchers.cs @@ -9,6 +9,7 @@ // Source License. See LICENSE.txt for details. // --------------------------------------------------------------------------------------- +using ILGPU.Util; using System; using System.Collections.Generic; using System.Diagnostics; @@ -48,7 +49,7 @@ private interface IKernelLaunchLoader /// The internal async launch cache dictionary. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private Dictionary launchCache; + private Dictionary? launchCache; /// /// Initializes the local launch cache. @@ -107,14 +108,14 @@ private TTarget GetOrLoadLauncher( { // Try to load a previously loaded delegate and ensure that the loaded // launcher is compatible with the desired target delegate type - if (!launchCache.TryGetValue(action, out var launcher) || + if (!launchCache.AsNotNull().TryGetValue(action, out var launcher) || !(launcher is TTarget)) { // Load the launcher using the provided loader launcher = loader.Load(this, action); - launchCache.Add(action, launcher); + launchCache.AsNotNull().Add(action, launcher); } - return launcher as TTarget; + return launcher.AsNotNullCast(); } } @@ -125,7 +126,7 @@ private void ClearLaunchCache_SyncRoot() { if (!LaunchCacheEnabled) return; - launchCache.Clear(); + launchCache.AsNotNull().Clear(); } #endregion diff --git a/Src/ILGPU/Runtime/Accelerator.cs b/Src/ILGPU/Runtime/Accelerator.cs index cc2b4c33e..a968d8189 100644 --- a/Src/ILGPU/Runtime/Accelerator.cs +++ b/Src/ILGPU/Runtime/Accelerator.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2016-2022 ILGPU Project +// Copyright (c) 2016-2023 ILGPU Project // www.ilgpu.net // // File: Accelerator.cs @@ -93,7 +93,7 @@ public static AcceleratorType CurrentType /// /// Will be raised if the accelerator is disposed. /// - public event EventHandler Disposed; + public event EventHandler? Disposed; #endregion @@ -128,6 +128,10 @@ protected Accelerator(Context context, Device device) InitKernelCache(); InitLaunchCache(); InitGC(); + + // NB: Initialized later by derived classes. + Backend = Utilities.InitNotNullable(); + DefaultStream = Utilities.InitNotNullable(); } #endregion diff --git a/Src/ILGPU/Runtime/AcceleratorObject.cs b/Src/ILGPU/Runtime/AcceleratorObject.cs index a8cd48593..4ed395f7b 100644 --- a/Src/ILGPU/Runtime/AcceleratorObject.cs +++ b/Src/ILGPU/Runtime/AcceleratorObject.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: AcceleratorObject.cs @@ -44,11 +44,6 @@ public abstract class AcceleratorObject : DisposeBase, IAcceleratorObject { #region Instance - /// - /// Constructs an accelerator object that lives on the CPU. - /// - protected AcceleratorObject() { } - /// /// Constructs an accelerator object. /// @@ -272,7 +267,7 @@ private void DisposeChildObjects_SyncRoot(bool disposing) foreach (var childObject in childObjects) { // Try to get the actual child object and dispose it - if (childObject.TryGetTarget(out AcceleratorObject obj)) + if (childObject.TryGetTarget(out AcceleratorObject? obj)) { // We can safely dispose the object at this point since the current // accelerator is bound and the syncRoot lock is acquired @@ -296,7 +291,7 @@ private void ChildObjectsGC_SyncRoot() childObjects = new List>(); foreach (var childObject in oldObjects) { - if (childObject.TryGetTarget(out AcceleratorObject _)) + if (childObject.TryGetTarget(out AcceleratorObject? _)) childObjects.Add(childObject); } } diff --git a/Src/ILGPU/Runtime/AcceleratorStream.cs b/Src/ILGPU/Runtime/AcceleratorStream.cs index c8c402921..542c7655b 100644 --- a/Src/ILGPU/Runtime/AcceleratorStream.cs +++ b/Src/ILGPU/Runtime/AcceleratorStream.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: AcceleratorStream.cs @@ -30,14 +30,6 @@ public abstract class AcceleratorStream : AcceleratorObject private readonly Action synchronizeAction; - /// - /// Constructs a new accelerator stream. - /// - protected AcceleratorStream() - { - synchronizeAction = () => Synchronize(); - } - /// /// Constructs a new accelerator stream. /// diff --git a/Src/ILGPU/Runtime/CPU/CPUAccelerator.cs b/Src/ILGPU/Runtime/CPU/CPUAccelerator.cs index 62d75ba2e..b4882c3af 100644 --- a/Src/ILGPU/Runtime/CPU/CPUAccelerator.cs +++ b/Src/ILGPU/Runtime/CPU/CPUAccelerator.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2016-2022 ILGPU Project +// Copyright (c) 2016-2023 ILGPU Project // www.ilgpu.net // // File: CPUAccelerator.cs @@ -12,6 +12,7 @@ using ILGPU.Backends; using ILGPU.Backends.IL; using ILGPU.Resources; +using ILGPU.Util; using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -68,7 +69,7 @@ public sealed partial class CPUAccelerator : Accelerator // Task execution private readonly object taskSynchronizationObject = new object(); - private volatile CPUAcceleratorTask currentTask; + private volatile CPUAcceleratorTask? currentTask; [SuppressMessage( "Microsoft.Usage", @@ -152,7 +153,7 @@ internal CPUAccelerator( /// /// Returns the IL backend of this accelerator. /// - internal new ILBackend Backend => base.Backend as ILBackend; + internal new ILBackend Backend => base.Backend.AsNotNullCast(); #endregion @@ -357,12 +358,16 @@ private MethodInfo GenerateKernelLauncherMethod( emitter.Emit(LocalOperation.Load, cpuKernel); emitter.EmitCall( typeof(CPUKernel).GetProperty( - nameof(CPUKernel.CPUAccelerator)).GetGetMethod(false)); + nameof(CPUKernel.CPUAccelerator)) + .AsNotNull() + .GetGetMethod(false) + .AsNotNull()); emitter.Emit(LocalOperation.Load, task); emitter.EmitCall( typeof(CPUAccelerator).GetMethod( nameof(CPUAccelerator.Launch), - BindingFlags.NonPublic | BindingFlags.Instance)); + BindingFlags.NonPublic | BindingFlags.Instance) + .AsNotNull()); // End of launch method emitter.Emit(OpCodes.Ret); @@ -375,7 +380,7 @@ private MethodInfo GenerateKernelLauncherMethod( #region Execution Methods - internal bool WaitForTask(ref CPUAcceleratorTask task) + internal bool WaitForTask([NotNullWhen(true)] ref CPUAcceleratorTask? task) { // Get a new task to execute lock (taskSynchronizationObject) diff --git a/Src/ILGPU/Runtime/CPU/CPUAcceleratorTask.cs b/Src/ILGPU/Runtime/CPU/CPUAcceleratorTask.cs index 96ff10f41..aa5701d74 100644 --- a/Src/ILGPU/Runtime/CPU/CPUAcceleratorTask.cs +++ b/Src/ILGPU/Runtime/CPU/CPUAcceleratorTask.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: CPUAcceleratorTask.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.Resources; +using ILGPU.Util; using System; using System.Diagnostics; using System.Reflection; @@ -63,7 +64,8 @@ public static ConstructorInfo GetTaskConstructor(Type taskType) => BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance, null, ConstructorParameterTypes, - null); + null) + .AsNotNull(); /// /// Returns the getter for the of a specific task @@ -75,7 +77,9 @@ public static MethodInfo GetTotalUserDimGetter(Type taskType) => taskType.GetProperty( nameof(TotalUserDim), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance) - .GetGetMethod(true); + .AsNotNull() + .GetGetMethod(true) + .AsNotNull(); /// /// Returns the getter for the of a specific task @@ -87,7 +91,9 @@ public static MethodInfo GetTotalUserDimXYGetter(Type taskType) => taskType.GetProperty( nameof(TotalUserDimXY), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance) - .GetGetMethod(true); + .AsNotNull() + .GetGetMethod(true) + .AsNotNull(); #endregion diff --git a/Src/ILGPU/Runtime/CPU/CPUDevice.cs b/Src/ILGPU/Runtime/CPU/CPUDevice.cs index f5a092f5a..9c0e35d7f 100644 --- a/Src/ILGPU/Runtime/CPU/CPUDevice.cs +++ b/Src/ILGPU/Runtime/CPU/CPUDevice.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: CPUDevice.cs @@ -336,7 +336,7 @@ public CPUAccelerator CreateCPUAccelerator( #region Object /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is CPUDevice device && device.WarpSize == WarpSize && device.MaxNumThreadsPerGroup == MaxNumThreadsPerGroup && diff --git a/Src/ILGPU/Runtime/CPU/CPUKernel.cs b/Src/ILGPU/Runtime/CPU/CPUKernel.cs index 890429804..4a7432477 100644 --- a/Src/ILGPU/Runtime/CPU/CPUKernel.cs +++ b/Src/ILGPU/Runtime/CPU/CPUKernel.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: CPUKernel.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.Backends; +using ILGPU.Util; using System; using System.Reflection; @@ -29,7 +30,9 @@ public sealed class CPUKernel : Kernel typeof(CPUKernel).GetProperty( nameof(KernelExecutionDelegate), BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance) - .GetGetMethod(true); + .ThrowIfNull() + .GetGetMethod(true) + .ThrowIfNull(); #endregion @@ -60,7 +63,8 @@ internal CPUKernel( /// /// Returns the associated CPU runtime. /// - public CPUAccelerator CPUAccelerator => Accelerator as CPUAccelerator; + public CPUAccelerator CPUAccelerator => + Accelerator.AsNotNullCast(); /// /// Returns the associated kernel-execution delegate. diff --git a/Src/ILGPU/Runtime/CPU/CPUMemoryBuffer.cs b/Src/ILGPU/Runtime/CPU/CPUMemoryBuffer.cs index 9ce5c268d..6bd629a1f 100644 --- a/Src/ILGPU/Runtime/CPU/CPUMemoryBuffer.cs +++ b/Src/ILGPU/Runtime/CPU/CPUMemoryBuffer.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2022 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: CPUMemoryBuffer.cs @@ -12,6 +12,7 @@ using ILGPU.Resources; using ILGPU.Runtime.Cuda; using ILGPU.Runtime.OpenCL; +using ILGPU.Util; using System; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; @@ -569,7 +570,8 @@ internal static CPUMemoryBuffer FromArray(Array array) { if (array is null) throw new ArgumentNullException(nameof(array)); - int elementSize = Interop.SizeOf(array.GetType().GetElementType()); + int elementSize = + Interop.SizeOf(array.GetType().GetElementType().AsNotNull()); return FromArray(array, elementSize); } diff --git a/Src/ILGPU/Runtime/CPU/CPUMemoryBufferCache.cs b/Src/ILGPU/Runtime/CPU/CPUMemoryBufferCache.cs index 943196ed1..784033f14 100644 --- a/Src/ILGPU/Runtime/CPU/CPUMemoryBufferCache.cs +++ b/Src/ILGPU/Runtime/CPU/CPUMemoryBufferCache.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021-2022 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: CPUMemoryBufferCache.cs @@ -30,7 +30,7 @@ sealed class CPUMemoryBufferCache : AcceleratorObject "Microsoft.Usage", "CA2213: Disposable fields should be disposed", Justification = "This is disposed in DisposeAcceleratorObject")] - private MemoryBuffer> cache; + private MemoryBuffer>? cache; /// /// Constructs a new memory-buffer cache. @@ -68,7 +68,7 @@ public CPUMemoryBufferCache(CPUAccelerator accelerator, long initialLength) /// /// Returns the underlying memory buffer view. /// - public ArrayView Cache => cache.View; + public ArrayView Cache => cache?.View ?? ArrayView.Empty; #endregion diff --git a/Src/ILGPU/Runtime/CPU/CPUMultiprocessor.cs b/Src/ILGPU/Runtime/CPU/CPUMultiprocessor.cs index 6d93f6f9c..d688e7824 100644 --- a/Src/ILGPU/Runtime/CPU/CPUMultiprocessor.cs +++ b/Src/ILGPU/Runtime/CPU/CPUMultiprocessor.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021-2022 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: CPUMultiprocessor.cs @@ -220,10 +220,10 @@ public void InitLaunch(CPUAcceleratorTask task) /// Entry point for a single processing thread. /// /// The absolute thread index. - private void ExecuteThread(object arg) + private void ExecuteThread(object? arg) { // Get the current thread information - int absoluteThreadIndex = (int)arg; + int absoluteThreadIndex = (int)arg.AsNotNull(); int threadIdx = absoluteThreadIndex % MaxNumThreadsPerMultiprocessor; bool isMainThread = threadIdx == 0; @@ -244,7 +244,7 @@ private void ExecuteThread(object arg) // Setup the current group context as it always stays the same groupContext.MakeCurrent(); - CPUAcceleratorTask task = null; + CPUAcceleratorTask? task = null; for (; ; ) { // Get a new task to execute (if any) diff --git a/Src/ILGPU/Runtime/CPU/CPURuntimeGroupContext.cs b/Src/ILGPU/Runtime/CPU/CPURuntimeGroupContext.cs index 201093aaa..e433d91be 100644 --- a/Src/ILGPU/Runtime/CPU/CPURuntimeGroupContext.cs +++ b/Src/ILGPU/Runtime/CPU/CPURuntimeGroupContext.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2022 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: CPURuntimeGroupContext.cs @@ -29,7 +29,7 @@ sealed class CPURuntimeGroupContext : CPURuntimeContext, CPURuntimeContext.IPare /// Represents the current context. /// [ThreadStatic] - private static CPURuntimeGroupContext currentContext; + private static CPURuntimeGroupContext? currentContext; /// /// Returns the current group runtime context. @@ -42,7 +42,7 @@ public static CPURuntimeGroupContext Current Trace.Assert( currentContext != null, ErrorMessages.InvalidKernelOperation); - return currentContext; + return currentContext.AsNotNull(); } } @@ -79,8 +79,8 @@ public static CPURuntimeGroupContext Current /// instructions out of nested loops /// to provide the best debugging experience. /// - private InlineList sharedMemory = - InlineList.Create(16); + private InlineList sharedMemory = + InlineList.Create(16); /// /// Shared-memory allocation lock object for synchronizing accesses to the @@ -332,7 +332,7 @@ public void Initialize( private void ClearSharedMemoryAllocations() { foreach (var entry in sharedMemory) - entry.Dispose(); + entry?.Dispose(); sharedMemory.Clear(); Array.Clear(groupAllocationIndices, 0, groupAllocationIndices.Length); Atomic.Exchange(ref groupAllocationIndexAccumulator, 0); diff --git a/Src/ILGPU/Runtime/CPU/CPURuntimeThreadContext.cs b/Src/ILGPU/Runtime/CPU/CPURuntimeThreadContext.cs index 241d9d040..c990ec939 100644 --- a/Src/ILGPU/Runtime/CPU/CPURuntimeThreadContext.cs +++ b/Src/ILGPU/Runtime/CPU/CPURuntimeThreadContext.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: CPURuntimeThreadContext.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.Resources; +using ILGPU.Util; using System; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -27,7 +28,7 @@ sealed class CPURuntimeThreadContext /// Represents the current context. /// [ThreadStatic] - private static CPURuntimeThreadContext currentContext; + private static CPURuntimeThreadContext? currentContext; /// /// Returns the current warp runtime context. @@ -40,7 +41,7 @@ public static CPURuntimeThreadContext Current Trace.Assert( currentContext != null, ErrorMessages.InvalidKernelOperation); - return currentContext; + return currentContext.AsNotNull(); } } diff --git a/Src/ILGPU/Runtime/CPU/CPURuntimeWarpContext.cs b/Src/ILGPU/Runtime/CPU/CPURuntimeWarpContext.cs index c8ff9065a..c6a25a61f 100644 --- a/Src/ILGPU/Runtime/CPU/CPURuntimeWarpContext.cs +++ b/Src/ILGPU/Runtime/CPU/CPURuntimeWarpContext.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2022 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: CPURuntimeWarpContext.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.Resources; +using ILGPU.Util; using System; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; @@ -28,7 +29,7 @@ sealed class CPURuntimeWarpContext : CPURuntimeContext, CPURuntimeContext.IParen /// Represents the current context. /// [ThreadStatic] - private static CPURuntimeWarpContext currentContext; + private static CPURuntimeWarpContext? currentContext; /// /// Returns the current warp runtime context. @@ -41,7 +42,7 @@ public static CPURuntimeWarpContext Current Trace.Assert( currentContext != null, ErrorMessages.InvalidKernelOperation); - return currentContext; + return currentContext.AsNotNull(); } } diff --git a/Src/ILGPU/Runtime/CPU/CPUStream.cs b/Src/ILGPU/Runtime/CPU/CPUStream.cs index acd510464..4778cc882 100644 --- a/Src/ILGPU/Runtime/CPU/CPUStream.cs +++ b/Src/ILGPU/Runtime/CPU/CPUStream.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: CPUStream.cs @@ -16,22 +16,8 @@ namespace ILGPU.Runtime.CPU /// sealed class CPUStream : AcceleratorStream { - #region Static - - /// - /// The default instance. - /// - internal static readonly CPUStream Default = new CPUStream(); - - #endregion - #region Instance - /// - /// Constructs a new CPU stream. - /// - private CPUStream() : base() { } - /// /// Constructs a new CPU stream. /// diff --git a/Src/ILGPU/Runtime/Cuda/CudaAPI.cs b/Src/ILGPU/Runtime/Cuda/CudaAPI.cs index b32911a95..98e6053d7 100644 --- a/Src/ILGPU/Runtime/Cuda/CudaAPI.cs +++ b/Src/ILGPU/Runtime/Cuda/CudaAPI.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: CudaAPI.cs @@ -71,7 +71,8 @@ public CudaError GetDriverVersion(out CudaDriverVersion driverVersion) public string GetErrorString(CudaError error) => cuGetErrorString(error, out IntPtr ptr) != CudaError.CUDA_SUCCESS ? RuntimeErrorMessages.CannotResolveErrorString - : Marshal.PtrToStringAnsi(ptr); + : Marshal.PtrToStringAnsi(ptr) + ?? RuntimeErrorMessages.CannotResolveErrorString; #endregion @@ -105,7 +106,7 @@ public CudaError GetDeviceCount(out int count) /// The resolved name. /// The device. /// The error status. - public unsafe CudaError GetDeviceName(out string name, int device) + public unsafe CudaError GetDeviceName(out string? name, int device) { const int MaxAcceleratorNameLength = 2048; name = null; @@ -381,7 +382,7 @@ public CudaError MemcpyAsync( IntPtr destination, IntPtr source, IntPtr length, - AcceleratorStream stream) + AcceleratorStream? stream) { var cudaStream = stream as CudaStream; return cuMemcpyAsync( @@ -406,7 +407,7 @@ public CudaError Memset( IntPtr destinationDevice, byte value, IntPtr length, - AcceleratorStream stream) + AcceleratorStream? stream) { var cudaStream = stream as CudaStream; return Memset( @@ -572,7 +573,7 @@ public CudaError LoadModule( public unsafe CudaError LoadModule( out IntPtr kernelModule, string moduleData, - out string errorLog) + out string? errorLog) { const int BufferSize = 1024; const int NumOptions = 2; @@ -787,7 +788,7 @@ public CudaError ComputeOccupancyMaxPotentialBlockSize( out int minGridSize, out int blockSize, IntPtr func, - ComputeDynamicMemorySizeForBlockSize blockSizeToDynamicSMemSize, + ComputeDynamicMemorySizeForBlockSize? blockSizeToDynamicSMemSize, IntPtr dynamicSMemSize, int blockSizeLimit) => cuOccupancyMaxPotentialBlockSize( diff --git a/Src/ILGPU/Runtime/Cuda/CudaAPI.xml b/Src/ILGPU/Runtime/Cuda/CudaAPI.xml index 893302ebe..ea0913437 100644 --- a/Src/ILGPU/Runtime/Cuda/CudaAPI.xml +++ b/Src/ILGPU/Runtime/Cuda/CudaAPI.xml @@ -191,7 +191,7 @@ + Type="ComputeDynamicMemorySizeForBlockSize?" /> diff --git a/Src/ILGPU/Runtime/Cuda/CudaAccelerator.cs b/Src/ILGPU/Runtime/Cuda/CudaAccelerator.cs index 2046e5d06..c338c10fa 100644 --- a/Src/ILGPU/Runtime/Cuda/CudaAccelerator.cs +++ b/Src/ILGPU/Runtime/Cuda/CudaAccelerator.cs @@ -12,6 +12,7 @@ using ILGPU.Backends.IL; using ILGPU.Backends.PTX; using ILGPU.Resources; +using ILGPU.Util; using System; using System.Diagnostics; using System.Reflection; @@ -44,7 +45,10 @@ public sealed class CudaAccelerator : private static readonly MethodInfo GetCudaAPIMethod = typeof(CudaAPI).GetProperty( nameof(CurrentAPI), - BindingFlags.Public | BindingFlags.Static).GetGetMethod(); + BindingFlags.Public | BindingFlags.Static) + .ThrowIfNull() + .GetGetMethod() + .ThrowIfNull(); /// /// Represents the method. @@ -61,7 +66,8 @@ public sealed class CudaAccelerator : private static readonly MethodInfo ThrowIfFailedMethod = typeof(CudaException).GetMethod( nameof(CudaException.ThrowIfFailed), - BindingFlags.Public | BindingFlags.Static); + BindingFlags.Public | BindingFlags.Static) + .ThrowIfNull(); /// /// Resolves the memory type of the given device pointer. @@ -177,7 +183,8 @@ internal CudaAccelerator( CudaException.ThrowIfFailed( CurrentAPI.GetCacheConfig(out cacheConfiguration)); - var nvvmAPI = !string.IsNullOrEmpty(context.Properties.LibNvvmPath) + var nvvmAPI = !string.IsNullOrEmpty(context.Properties.LibNvvmPath) && + !string.IsNullOrEmpty(context.Properties.LibDevicePath) ? NvvmAPI.Create( context.Properties.LibNvvmPath, context.Properties.LibDevicePath) @@ -187,7 +194,7 @@ internal CudaAccelerator( Context, Capabilities, Architecture, - (CudaInstructionSet)Device.InstructionSet, + Device.InstructionSet.GetValueOrDefault(), nvvmAPI)); } @@ -198,7 +205,7 @@ internal CudaAccelerator( /// /// Returns the Cuda device. /// - public new CudaDevice Device => base.Device as CudaDevice; + public new CudaDevice Device => base.Device.AsNotNullCast(); /// /// Returns the device id. @@ -214,7 +221,7 @@ internal CudaAccelerator( /// Returns the PTX architecture. /// public CudaArchitecture Architecture => - (CudaArchitecture)Device.Architecture; + Device.Architecture.GetValueOrDefault(); /// /// Returns the PTX instruction set. @@ -353,13 +360,13 @@ public CudaCacheConfiguration CacheConfiguration /// /// Returns the PTX backend of this accelerator. /// - public new PTXBackend Backend => base.Backend as PTXBackend; + public new PTXBackend Backend => base.Backend.AsNotNullCast(); /// /// Returns the capabilities of this accelerator. /// public new CudaCapabilityContext Capabilities => - base.Capabilities as CudaCapabilityContext; + base.Capabilities.AsNotNullCast(); #endregion diff --git a/Src/ILGPU/Runtime/Cuda/CudaArchitecture.cs b/Src/ILGPU/Runtime/Cuda/CudaArchitecture.cs index 409e3a4d2..932f267ba 100644 --- a/Src/ILGPU/Runtime/Cuda/CudaArchitecture.cs +++ b/Src/ILGPU/Runtime/Cuda/CudaArchitecture.cs @@ -90,7 +90,7 @@ public int CompareTo(CudaArchitecture other) /// The other object. /// True, /// if the given object is equal to this architecture. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is CudaArchitecture architecture && architecture == this; /// diff --git a/Src/ILGPU/Runtime/Cuda/CudaDevice.cs b/Src/ILGPU/Runtime/Cuda/CudaDevice.cs index 79b3462f5..a6e6f7db9 100644 --- a/Src/ILGPU/Runtime/Cuda/CudaDevice.cs +++ b/Src/ILGPU/Runtime/Cuda/CudaDevice.cs @@ -177,8 +177,8 @@ private void InitDeviceInfo() { // Get the device name ThrowIfFailed( - CurrentAPI.GetDeviceName(out string name, DeviceId)); - Name = name; + CurrentAPI.GetDeviceName(out string? name, DeviceId)); + Name = name ?? string.Empty; // Resolve clock rate ClockRate = CurrentAPI.GetDeviceAttribute( @@ -602,7 +602,7 @@ protected override void PrintGeneralInfo(TextWriter writer) #region Object /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is CudaDevice device && device.PCIDomainId == PCIDomainId && device.PCIBusId == PCIBusId && diff --git a/Src/ILGPU/Runtime/Cuda/CudaDriverVersion.cs b/Src/ILGPU/Runtime/Cuda/CudaDriverVersion.cs index 92c6c7bc4..501a6b6ad 100644 --- a/Src/ILGPU/Runtime/Cuda/CudaDriverVersion.cs +++ b/Src/ILGPU/Runtime/Cuda/CudaDriverVersion.cs @@ -115,7 +115,7 @@ public static CudaDriverVersion FromValue(int value) => /// /// The other object. /// True, if the given object is equal to this version. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is CudaDriverVersion version && version == this; /// diff --git a/Src/ILGPU/Runtime/Cuda/CudaException.cs b/Src/ILGPU/Runtime/Cuda/CudaException.cs index fb174b767..a9b12c3d1 100644 --- a/Src/ILGPU/Runtime/Cuda/CudaException.cs +++ b/Src/ILGPU/Runtime/Cuda/CudaException.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: CudaException.cs @@ -29,9 +29,7 @@ public sealed class CudaException : AcceleratorException /// Constructs a new Cuda exception. /// public CudaException() - { - Error = "N/A"; - } + { } /// /// Constructs a new Cuda exception. @@ -69,7 +67,7 @@ public CudaException(string message, Exception innerException) private CudaException(SerializationInfo info, StreamingContext context) : base(info, context) { - Error = info.GetString("Error"); + Error = info.GetString("Error") ?? string.Empty; } #endregion @@ -79,7 +77,7 @@ private CudaException(SerializationInfo info, StreamingContext context) /// /// Returns the error. /// - public string Error { get; } + public string Error { get; } = "N/A"; /// /// Returns . diff --git a/Src/ILGPU/Runtime/Cuda/CudaInstructionSet.cs b/Src/ILGPU/Runtime/Cuda/CudaInstructionSet.cs index 209db1e45..9547af397 100644 --- a/Src/ILGPU/Runtime/Cuda/CudaInstructionSet.cs +++ b/Src/ILGPU/Runtime/Cuda/CudaInstructionSet.cs @@ -91,7 +91,7 @@ public int CompareTo(CudaInstructionSet other) /// The other object. /// True, /// if the given object is equal to this instruction set. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is CudaInstructionSet instructionSet && instructionSet == this; /// diff --git a/Src/ILGPU/Runtime/Cuda/CudaKernel.cs b/Src/ILGPU/Runtime/Cuda/CudaKernel.cs index fa73b9375..3f5c6c07c 100644 --- a/Src/ILGPU/Runtime/Cuda/CudaKernel.cs +++ b/Src/ILGPU/Runtime/Cuda/CudaKernel.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: CudaKernel.cs @@ -45,13 +45,13 @@ public sealed class CudaKernel : Kernel internal CudaKernel( CudaAccelerator accelerator, PTXCompiledKernel kernel, - MethodInfo launcher) + MethodInfo? launcher) : base(accelerator, kernel, launcher) { var kernelLoaded = CurrentAPI.LoadModule( out modulePtr, kernel.PTXAssembly, - out string errorLog); + out string? errorLog); if (kernelLoaded != CudaError.CUDA_SUCCESS) { Trace.WriteLine("PTX Kernel loading failed:"); diff --git a/Src/ILGPU/Runtime/Cuda/CudaMemoryBuffer.cs b/Src/ILGPU/Runtime/Cuda/CudaMemoryBuffer.cs index 744d2706c..c0ae2d9c8 100644 --- a/Src/ILGPU/Runtime/Cuda/CudaMemoryBuffer.cs +++ b/Src/ILGPU/Runtime/Cuda/CudaMemoryBuffer.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2022 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: CudaMemoryBuffer.cs @@ -32,7 +32,7 @@ public sealed class CudaMemoryBuffer : MemoryBuffer /// The value to write into the buffer. /// The target view to write to. public static void CudaMemSet( - CudaStream stream, + CudaStream? stream, byte value, in ArrayView targetView) where T : unmanaged @@ -62,7 +62,7 @@ public static void CudaMemSet( /// The source view to copy from. /// The target view to copy to. public static void CudaCopy( - CudaStream stream, + CudaStream? stream, in ArrayView sourceView, in ArrayView targetView) where T : unmanaged diff --git a/Src/ILGPU/Runtime/Cuda/CudaProfilingMarker.cs b/Src/ILGPU/Runtime/Cuda/CudaProfilingMarker.cs index 0d358deb8..276b6a565 100644 --- a/Src/ILGPU/Runtime/Cuda/CudaProfilingMarker.cs +++ b/Src/ILGPU/Runtime/Cuda/CudaProfilingMarker.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: CudaProfilingMarker.cs @@ -23,7 +23,7 @@ internal sealed class CudaProfilingMarker : ProfilingMarker #region Instance internal CudaProfilingMarker(Accelerator accelerator) - : base (accelerator) + : base(accelerator) { CudaException.ThrowIfFailed( CurrentAPI.CreateEvent( diff --git a/Src/ILGPU/Runtime/Cuda/NvvmAPI.cs b/Src/ILGPU/Runtime/Cuda/NvvmAPI.cs index b1a13bd95..d77396926 100644 --- a/Src/ILGPU/Runtime/Cuda/NvvmAPI.cs +++ b/Src/ILGPU/Runtime/Cuda/NvvmAPI.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: NvvmAPI.cs @@ -36,7 +36,7 @@ public sealed class NvvmAPI : DisposeBase CharSet = CharSet.Ansi, BestFitMapping = false, ThrowOnUnmappableChar = true)] - delegate string NvvmGetErrorString(NvvmResult result); + delegate string? NvvmGetErrorString(NvvmResult result); delegate NvvmResult NvvmVersion(out int major, out int minor); @@ -59,7 +59,7 @@ delegate NvvmResult NvvmAddModuleToProgram( IntPtr program, IntPtr buffer, IntPtr size, - string name); + string? name); [UnmanagedFunctionPointer( CallingConvention.Winapi, @@ -70,7 +70,7 @@ delegate NvvmResult NvvmLazyAddModuleToProgram( IntPtr program, IntPtr buffer, IntPtr size, - string name); + string? name); delegate NvvmResult NvvmCompileProgram( IntPtr program, @@ -245,7 +245,7 @@ protected override void Dispose(bool disposing) /// /// The error code. /// The error string. - public string GetErrorString(NvvmResult result) => + public string? GetErrorString(NvvmResult result) => nvvmGetErrorString(result); /// @@ -300,7 +300,7 @@ public NvvmResult AddModuleToProgram( IntPtr program, IntPtr buffer, IntPtr size, - string name) => + string? name) => nvvmAddModuleToProgram(program, buffer, size, name); /// @@ -315,7 +315,7 @@ public NvvmResult LazyAddModuleToProgram( IntPtr program, IntPtr buffer, IntPtr size, - string name) => + string? name) => nvvmLazyAddModuleToProgram(program, buffer, size, name); /// @@ -347,7 +347,7 @@ public NvvmResult VerifyProgram(IntPtr program, int numOptions, IntPtr options) /// The program. /// Filled in with the PTX result. /// The error code. - public unsafe NvvmResult GetCompiledResult(IntPtr program, out string result) + public unsafe NvvmResult GetCompiledResult(IntPtr program, out string? result) { var error = GetCompiledResultSize(program, out var bufferSize); if (error == NvvmResult.NVVM_SUCCESS) @@ -399,7 +399,7 @@ public NvvmResult GetCompiledResult(IntPtr program, IntPtr buffer) => /// The program. /// Filled in with the program log. /// The error code. - public unsafe NvvmResult GetProgramLog(IntPtr program, out string result) + public unsafe NvvmResult GetProgramLog(IntPtr program, out string? result) { var error = GetProgramLogSize(program, out var bufferSize); if (error == NvvmResult.NVVM_SUCCESS) diff --git a/Src/ILGPU/Runtime/CurrentAccelerator.cs b/Src/ILGPU/Runtime/CurrentAccelerator.cs index 14836a8b5..bfba7aec8 100644 --- a/Src/ILGPU/Runtime/CurrentAccelerator.cs +++ b/Src/ILGPU/Runtime/CurrentAccelerator.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: CurrentAccelerator.cs @@ -23,12 +23,12 @@ partial class Accelerator /// Represents the current accelerator. /// [ThreadStatic] - private static Accelerator currentAccelerator; + private static Accelerator? currentAccelerator; /// /// Returns the current group runtime context. /// - public static Accelerator Current + public static Accelerator? Current { get => currentAccelerator; private set => currentAccelerator = value; @@ -106,7 +106,7 @@ internal ScopedAcceleratorBinding(Accelerator accelerator) /// Returns the old accelerator that was the current one /// before the current binding operation (if any). /// - public Accelerator OldAccelerator { get; private set; } + public Accelerator? OldAccelerator { get; private set; } /// /// Returns true if an old accelerator has to be recovered. @@ -125,7 +125,7 @@ public void Recover() { if (!IsRecoverable) return; - OldAccelerator.Bind(); + OldAccelerator?.Bind(); OldAccelerator = null; } @@ -165,7 +165,7 @@ public void Recover() /// /// True, if the given object is equal to the current binding. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is ScopedAcceleratorBinding binding && Equals(binding); /// @@ -173,14 +173,14 @@ public override bool Equals(object obj) => /// /// The hash code of this binding. public override int GetHashCode() => - IsRecoverable ? OldAccelerator.GetHashCode() : 0; + OldAccelerator?.GetHashCode() ?? 0; /// /// Returns the string representation of this binding. /// /// The string representation of this binding. public override string ToString() => - IsRecoverable ? OldAccelerator.ToString() : ""; + OldAccelerator?.ToString() ?? ""; #endregion diff --git a/Src/ILGPU/Runtime/Device.cs b/Src/ILGPU/Runtime/Device.cs index 4517450cf..90910c9ea 100644 --- a/Src/ILGPU/Runtime/Device.cs +++ b/Src/ILGPU/Runtime/Device.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: Device.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.Resources; +using ILGPU.Util; using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -115,6 +116,9 @@ public abstract class Device : IDevice, IAcceleratorBuilder protected Device() { AcceleratorType = DeviceTypeAttribute.GetAcceleratorType(GetType()); + + // NB: Initialized later by derived classes. + Capabilities = Utilities.InitNotNullable(); } #endregion @@ -279,7 +283,7 @@ protected virtual void PrintGeneralInfo(TextWriter writer) /// /// True, if the given object is equal to the current device. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is Device device && device.AcceleratorType == AcceleratorType && device.Name == Name; diff --git a/Src/ILGPU/Runtime/Kernel.cs b/Src/ILGPU/Runtime/Kernel.cs index e05e46d6a..1a48e004f 100644 --- a/Src/ILGPU/Runtime/Kernel.cs +++ b/Src/ILGPU/Runtime/Kernel.cs @@ -14,9 +14,11 @@ using ILGPU.Backends.IL; using ILGPU.IR; using ILGPU.Resources; +using ILGPU.Util; using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; @@ -79,7 +81,8 @@ private static void ImplementSpecializationCacheArgs( new Type[] { field.FieldType - }); + }) + .AsNotNull(); emitter.EmitNewObject(instanceConstructor); emitter.Emit(OpCodes.Box, fieldReturnType); @@ -145,9 +148,10 @@ public static TDelegate CreateSpecializedLauncher( loader, entry, specialization); - return launcherMethod.CreateDelegate( + return (launcherMethod.CreateDelegate( typeof(TDelegate), - cacheInstance) as TDelegate; + cacheInstance) as TDelegate) + .AsNotNull(); } /// @@ -195,8 +199,9 @@ private static MethodInfo CreateSpecializedLauncherMethod( var valueProperty = param.SpecializedType.GetProperty( nameof(SpecializedValue.Value), - BindingFlags.Public | BindingFlags.Instance); - emitter.EmitCall(valueProperty.GetGetMethod()); + BindingFlags.Public | BindingFlags.Instance) + .AsNotNull(); + emitter.EmitCall(valueProperty.GetGetMethod().AsNotNull()); // Store value emitter.Emit(OpCodes.Stfld, fields[i]); @@ -205,7 +210,8 @@ private static MethodInfo CreateSpecializedLauncherMethod( // Resolve kernel and dispatch it var getOrCreateMethod = cacheType.GetMethod( "GetOrCreateKernel", - BindingFlags.Public | BindingFlags.Instance); + BindingFlags.Public | BindingFlags.Instance) + .AsNotNull(); emitter.Emit(ArgumentOperation.Load, KernelInstanceParamIdx); emitter.Emit(LocalOperation.Load, keyVariable); emitter.EmitCall(getOrCreateMethod); @@ -219,7 +225,8 @@ private static MethodInfo CreateSpecializedLauncherMethod( // Dispatch kernel var invokeMethod = typeof(TDelegate).GetMethod( "Invoke", - BindingFlags.Public | BindingFlags.Instance); + BindingFlags.Public | BindingFlags.Instance) + .AsNotNull(); emitter.EmitCall(invokeMethod); // Return @@ -273,7 +280,7 @@ private static Type CreateSpecializedLauncherStruct( protected Kernel( Accelerator accelerator, CompiledKernel compiledKernel, - MethodInfo launcher) + MethodInfo? launcher) : base(accelerator) { Debug.Assert(compiledKernel != null, "Invalid compiled kernel"); @@ -288,7 +295,7 @@ protected Kernel( /// /// Returns the associated kernel launcher. /// - public MethodInfo Launcher { get; internal set; } + public MethodInfo? Launcher { get; internal set; } /// /// Returns the associated specialization. @@ -307,7 +314,7 @@ protected Kernel( /// This instance will be available when the property /// is enabled. /// - public CompiledKernel.KernelInfo Info => CompiledKernel.Info; + public CompiledKernel.KernelInfo? Info => CompiledKernel.Info; /// /// Returns the associated compiled kernel object. @@ -327,7 +334,8 @@ protected Kernel( [MethodImpl(MethodImplOptions.AggressiveInlining)] public TDelegate CreateLauncherDelegate() where TDelegate : Delegate => - Launcher.CreateDelegate(typeof(TDelegate), this) as TDelegate; + (Launcher.AsNotNull().CreateDelegate(typeof(TDelegate), this) as TDelegate) + .AsNotNull(); /// /// Invokes the associated launcher via reflection. @@ -355,7 +363,7 @@ private void InvokeLauncher( ?? throw new ArgumentNullException(nameof(stream)); reflectionArgs[KernelParamDimensionIdx] = dimension; args.CopyTo(reflectionArgs, KernelParameterOffset); - Launcher.Invoke(null, reflectionArgs); + Launcher.AsNotNull().Invoke(null, reflectionArgs); } #endregion @@ -407,7 +415,7 @@ public static class KernelUtil /// True, if a kernel object could be resolved. public static bool TryGetKernel( this TDelegate kernelDelegate, - out Kernel kernel) + [NotNullWhen(true)] out Kernel? kernel) where TDelegate : Delegate { // Try to resolve the kernel object from the delegate directly. @@ -423,7 +431,8 @@ public static bool TryGetKernel( // needs to be extracted from this inner delegate using reflection. var displayClass = kernelDelegate.Method.DeclaringType; - if (displayClass.IsDefined(typeof(CompilerGeneratedAttribute), false)) + if (displayClass != null && + displayClass.IsDefined(typeof(CompilerGeneratedAttribute), false)) { var capturedFields = displayClass.GetFields( BindingFlags.Instance @@ -501,7 +510,7 @@ public static KernelSpecialization GetKernelSpecialization( /// This instance will be available when the property /// is enabled. /// - public static CompiledKernel.KernelInfo GetKernelInfo( + public static CompiledKernel.KernelInfo? GetKernelInfo( this TDelegate kernelDelegate) where TDelegate : Delegate => kernelDelegate.GetKernel().Info; diff --git a/Src/ILGPU/Runtime/KernelCache.cs b/Src/ILGPU/Runtime/KernelCache.cs index 88908a16c..f2799da46 100644 --- a/Src/ILGPU/Runtime/KernelCache.cs +++ b/Src/ILGPU/Runtime/KernelCache.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: KernelCache.cs @@ -12,9 +12,11 @@ using ILGPU.Backends; using ILGPU.Backends.EntryPoints; using ILGPU.Resources; +using ILGPU.Util; using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace ILGPU.Runtime @@ -101,7 +103,7 @@ public bool Equals(CachedCompiledKernelKey other) => /// /// True, if the given object is equal to the current one. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is CachedCompiledKernelKey other && Equals(other); /// @@ -183,7 +185,7 @@ public bool Equals(CachedKernelKey other) => /// /// The other object. /// True, if the given object is equal to the current one. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is CachedKernelKey other && Equals(other); /// @@ -219,7 +221,7 @@ private struct CachedKernel /// Detailed kernel information. public CachedKernel( WeakReference kernel, - KernelInfo kernelInfo) + KernelInfo? kernelInfo) { kernelReference = kernel; KernelInfo = kernelInfo; @@ -232,7 +234,7 @@ public CachedKernel( /// /// Returns the stored kernel information. /// - public KernelInfo KernelInfo { get; } + public KernelInfo? KernelInfo { get; } #endregion @@ -243,7 +245,7 @@ public CachedKernel( /// /// The resolved kernel. /// True, if the associated kernel could be resolved. - public readonly bool TryGetKernel(out T kernel) + public readonly bool TryGetKernel([NotNullWhen(true)] out T? kernel) where T : class { kernel = null; @@ -294,7 +296,7 @@ public interface IKernelLoader Kernel LoadKernel( Accelerator accelerator, CompiledKernel compiledKernel, - out KernelInfo kernelInfo); + out KernelInfo? kernelInfo); } /// @@ -302,7 +304,7 @@ Kernel LoadKernel( /// private delegate T CachedKernelLoader( in TKernelLoader kernelLoader, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where T : class where TKernelLoader : struct, IKernelLoader; @@ -316,13 +318,13 @@ private delegate T CachedKernelLoader( [DebuggerBrowsable(DebuggerBrowsableState.Never)] private Dictionary< CachedCompiledKernelKey, - WeakReference> compiledKernelCache; + WeakReference>? compiledKernelCache; /// /// A cache for loaded kernel objects. /// [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private Dictionary kernelCache; + private Dictionary? kernelCache; /// /// Initializes the local kernel cache. @@ -360,8 +362,8 @@ private void InitKernelCache() /// private bool RequestKernelCacheGC_SyncRoot => KernelCacheEnabled && - ((compiledKernelCache.Count + 1) % NumberNewKernelsUntilGC == 0 || - (kernelCache.Count + 1) % NumberNewKernelsUntilGC == 0); + ((compiledKernelCache.AsNotNull().Count + 1) % NumberNewKernelsUntilGC == 0 || + (kernelCache.AsNotNull().Count + 1) % NumberNewKernelsUntilGC == 0); #endregion @@ -384,7 +386,7 @@ private T LoadCachedKernel( in KernelSpecialization specialization, in TKernelLoader kernelLoader, CachedKernelLoader cachedLoader, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where T : class where TKernelLoader : struct, IKernelLoader { @@ -398,11 +400,13 @@ private T LoadCachedKernel( kernelLoader.GroupSize); lock (syncRoot) { - if (!kernelCache.TryGetValue(cachedKey, out CachedKernel cached) || - !cached.TryGetKernel(out T result)) + if (!kernelCache.AsNotNull().TryGetValue( + cachedKey, + out CachedKernel cached) || + !cached.TryGetKernel(out T? result)) { result = cachedLoader(kernelLoader, out kernelInfo); - kernelCache[cachedKey] = new CachedKernel( + kernelCache.AsNotNull()[cachedKey] = new CachedKernel( cached.UpdateReference(result), kernelInfo); } @@ -436,7 +440,7 @@ private Kernel LoadGenericKernelDirect( in EntryPointDescription entry, in KernelSpecialization specialization, in TKernelLoader kernelLoader, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TKernelLoader : struct, IKernelLoader { var compiledKernel = CompileKernel(entry, specialization); @@ -460,13 +464,13 @@ private Kernel LoadGenericKernel( EntryPointDescription entry, KernelSpecialization specialization, in TKernelLoader kernelLoader, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TKernelLoader : struct, IKernelLoader => LoadCachedKernel( entry, specialization, kernelLoader, - (in TKernelLoader loader, out KernelInfo info) => + (in TKernelLoader loader, out KernelInfo? info) => LoadGenericKernelDirect(entry, specialization, loader, out info), out kernelInfo); @@ -483,7 +487,7 @@ private TDelegate LoadSpecializationKernelDirect( in EntryPointDescription entry, in KernelSpecialization specialization, in TKernelLoader kernelLoader, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TDelegate : Delegate where TKernelLoader : struct, IKernelLoader { @@ -516,14 +520,14 @@ private TDelegate LoadSpecializationKernel( EntryPointDescription entry, KernelSpecialization specialization, in TKernelLoader kernelLoader, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TDelegate : Delegate where TKernelLoader : struct, IKernelLoader => LoadCachedKernel( entry, specialization, kernelLoader, - (in TKernelLoader loader, out KernelInfo info) => + (in TKernelLoader loader, out KernelInfo? info) => LoadSpecializationKernelDirect( entry, specialization, @@ -567,15 +571,15 @@ public CompiledKernel CompileKernel( var cachedKey = new CachedCompiledKernelKey(entry, specialization); lock (syncRoot) { - if (!compiledKernelCache.TryGetValue( + if (!compiledKernelCache.AsNotNull().TryGetValue( cachedKey, - out WeakReference cached) || - !cached.TryGetTarget(out CompiledKernel result)) + out WeakReference? cached) || + !cached.TryGetTarget(out CompiledKernel? result)) { result = Backend.Compile(entry, specialization); if (cached == null) { - compiledKernelCache.Add( + compiledKernelCache.AsNotNull().Add( cachedKey, new WeakReference(result)); } @@ -601,8 +605,8 @@ private void ClearKernelCache_SyncRoot() { if (!KernelCacheEnabled) return; - compiledKernelCache.Clear(); - kernelCache.Clear(); + compiledKernelCache.AsNotNull().Clear(); + kernelCache.AsNotNull().Clear(); } /// @@ -617,26 +621,26 @@ private void KernelCacheGC_SyncRoot() if (!KernelCacheEnabled) return; - if (compiledKernelCache.Count >= MinNumberOfKernelsInGC) + if (compiledKernelCache.AsNotNull().Count >= MinNumberOfKernelsInGC) { - var oldCompiledKernels = compiledKernelCache; + var oldCompiledKernels = compiledKernelCache.AsNotNull(); compiledKernelCache = new Dictionary< CachedCompiledKernelKey, WeakReference>(); foreach (var entry in oldCompiledKernels) { - if (entry.Value.TryGetTarget(out CompiledKernel _)) + if (entry.Value.TryGetTarget(out CompiledKernel? _)) compiledKernelCache.Add(entry.Key, entry.Value); } } - if (kernelCache.Count >= MinNumberOfKernelsInGC) + if (kernelCache.AsNotNull().Count >= MinNumberOfKernelsInGC) { - var oldKernels = kernelCache; + var oldKernels = kernelCache.AsNotNull(); kernelCache = new Dictionary(); foreach (var entry in oldKernels) { - if (entry.Value.TryGetKernel(out object _)) + if (entry.Value.TryGetKernel(out object? _)) kernelCache.Add(entry.Key, entry.Value); } } diff --git a/Src/ILGPU/Runtime/KernelInfo.cs b/Src/ILGPU/Runtime/KernelInfo.cs index 11c70261a..bd916dfe8 100644 --- a/Src/ILGPU/Runtime/KernelInfo.cs +++ b/Src/ILGPU/Runtime/KernelInfo.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: KernelInfo.cs @@ -31,7 +31,7 @@ public sealed class KernelInfo : CompiledKernel.KernelInfo /// The minimum grid size (if known). /// The created kernel information object. public static KernelInfo CreateFrom( - CompiledKernel.KernelInfo info, + CompiledKernel.KernelInfo? info, int? minGroupSize, int? minGridSize) => info is null diff --git a/Src/ILGPU/Runtime/KernelLauncherBuilder.cs b/Src/ILGPU/Runtime/KernelLauncherBuilder.cs index 461f8ba8d..96d48c4bf 100644 --- a/Src/ILGPU/Runtime/KernelLauncherBuilder.cs +++ b/Src/ILGPU/Runtime/KernelLauncherBuilder.cs @@ -12,6 +12,7 @@ using ILGPU.Backends.EntryPoints; using ILGPU.Backends.IL; using ILGPU.Resources; +using ILGPU.Util; using System; using System.Diagnostics; using System.Reflection; @@ -48,7 +49,7 @@ private static void EmitLoadDimensions( Action manipulateIdx) where TEmitter : struct, IILEmitter { - var indexFieldGetter = new MethodInfo[] + var indexFieldGetter = new MethodInfo?[] { indexType.GetProperty( nameof(Index3D.X), @@ -187,14 +188,18 @@ public static void EmitLoadKernelConfig( .GetProperty( nameof(KernelConfig.GridDim), BindingFlags.Public | BindingFlags.Instance) - .GetGetMethod()); + .AsNotNull() + .GetGetMethod() + .AsNotNull()); emitter.Emit(LocalOperation.LoadAddress, kernelCfgLocal); emitter.EmitCall( typeof(KernelConfig) .GetProperty( nameof(KernelConfig.GroupDim), BindingFlags.Public | BindingFlags.Instance) - .GetGetMethod()); + .AsNotNull() + .GetGetMethod() + .AsNotNull()); EmitVerifyKernelLaunchBounds(emitter, maxGridSize, maxGroupSize); } } @@ -225,7 +230,8 @@ private static void EmitVerifyKernelLaunchBounds( emitter.EmitCall( typeof(KernelLauncherBuilder).GetMethod( nameof(VerifyKernelLaunchBounds), - BindingFlags.NonPublic | BindingFlags.Static)); + BindingFlags.NonPublic | BindingFlags.Static) + .AsNotNull()); } /// diff --git a/Src/ILGPU/Runtime/KernelLoaders.tt b/Src/ILGPU/Runtime/KernelLoaders.tt index 1a5122eae..7d86f6c3a 100644 --- a/Src/ILGPU/Runtime/KernelLoaders.tt +++ b/Src/ILGPU/Runtime/KernelLoaders.tt @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2016-2021 ILGPU Project +// Copyright (c) 2016-2023 ILGPU Project // www.ilgpu.net // // File: KernelLoaders.tt/KernelLoaders.cs @@ -74,7 +74,7 @@ namespace ILGPU.Runtime public static Action> LoadKernel<<#= delegateParams.TypeParams #>>( this Accelerator accelerator, Action<<#= delegateParams.TypeParams #>> action, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) <#= delegateParams.TypeRestrictions #> { if (action == null) @@ -111,7 +111,7 @@ namespace ILGPU.Runtime public static Action> LoadStreamKernel<<#= delegateParams.TypeParams #>>( this Accelerator accelerator, Action<<#= delegateParams.TypeParams #>> action, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) <#= delegateParams.TypeRestrictions #> { var baseKernel = accelerator.LoadKernel<<#= delegateParams.TypeParams #>>(action, out kernelInfo); @@ -152,7 +152,7 @@ namespace ILGPU.Runtime this Accelerator accelerator, Action<<#= delegateParams.TypeParams #>> action, KernelSpecialization specialization, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) <#= delegateParams.TypeRestrictions #> { if (action == null) @@ -201,7 +201,7 @@ namespace ILGPU.Runtime this Accelerator accelerator, Action<<#= delegateParams.TypeParams #>> action, KernelSpecialization specialization, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) <#= delegateParams.TypeRestrictions #> { var baseKernel = accelerator.LoadKernel<<#= delegateParams.TypeParams #>>( @@ -260,7 +260,7 @@ namespace ILGPU.Runtime this Accelerator accelerator, Action> action, int customGroupSize, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TIndex : struct, IIndex <#= delegateParams.TypeRestrictions #> { @@ -316,7 +316,7 @@ namespace ILGPU.Runtime this Accelerator accelerator, Action> action, int customGroupSize, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TIndex : struct, IIndex <#= delegateParams.TypeRestrictions #> { @@ -362,7 +362,7 @@ namespace ILGPU.Runtime public static Action> LoadAutoGroupedKernel>( this Accelerator accelerator, Action> action, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TIndex : struct, IIndex <#= delegateParams.TypeRestrictions #> { @@ -405,7 +405,7 @@ namespace ILGPU.Runtime public static Action> LoadAutoGroupedStreamKernel>( this Accelerator accelerator, Action> action, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TIndex : struct, IIndex <#= delegateParams.TypeRestrictions #> { diff --git a/Src/ILGPU/Runtime/KernelLoading.cs b/Src/ILGPU/Runtime/KernelLoading.cs index fb7cc20e8..a2adfdb4e 100644 --- a/Src/ILGPU/Runtime/KernelLoading.cs +++ b/Src/ILGPU/Runtime/KernelLoading.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: KernelLoading.cs @@ -131,7 +131,7 @@ public Kernel LoadImplicitlyGroupedKernel( public Kernel LoadImplicitlyGroupedKernel( CompiledKernel kernel, int customGroupSize, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) { Bind(); return LoadImplicitlyGroupedKernelInternal( @@ -159,7 +159,7 @@ public Kernel LoadImplicitlyGroupedKernel( protected abstract Kernel LoadImplicitlyGroupedKernelInternal( CompiledKernel kernel, int customGroupSize, - out KernelInfo kernelInfo); + out KernelInfo? kernelInfo); /// /// Loads the given implicitly-grouped kernel while using an automatically @@ -187,7 +187,7 @@ public Kernel LoadAutoGroupedKernel(CompiledKernel kernel) => /// public Kernel LoadAutoGroupedKernel( CompiledKernel kernel, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) { Bind(); return LoadAutoGroupedKernelInternal(kernel, out kernelInfo); @@ -207,7 +207,7 @@ public Kernel LoadAutoGroupedKernel( /// protected abstract Kernel LoadAutoGroupedKernelInternal( CompiledKernel kernel, - out KernelInfo kernelInfo); + out KernelInfo? kernelInfo); #endregion @@ -229,7 +229,7 @@ private struct DefaultKernelLoader : IKernelLoader public Kernel LoadKernel( Accelerator accelerator, CompiledKernel compiledKernel, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) { var kernel = accelerator.LoadKernel(compiledKernel); kernelInfo = KernelInfo.CreateFrom( @@ -265,7 +265,7 @@ public GroupedKernelLoader(int groupSize) public Kernel LoadKernel( Accelerator accelerator, CompiledKernel compiledKernel, - out KernelInfo kernelInfo) => + out KernelInfo? kernelInfo) => accelerator.LoadImplicitlyGroupedKernel( compiledKernel, GroupSize, @@ -287,7 +287,7 @@ private struct AutoKernelLoader : IKernelLoader public Kernel LoadKernel( Accelerator accelerator, CompiledKernel compiledKernel, - out KernelInfo kernelInfo) => + out KernelInfo? kernelInfo) => accelerator.LoadAutoGroupedKernel( compiledKernel, out kernelInfo); @@ -312,7 +312,7 @@ private TDelegate LoadGenericKernel( in EntryPointDescription entry, in KernelSpecialization specialization, in TKernelLoader kernelLoader, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TDelegate : Delegate where TKernelLoader : struct, IKernelLoader { @@ -379,7 +379,7 @@ public Kernel LoadKernel( public Kernel LoadKernel( MethodInfo method, KernelSpecialization specialization, - out KernelInfo kernelInfo) => + out KernelInfo? kernelInfo) => LoadGenericKernel( EntryPointDescription.FromExplicitlyGroupedKernel(method), specialization, @@ -429,7 +429,7 @@ public Kernel LoadAutoGroupedKernel(MethodInfo method) => /// public Kernel LoadAutoGroupedKernel( MethodInfo method, - out KernelInfo kernelInfo) => + out KernelInfo? kernelInfo) => LoadGenericKernel( EntryPointDescription.FromImplicitlyGroupedKernel(method), KernelSpecialization.Empty, @@ -484,7 +484,7 @@ public TDelegate LoadKernel( public TDelegate LoadKernel( MethodInfo method, KernelSpecialization specialization, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TDelegate : Delegate => LoadGenericKernel( EntryPointDescription.FromExplicitlyGroupedKernel(method), @@ -527,7 +527,7 @@ public TDelegate LoadImplicitlyGroupedKernel( public TDelegate LoadImplicitlyGroupedKernel( MethodInfo method, int customGroupSize, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TDelegate : Delegate => LoadGenericKernel( EntryPointDescription.FromImplicitlyGroupedKernel(method), @@ -554,7 +554,7 @@ public TDelegate LoadAutoGroupedKernel(MethodInfo method) /// The loaded kernel-launcher delegate. public TDelegate LoadAutoGroupedKernel( MethodInfo method, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TDelegate : Delegate => LoadGenericKernel( EntryPointDescription.FromImplicitlyGroupedKernel(method), @@ -579,7 +579,7 @@ public TDelegate LoadAutoGroupedKernel( /// public TDelegate LoadKernel( TSourceDelegate methodDelegate, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TDelegate : Delegate where TSourceDelegate : Delegate => LoadKernel( @@ -604,7 +604,7 @@ public TDelegate LoadKernel( public TDelegate LoadKernel( TSourceDelegate methodDelegate, KernelSpecialization specialization, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TDelegate : Delegate where TSourceDelegate : Delegate => LoadKernel( @@ -651,7 +651,7 @@ public TDelegate LoadImplicitlyGroupedKernel( public TDelegate LoadImplicitlyGroupedKernel( TSourceDelegate methodDelegate, int customGroupSize, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TDelegate : Delegate where TSourceDelegate : Delegate => LoadImplicitlyGroupedKernel( @@ -670,7 +670,7 @@ public TDelegate LoadImplicitlyGroupedKernel( /// The loaded kernel-launcher delegate. public TDelegate LoadAutoGroupedKernel( TSourceDelegate methodDelegate, - out KernelInfo kernelInfo) + out KernelInfo? kernelInfo) where TDelegate : Delegate where TSourceDelegate : Delegate => LoadAutoGroupedKernel( diff --git a/Src/ILGPU/Runtime/KernelSpecialization.cs b/Src/ILGPU/Runtime/KernelSpecialization.cs index d6bdc5337..3da788522 100644 --- a/Src/ILGPU/Runtime/KernelSpecialization.cs +++ b/Src/ILGPU/Runtime/KernelSpecialization.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2018-2021 ILGPU Project +// Copyright (c) 2018-2023 ILGPU Project // www.ilgpu.net // // File: KernelSpecialization.cs @@ -120,7 +120,7 @@ public bool IsCompatibleWith(Accelerator accelerator) /// /// True, if the given object is equal to the current specialization. /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is KernelSpecialization specialization && specialization == this; /// diff --git a/Src/ILGPU/Runtime/MemoryBuffer.cs b/Src/ILGPU/Runtime/MemoryBuffer.cs index ea1f150b9..30b376b82 100644 --- a/Src/ILGPU/Runtime/MemoryBuffer.cs +++ b/Src/ILGPU/Runtime/MemoryBuffer.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: MemoryBuffer.cs @@ -26,16 +26,6 @@ public abstract class MemoryBuffer : AcceleratorObject { #region Instance - /// - /// Initializes this buffer on the CPU. - /// - /// The length of this source. - /// The element size. - protected MemoryBuffer(long length, int elementSize) - { - Init(length, elementSize); - } - /// /// Initializes this array view buffer. /// diff --git a/Src/ILGPU/Runtime/OpenCL/CLAPI.cs b/Src/ILGPU/Runtime/OpenCL/CLAPI.cs index 2593919ae..20b99dfbd 100644 --- a/Src/ILGPU/Runtime/OpenCL/CLAPI.cs +++ b/Src/ILGPU/Runtime/OpenCL/CLAPI.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: CLAPI.cs @@ -9,6 +9,7 @@ // Source License. See LICENSE.txt for details. // --------------------------------------------------------------------------------------- +using ILGPU.Util; using System; using System.Diagnostics; using System.Runtime.CompilerServices; @@ -338,7 +339,7 @@ public void GetDeviceInfo( /// The delegate type. /// The platform pointer. /// The resolved extension. - public T GetExtension(IntPtr platform) + public T? GetExtension(IntPtr platform) where T : Delegate => GetExtension(platform, typeof(T).Name); @@ -349,7 +350,7 @@ public T GetExtension(IntPtr platform) /// The platform pointer. /// The extension name. /// The resolved extension. - public T GetExtension(IntPtr platform, string name) + public T? GetExtension(IntPtr platform, string name) where T : Delegate { var address = clGetExtensionFunctionAddressForPlatform( @@ -606,7 +607,7 @@ public CLError GetProgramBuildInfo( public CLError GetProgramBuildLog( IntPtr program, IntPtr device, - out string buildLog) + out string? buildLog) { const int LogSize = 32_000; var log = new sbyte[LogSize]; @@ -959,7 +960,7 @@ public CLError ReadBuffer( IntPtr size, IntPtr ptr) { - var clStream = stream as CLStream; + var clStream = stream.AsNotNullCast(); CLException.ThrowIfFailed(EnqueueBarrier(clStream.CommandQueue)); return clEnqueueReadBuffer( clStream.CommandQueue, @@ -996,7 +997,7 @@ public CLError WriteBuffer( IntPtr size, IntPtr ptr) { - var clStream = stream as CLStream; + var clStream = stream.AsNotNullCast(); CLException.ThrowIfFailed(EnqueueBarrier(clStream.CommandQueue)); return clEnqueueWriteBuffer( clStream.CommandQueue, @@ -1031,7 +1032,7 @@ public CLError FillBuffer( IntPtr size) where T : unmanaged { - var clStream = stream as CLStream; + var clStream = stream.AsNotNullCast(); CLException.ThrowIfFailed(EnqueueBarrier(clStream.CommandQueue)); return clEnqueueFillBuffer( clStream.CommandQueue, @@ -1070,7 +1071,7 @@ public CLError CopyBuffer( IntPtr targetOffset, IntPtr size) { - var clStream = stream as CLStream; + var clStream = stream.AsNotNullCast(); CLException.ThrowIfFailed(EnqueueBarrier(clStream.CommandQueue)); return clEnqueueCopyBuffer( clStream.CommandQueue, diff --git a/Src/ILGPU/Runtime/OpenCL/CLAccelerator.cs b/Src/ILGPU/Runtime/OpenCL/CLAccelerator.cs index de4037ff3..8a83b7256 100644 --- a/Src/ILGPU/Runtime/OpenCL/CLAccelerator.cs +++ b/Src/ILGPU/Runtime/OpenCL/CLAccelerator.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CLAccelerator.cs @@ -35,7 +35,10 @@ public sealed class CLAccelerator : KernelAccelerator /// Represents the method. @@ -52,7 +56,8 @@ public sealed class CLAccelerator : KernelAccelerator /// Specifies the kernel entry point name for the following dummy kernels. @@ -219,7 +224,7 @@ private void InitSubGroupSupport(CLDevice acceleratorId) /// /// Returns the parent OpenCL device. /// - public new CLDevice Device => base.Device as CLDevice; + public new CLDevice Device => base.Device.AsNotNullCast(); /// /// Returns the native OpenCL platform id. @@ -274,7 +279,7 @@ private void InitSubGroupSupport(CLDevice acceleratorId) /// /// Returns the OpenCL backend of this accelerator. /// - public new CLBackend Backend => base.Backend as CLBackend; + public new CLBackend Backend => base.Backend.AsNotNullCast(); /// /// Returns the capabilities of this accelerator. @@ -528,7 +533,7 @@ protected override int EstimateGroupSizeInternal( if (maxGroupSize < 1) maxGroupSize = MaxNumThreadsPerGroup; - var clKernel = kernel as CLKernel; + var clKernel = kernel.AsNotNullCast(); var workGroupSizeNative = CurrentAPI.GetKernelWorkGroupInfo( clKernel.KernelPtr, DeviceId, diff --git a/Src/ILGPU/Runtime/OpenCL/CLDevice.cs b/Src/ILGPU/Runtime/OpenCL/CLDevice.cs index d77262f60..27437f61a 100644 --- a/Src/ILGPU/Runtime/OpenCL/CLDevice.cs +++ b/Src/ILGPU/Runtime/OpenCL/CLDevice.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021-2022 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: CLDevice.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.Backends.OpenCL; +using ILGPU.Util; using System; using System.Collections.Generic; using System.Collections.Immutable; @@ -191,7 +192,7 @@ private static void GetDevicesInternal( #region Instance - private readonly clGetKernelSubGroupInfoKHR getKernelSubGroupInfo; + private readonly clGetKernelSubGroupInfoKHR? getKernelSubGroupInfo; private readonly HashSet extensionSet = new HashSet(); /// @@ -231,6 +232,7 @@ public CLDevice(IntPtr platformId, IntPtr deviceId) /// /// Init general platform information. /// + [MemberNotNull(nameof(PlatformName))] private void InitPlatformInfo() { PlatformName = CurrentAPI.GetPlatformInfo( @@ -321,6 +323,7 @@ private void InitGridInfo() "CA1307:Specify StringComparison", Justification = "string.GetHashCode(StringComparison) not " + "available in net471")] + [MemberNotNull(nameof(VendorName))] private void InitVendorAndWarpSizeInfo() { VendorName = CurrentAPI.GetPlatformInfo( @@ -519,7 +522,7 @@ private void InitGenericAddressSpaceSupport() /// public new CLCapabilityContext Capabilities { - get => base.Capabilities as CLCapabilityContext; + get => base.Capabilities.AsNotNullCast(); private set => base.Capabilities = value; } @@ -725,7 +728,7 @@ protected override void PrintGeneralInfo(TextWriter writer) #region Object /// - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is CLDevice device && device.PlatformId == PlatformId && device.DeviceId == DeviceId && diff --git a/Src/ILGPU/Runtime/OpenCL/CLKernel.cs b/Src/ILGPU/Runtime/OpenCL/CLKernel.cs index abd6dd2fa..685bbdd90 100644 --- a/Src/ILGPU/Runtime/OpenCL/CLKernel.cs +++ b/Src/ILGPU/Runtime/OpenCL/CLKernel.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2021 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CLKernel.cs @@ -44,7 +44,7 @@ public static CLError LoadKernel( CLCVersion version, out IntPtr programPtr, out IntPtr kernelPtr, - out string errorLog) + out string? errorLog) { errorLog = null; kernelPtr = IntPtr.Zero; @@ -137,7 +137,7 @@ public static unsafe byte[] LoadBinaryRepresentation(IntPtr program) public CLKernel( CLAccelerator accelerator, CLCompiledKernel kernel, - MethodInfo launcher) + MethodInfo? launcher) : base(accelerator, kernel, launcher) { var errorCode = LoadKernel( diff --git a/Src/ILGPU/Runtime/OpenCL/CLMemoryBuffer.cs b/Src/ILGPU/Runtime/OpenCL/CLMemoryBuffer.cs index 02ac7722c..51365de42 100644 --- a/Src/ILGPU/Runtime/OpenCL/CLMemoryBuffer.cs +++ b/Src/ILGPU/Runtime/OpenCL/CLMemoryBuffer.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2019-2022 ILGPU Project +// Copyright (c) 2019-2023 ILGPU Project // www.ilgpu.net // // File: CLMemoryBuffer.cs @@ -10,6 +10,7 @@ // --------------------------------------------------------------------------------------- using ILGPU.Resources; +using ILGPU.Util; using System; using static ILGPU.Runtime.OpenCL.CLAPI; @@ -170,21 +171,21 @@ protected internal override void MemSet( AcceleratorStream stream, byte value, in ArrayView targetView) => - CLMemSet(stream as CLStream, value, targetView); + CLMemSet(stream.AsNotNullCast(), value, targetView); /// protected internal override void CopyFrom( AcceleratorStream stream, in ArrayView sourceView, in ArrayView targetView) => - CLCopy(stream as CLStream, sourceView, targetView); + CLCopy(stream.AsNotNullCast(), sourceView, targetView); /// protected internal override void CopyTo( AcceleratorStream stream, in ArrayView sourceView, in ArrayView targetView) => - CLCopy(stream as CLStream, sourceView, targetView); + CLCopy(stream.AsNotNullCast(), sourceView, targetView); #endregion diff --git a/Src/ILGPU/Runtime/PageLockedArrays.cs b/Src/ILGPU/Runtime/PageLockedArrays.cs index 14013c42c..9a92773da 100644 --- a/Src/ILGPU/Runtime/PageLockedArrays.cs +++ b/Src/ILGPU/Runtime/PageLockedArrays.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: PageLockedArrays.cs @@ -14,6 +14,7 @@ using ILGPU.Util; using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; namespace ILGPU.Runtime @@ -36,12 +37,14 @@ public abstract class PageLockedArray : DisposeBase /// /// Returns the memory buffer wrapper of the .Net array. /// - protected internal MemoryBuffer MemoryBuffer { get; private set; } + protected internal MemoryBuffer MemoryBuffer { get; private set; } = + Utilities.InitNotNullable(); /// /// Returns the page locking scope that includes the underlying array. /// - protected internal PageLockScope Scope { get; private set; } + protected internal PageLockScope Scope { get; private set; } = + Utilities.InitNotNullable>(); /// /// Returns the array view of the underlying .Net array. @@ -64,14 +67,14 @@ public abstract class PageLockedArray : DisposeBase /// The pinned host pointer. /// The total number of elements. protected unsafe void Initialize( - Accelerator accelerator, + Accelerator? accelerator, IntPtr ptr, long length) { if (length < 0L) throw new ArgumentNullException(nameof(length)); - if (length > 0L) + if (accelerator != null && length > 0L) { MemoryBuffer = CPUMemoryBuffer.Create( accelerator, @@ -140,7 +143,7 @@ public sealed class PageLockedArray1D : PageLockedArray /// /// The parent accelerator. /// The number of elements to allocate. - internal PageLockedArray1D(Accelerator accelerator, LongIndex1D extent) + internal PageLockedArray1D(Accelerator? accelerator, LongIndex1D extent) : this(accelerator, extent, false) { } @@ -151,7 +154,7 @@ internal PageLockedArray1D(Accelerator accelerator, LongIndex1D extent) /// The number of elements to allocate. /// True, to allocate an uninitialized array. internal unsafe PageLockedArray1D( - Accelerator accelerator, + Accelerator? accelerator, LongIndex1D extent, bool uninitialized) { diff --git a/Src/ILGPU/Runtime/PeerAccess.cs b/Src/ILGPU/Runtime/PeerAccess.cs index 6fae45046..5e01e4d90 100644 --- a/Src/ILGPU/Runtime/PeerAccess.cs +++ b/Src/ILGPU/Runtime/PeerAccess.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: PeerAccess.cs @@ -33,7 +33,7 @@ partial class Accelerator /// /// Event handler to disable peer access to disposed accelerators. /// - private void PeerAccessAcceleratorDestroyed(object sender, EventArgs e) + private void PeerAccessAcceleratorDestroyed(object? sender, EventArgs e) { // Reject cases in which the sender is not another accelerator instance if (!(sender is Accelerator otherAccelerator)) diff --git a/Src/ILGPU/Runtime/SpecializedValue.cs b/Src/ILGPU/Runtime/SpecializedValue.cs index 6e7017f76..643eb0c54 100644 --- a/Src/ILGPU/Runtime/SpecializedValue.cs +++ b/Src/ILGPU/Runtime/SpecializedValue.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: SpecializedValue.cs @@ -85,7 +85,7 @@ public SpecializedValue(T value) /// /// The other object. /// True, if the given object is equal to this value. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is SpecializedValue other && Equals(other); /// @@ -98,7 +98,7 @@ public override bool Equals(object obj) => /// Returns the string representation of this value. /// /// The string representation of this value. - public override string ToString() => Value.ToString(); + public override string? ToString() => Value.ToString(); #endregion diff --git a/Src/ILGPU/RuntimeSystem.cs b/Src/ILGPU/RuntimeSystem.cs index 342392e09..5afb90e12 100644 --- a/Src/ILGPU/RuntimeSystem.cs +++ b/Src/ILGPU/RuntimeSystem.cs @@ -13,6 +13,7 @@ using ILGPU.Util; using System; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Reflection; using System.Reflection.Emit; using System.Threading; @@ -164,6 +165,8 @@ public RuntimeSystem() /// /// Reloads the assembly builder. /// + [MemberNotNull(nameof(assemblyBuilder))] + [MemberNotNull(nameof(moduleBuilder))] private void ReloadAssemblyBuilder() { using var writerLock = assemblyLock.EnterWriteScope(); @@ -176,7 +179,8 @@ private void ReloadAssemblyBuilder() assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.RunAndCollect); - moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name); + moduleBuilder = + assemblyBuilder.DefineDynamicModule(assemblyName.Name.AsNotNull()); } /// diff --git a/Src/ILGPU/Static/DllLibraryImporter.ttinclude b/Src/ILGPU/Static/DllLibraryImporter.ttinclude index bc6d08950..bf33a4c8b 100644 --- a/Src/ILGPU/Static/DllLibraryImporter.ttinclude +++ b/Src/ILGPU/Static/DllLibraryImporter.ttinclude @@ -176,7 +176,7 @@ public void WriteLibraryCreateInternal(ImportLibrary importLib) WriteLine($"#region Creation"); WriteLine(); - Write($"private static {importLib.ClassName} CreateInternal("); + Write($"private static {importLib.ClassName}? CreateInternal("); WriteLine($"{importLib.VersionType} version)"); WriteLine("{"); diff --git a/Src/ILGPU/Util/DataBlocks.tt b/Src/ILGPU/Util/DataBlocks.tt index 330693583..cca407075 100644 --- a/Src/ILGPU/Util/DataBlocks.tt +++ b/Src/ILGPU/Util/DataBlocks.tt @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2016-2021 ILGPU Project +// Copyright (c) 2016-2023 ILGPU Project // www.ilgpu.net // // File: DataBlocks.tt/DataBlocks.cs @@ -115,7 +115,7 @@ namespace ILGPU.Util /// /// The other object. /// True, if the given object is equal to the current one. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is DataBlock<<#= typeParams.TypeParams #>> other && Equals(other); /// diff --git a/Src/ILGPU/Util/Extension.cs b/Src/ILGPU/Util/Extension.cs index 796368275..4dd6b5e15 100644 --- a/Src/ILGPU/Util/Extension.cs +++ b/Src/ILGPU/Util/Extension.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: Extension.cs @@ -12,6 +12,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; namespace ILGPU.Util { @@ -59,7 +60,8 @@ public interface IExtensionObject /// The extension type. /// The extension instance. /// True, if the extension could be retrieved. - bool TryGetExtension(out T extension) where T : TExtension; + bool TryGetExtension([NotNullWhen(true)] out T? extension) + where T : TExtension; /// /// Executes the given action for each registered extension. @@ -120,10 +122,11 @@ public T GetExtension() where T : TExtension /// The extension type. /// The extension instance. /// True, if the extension could be retrieved. - public bool TryGetExtension(out T extension) where T : TExtension + public bool TryGetExtension([NotNullWhen(true)] out T? extension) + where T : TExtension { extension = null; - if (!extensions.TryGetValue(typeof(T), out TExtension ext)) + if (!extensions.TryGetValue(typeof(T), out TExtension? ext)) return false; extension = ext as T; Debug.Assert(extension != null, "Invalid backend extension"); diff --git a/Src/ILGPU/Util/FormatString.cs b/Src/ILGPU/Util/FormatString.cs index 207e37e8a..29004b4ee 100644 --- a/Src/ILGPU/Util/FormatString.cs +++ b/Src/ILGPU/Util/FormatString.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2021 ILGPU Project +// Copyright (c) 2021-2023 ILGPU Project // www.ilgpu.net // // File: FormatString.cs @@ -61,7 +61,7 @@ public FormatExpression(int argument) /// /// Returns the string to output (if any). /// - public string String { get; } + public string? String { get; } /// /// Returns the argument reference to output. diff --git a/Src/ILGPU/Util/InlineList.cs b/Src/ILGPU/Util/InlineList.cs index cc6f59141..c43cd33ac 100644 --- a/Src/ILGPU/Util/InlineList.cs +++ b/Src/ILGPU/Util/InlineList.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2020-2021 ILGPU Project +// Copyright (c) 2020-2023 ILGPU Project // www.ilgpu.net // // File: InlineList.cs @@ -516,7 +516,7 @@ public interface IFormatter /// /// The item to format. /// The default string representation. - public readonly string Format(T item) => item.ToString(); + public readonly string Format(T item) => item?.ToString() ?? string.Empty; } /// diff --git a/Src/ILGPU/Util/MethodExtensions.cs b/Src/ILGPU/Util/MethodExtensions.cs index 5beff8120..ed3317e68 100644 --- a/Src/ILGPU/Util/MethodExtensions.cs +++ b/Src/ILGPU/Util/MethodExtensions.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: MethodExtensions.cs @@ -61,7 +61,8 @@ public static bool IsNotCapturingLambda(this MethodBase method) // https://github.com/dotnet/fsharp/tree/596f3d7 // var declaringType = method.DeclaringType; - return declaringType.IsClass + return declaringType != null + && declaringType.IsClass && declaringType.GetFields( BindingFlags.Instance | BindingFlags.NonPublic | diff --git a/Src/ILGPU/Util/NullableAttributes.cs b/Src/ILGPU/Util/NullableAttributes.cs new file mode 100644 index 000000000..0ea4d3d89 --- /dev/null +++ b/Src/ILGPU/Util/NullableAttributes.cs @@ -0,0 +1,225 @@ +// --------------------------------------------------------------------------------------- +// ILGPU +// Copyright (c) 2023 ILGPU Project +// www.ilgpu.net +// +// File: NullableAttributes.cs +// +// This file is part of ILGPU and is distributed under the University of Illinois Open +// Source License. See LICENSE.txt for details. +// --------------------------------------------------------------------------------------- + +// +// Adds missing Nullable Attributes for NETFRAMEWORK and NETSTANDARD. +// Source: https://raw.githubusercontent.com/dotnet/runtime/v7.0.0/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs +// +#if NETFRAMEWORK || NETSTANDARD + +// disable: max_line_length +#pragma warning disable IDE0021 // Use block body for constructor + +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +namespace System.Diagnostics.CodeAnalysis +{ +#if !NETSTANDARD2_1 + /// Specifies that null is allowed as an input even if the corresponding type disallows it. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class AllowNullAttribute : Attribute + { } + + /// Specifies that null is disallowed as an input even if the corresponding type allows it. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class DisallowNullAttribute : Attribute + { } + + /// Specifies that an output may be null even if the corresponding type disallows it. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class MaybeNullAttribute : Attribute + { } + + /// Specifies that an output will not be null even if the corresponding type allows it. Specifies that an input argument was not null when the call returns. + [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class NotNullAttribute : Attribute + { } + + /// Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class MaybeNullWhenAttribute : Attribute + { + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter may be null. + /// + public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } + } + + /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class NotNullWhenAttribute : Attribute + { + /// Initializes the attribute with the specified return value condition. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; + + /// Gets the return value condition. + public bool ReturnValue { get; } + } + + /// Specifies that the output will be non-null if the named parameter is non-null. + [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class NotNullIfNotNullAttribute : Attribute + { + /// Initializes the attribute with the associated parameter name. + /// + /// The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. + /// + public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName; + + /// Gets the associated parameter name. + public string ParameterName { get; } + } + + /// Applied to a method that will never return under any circumstance. + [AttributeUsage(AttributeTargets.Method, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class DoesNotReturnAttribute : Attribute + { } + + /// Specifies that the method will not return if the associated Boolean parameter is passed the specified value. + [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class DoesNotReturnIfAttribute : Attribute + { + /// Initializes the attribute with the specified parameter value. + /// + /// The condition parameter value. Code after the method will be considered unreachable by diagnostics if the argument to + /// the associated parameter matches this value. + /// + public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue; + + /// Gets the condition parameter value. + public bool ParameterValue { get; } + } +#endif + + /// Specifies that the method or property will ensure that the listed field and property members have not-null values. + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class MemberNotNullAttribute : Attribute + { + /// Initializes the attribute with a field or property member. + /// + /// The field or property member that is promised to be not-null. + /// + public MemberNotNullAttribute(string member) => Members = new[] { member }; + + /// Initializes the attribute with the list of field and property members. + /// + /// The list of field and property members that are promised to be not-null. + /// + public MemberNotNullAttribute(params string[] members) => Members = members; + + /// Gets field or property member names. + public string[] Members { get; } + } + + /// Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition. + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] +#if SYSTEM_PRIVATE_CORELIB + public +#else + internal +#endif + sealed class MemberNotNullWhenAttribute : Attribute + { + /// Initializes the attribute with the specified return value condition and a field or property member. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + /// + /// The field or property member that is promised to be not-null. + /// + public MemberNotNullWhenAttribute(bool returnValue, string member) + { + ReturnValue = returnValue; + Members = new[] { member }; + } + + /// Initializes the attribute with the specified return value condition and list of field and property members. + /// + /// The return value condition. If the method returns this value, the associated parameter will not be null. + /// + /// + /// The list of field and property members that are promised to be not-null. + /// + public MemberNotNullWhenAttribute(bool returnValue, params string[] members) + { + ReturnValue = returnValue; + Members = members; + } + + /// Gets the return value condition. + public bool ReturnValue { get; } + + /// Gets field or property member names. + public string[] Members { get; } + } +} + +#pragma warning restore IDE0021 // Use block body for constructor + +#endif diff --git a/Src/ILGPU/Util/PrimitiveDataBlocks.tt b/Src/ILGPU/Util/PrimitiveDataBlocks.tt index fc8aec7d8..6226f6775 100644 --- a/Src/ILGPU/Util/PrimitiveDataBlocks.tt +++ b/Src/ILGPU/Util/PrimitiveDataBlocks.tt @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2016-2021 ILGPU Project +// Copyright (c) 2016-2023 ILGPU Project // www.ilgpu.net // // File: PrimitiveDataBlocks.tt/PrimitiveDataBlocks.cs @@ -141,7 +141,7 @@ namespace ILGPU.Util /// /// The other object. /// True, if the given object is equal to the current one. - public override bool Equals(object obj) => + public override bool Equals(object? obj) => obj is <#= typeParams.TypeName #> other && Equals(other); /// diff --git a/Src/ILGPU/Util/TypeExtensions.cs b/Src/ILGPU/Util/TypeExtensions.cs index 59f2fa6aa..fc9b688a9 100644 --- a/Src/ILGPU/Util/TypeExtensions.cs +++ b/Src/ILGPU/Util/TypeExtensions.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2021 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: TypeExtensions.cs @@ -15,7 +15,7 @@ using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Reflection; -using System.Text; +using System.Runtime.CompilerServices; namespace ILGPU.Util { @@ -32,7 +32,9 @@ public static class TypeExtensions /// The resolved element type in case of an array view. /// /// True, in case of an array view. - public static bool IsArrayViewType(this Type type, out Type elementType) + public static bool IsArrayViewType( + this Type type, + [NotNullWhen(true)] out Type? elementType) { elementType = null; if (!type.IsGenericType || @@ -79,7 +81,9 @@ public static bool IsValueTuple(this Type type) /// The resolved element type in case of an array view. /// /// True, in case of an array view. - public static bool IsSpecializedType(this Type type, out Type nestedType) + public static bool IsSpecializedType( + this Type type, + [NotNullWhen(true)] out Type? nestedType) { nestedType = null; if (!type.IsGenericType || @@ -98,7 +102,9 @@ public static bool IsSpecializedType(this Type type, out Type nestedType) /// The source type. /// The element type (if any). /// True, if the given type is an immutable array. - public static bool IsImmutableArray(this Type type, out Type elementType) + public static bool IsImmutableArray( + this Type type, + [NotNullWhen(true)] out Type? elementType) { elementType = null; if (!type.IsGenericType || @@ -132,7 +138,7 @@ public static bool IsDelegate(this Type type) => /// /// The source type. /// The resolved delegate invocation method. - public static MethodInfo GetDelegateInvokeMethod(this Type type) + public static MethodInfo? GetDelegateInvokeMethod(this Type type) { const string InvokeMethodName = "Invoke"; return !type.IsDelegate() @@ -234,7 +240,7 @@ public static bool IsILGPUPrimitiveType(this Type type) => /// /// The source type. /// The resolved managed type. - public static Type GetManagedType(this BasicValueType type) => + public static Type? GetManagedType(this BasicValueType type) => type switch { BasicValueType.Int1 => typeof(bool), @@ -455,5 +461,27 @@ public static bool IsFloat(this ArithmeticBasicValueType value) /// The required conversion flags. internal static ConvertFlags ToTargetUnsignedFlags(this Type type) => type.IsUnsignedInt() ? ConvertFlags.TargetUnsigned : ConvertFlags.None; + + /// + /// Applies the null-forgiving operator. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T AsNotNull(this T? value) + => value!; + + /// + /// Applies the null-forgiving operator. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T AsNotNullCast(this object? value) + where T : class + => (value as T).AsNotNull(); + + /// + /// Throws exception of the value is null. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T ThrowIfNull(this T? value) + => value ?? throw new ArgumentNullException(nameof(value)); } } diff --git a/Src/ILGPU/Util/Utilities.cs b/Src/ILGPU/Util/Utilities.cs index 50b3f193c..f0f74ca01 100644 --- a/Src/ILGPU/Util/Utilities.cs +++ b/Src/ILGPU/Util/Utilities.cs @@ -1,6 +1,6 @@ // --------------------------------------------------------------------------------------- // ILGPU -// Copyright (c) 2017-2022 ILGPU Project +// Copyright (c) 2017-2023 ILGPU Project // www.ilgpu.net // // File: Utilities.cs @@ -109,5 +109,12 @@ public static long GCD(long a, long b) [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long LCM(long a, long b) => a * b / GCD(a, b); + + /// + /// Initializes a non-nullable instance with null. + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static T InitNotNullable() + => default(T).AsNotNull(); } }