From 633c5ec3306e474dab15617c5f93b94546bd9e09 Mon Sep 17 00:00:00 2001
From: gdkchan <gab.dark.100@gmail.com>
Date: Sun, 5 Jun 2022 14:15:27 -0300
Subject: [PATCH] Extend uses count from ushort to uint on Operand Data
 structure (#3374)

---
 .../IntermediateRepresentation/Operand.cs     | 72 +++++++++++++++++--
 1 file changed, 67 insertions(+), 5 deletions(-)

diff --git a/ARMeilleure/IntermediateRepresentation/Operand.cs b/ARMeilleure/IntermediateRepresentation/Operand.cs
index 74b1c71ef..b3aafa7ae 100644
--- a/ARMeilleure/IntermediateRepresentation/Operand.cs
+++ b/ARMeilleure/IntermediateRepresentation/Operand.cs
@@ -14,10 +14,11 @@ namespace ARMeilleure.IntermediateRepresentation
             public byte Kind;
             public byte Type;
             public byte SymbolType;
+            public byte Padding; // Unused space.
             public ushort AssignmentsCount;
             public ushort AssignmentsCapacity;
-            public ushort UsesCount;
-            public ushort UsesCapacity;
+            public uint UsesCount;
+            public uint UsesCapacity;
             public Operation* Assignments;
             public Operation* Uses;
             public ulong Value;
@@ -84,11 +85,11 @@ namespace ARMeilleure.IntermediateRepresentation
             {
                 Debug.Assert(Kind != OperandKind.Memory);
 
-                return new ReadOnlySpan<Operation>(_data->Uses, _data->UsesCount);
+                return new ReadOnlySpan<Operation>(_data->Uses, (int)_data->UsesCount);
             }
         }
 
-        public int UsesCount => _data->UsesCount;
+        public int UsesCount => (int)_data->UsesCount;
         public int AssignmentsCount => _data->AssignmentsCount;
 
         public bool Relocatable => Symbol.Type != SymbolType.None;
@@ -178,7 +179,7 @@ namespace ARMeilleure.IntermediateRepresentation
                 {
                     Add(operation, ref addr._data->Assignments, ref addr._data->AssignmentsCount, ref addr._data->AssignmentsCapacity);
                 }
-                
+
                 if (index != default)
                 {
                     Add(operation, ref index._data->Assignments, ref index._data->AssignmentsCount, ref index._data->AssignmentsCapacity);
@@ -265,6 +266,13 @@ namespace ARMeilleure.IntermediateRepresentation
             data = Allocators.References.Allocate<T>(initialCapacity);
         }
 
+        private static void New<T>(ref T* data, ref uint count, ref uint capacity, uint initialCapacity) where T : unmanaged
+        {
+            count = 0;
+            capacity = initialCapacity;
+            data = Allocators.References.Allocate<T>(initialCapacity);
+        }
+
         private static void Add<T>(T item, ref T* data, ref ushort count, ref ushort capacity) where T : unmanaged
         {
             if (count < capacity)
@@ -294,6 +302,40 @@ namespace ARMeilleure.IntermediateRepresentation
             }
         }
 
+        private static void Add<T>(T item, ref T* data, ref uint count, ref uint capacity) where T : unmanaged
+        {
+            if (count < capacity)
+            {
+                data[count++] = item;
+
+                return;
+            }
+
+            // Could not add item in the fast path, fallback onto the slow path.
+            ExpandAdd(item, ref data, ref count, ref capacity);
+
+            static void ExpandAdd(T item, ref T* data, ref uint count, ref uint capacity)
+            {
+                uint newCount = checked(count + 1);
+                uint newCapacity = (uint)Math.Min(capacity * 2, int.MaxValue);
+
+                if (newCapacity <= capacity)
+                {
+                    throw new OverflowException();
+                }
+
+                var oldSpan = new Span<T>(data, (int)count);
+
+                capacity = newCapacity;
+                data = Allocators.References.Allocate<T>(capacity);
+
+                oldSpan.CopyTo(new Span<T>(data, (int)count));
+
+                data[count] = item;
+                count = newCount;
+            }
+        }
+
         private static void Remove<T>(in T item, ref T* data, ref ushort count) where T : unmanaged
         {
             var span = new Span<T>(data, count);
@@ -314,6 +356,26 @@ namespace ARMeilleure.IntermediateRepresentation
             }
         }
 
+        private static void Remove<T>(in T item, ref T* data, ref uint count) where T : unmanaged
+        {
+            var span = new Span<T>(data, (int)count);
+
+            for (int i = 0; i < span.Length; i++)
+            {
+                if (EqualityComparer<T>.Default.Equals(span[i], item))
+                {
+                    if (i + 1 < count)
+                    {
+                        span.Slice(i + 1).CopyTo(span.Slice(i));
+                    }
+
+                    count--;
+
+                    return;
+                }
+            }
+        }
+
         public override int GetHashCode()
         {
             if (Kind == OperandKind.LocalVariable)