aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/CodeGen/RegisterAllocators
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/CodeGen/RegisterAllocators')
-rw-r--r--ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs7
-rw-r--r--ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs244
-rw-r--r--ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs70
-rw-r--r--ARMeilleure/CodeGen/RegisterAllocators/LiveInterval.cs2
4 files changed, 165 insertions, 158 deletions
diff --git a/ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs b/ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs
index 417f3bae..cc731b74 100644
--- a/ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs
+++ b/ARMeilleure/CodeGen/RegisterAllocators/CopyResolver.cs
@@ -1,9 +1,8 @@
using ARMeilleure.IntermediateRepresentation;
using System;
using System.Collections.Generic;
-
-using static ARMeilleure.IntermediateRepresentation.OperandHelper;
-using static ARMeilleure.IntermediateRepresentation.OperationHelper;
+using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
+using static ARMeilleure.IntermediateRepresentation.Operation.Factory;
namespace ARMeilleure.CodeGen.RegisterAllocators
{
@@ -210,7 +209,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
Operand register = GetRegister(left.Register, type);
- _spillQueue.Enqueue(Operation(Instruction.Spill, null, offset, register));
+ _spillQueue.Enqueue(Operation(Instruction.Spill, default, offset, register));
HasCopy = true;
}
diff --git a/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs b/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs
index 2f68c43f..7b339efb 100644
--- a/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs
+++ b/ARMeilleure/CodeGen/RegisterAllocators/HybridAllocator.cs
@@ -1,11 +1,10 @@
using ARMeilleure.IntermediateRepresentation;
using ARMeilleure.Translation;
-using System.Collections.Generic;
+using System;
using System.Diagnostics;
using System.Numerics;
-
-using static ARMeilleure.IntermediateRepresentation.OperandHelper;
-using static ARMeilleure.IntermediateRepresentation.OperationHelper;
+using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
+using static ARMeilleure.IntermediateRepresentation.Operation.Factory;
namespace ARMeilleure.CodeGen.RegisterAllocators
{
@@ -29,19 +28,14 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
}
}
- private class LocalInfo
+ private struct LocalInfo
{
- public int Uses { get; set; }
- public int UseCount { get; set; }
-
- public bool PreAllocated { get; set; }
- public int Register { get; set; }
- public int SpillOffset { get; set; }
-
+ public int Uses { get; set; }
+ public int UsesAllocated { get; set; }
+ public int Register { get; set; }
+ public int SpillOffset { get; set; }
public int Sequence { get; set; }
-
public Operand Temp { get; set; }
-
public OperandType Type { get; }
private int _first;
@@ -49,13 +43,21 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public bool IsBlockLocal => _first == _last;
- public LocalInfo(OperandType type, int uses)
+ public LocalInfo(OperandType type, int uses, int blkIndex)
{
Uses = uses;
Type = type;
+ UsesAllocated = 0;
+ Register = 0;
+ SpillOffset = 0;
+ Sequence = 0;
+ Temp = default;
+
_first = -1;
_last = -1;
+
+ SetBlockIndex(blkIndex);
}
public void SetBlockIndex(int blkIndex)
@@ -72,10 +74,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
}
}
- public AllocationResult RunPass(
- ControlFlowGraph cfg,
- StackAllocator stackAlloc,
- RegisterMasks regMasks)
+ public AllocationResult RunPass(ControlFlowGraph cfg, StackAllocator stackAlloc, RegisterMasks regMasks)
{
int intUsedRegisters = 0;
int vecUsedRegisters = 0;
@@ -84,9 +83,33 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
int vecFreeRegisters = regMasks.VecAvailableRegisters;
var blockInfo = new BlockInfo[cfg.Blocks.Count];
+ var localInfo = new LocalInfo[cfg.Blocks.Count * 3];
+ int localInfoCount = 0;
+
+ // The "visited" state is stored in the MSB of the local's value.
+ const ulong VisitedMask = 1ul << 63;
+
+ bool IsVisited(Operand local)
+ {
+ return (local.GetValueUnsafe() & VisitedMask) != 0;
+ }
+
+ void SetVisited(Operand local)
+ {
+ local.GetValueUnsafe() |= VisitedMask | (uint)++localInfoCount;
+ }
+
+ ref LocalInfo GetLocalInfo(Operand local)
+ {
+ Debug.Assert(local.Kind == OperandKind.LocalVariable);
+
+ if (!IsVisited(local))
+ {
+ throw new InvalidOperationException("Local was not visisted yet. Used before defined?");
+ }
- var locInfo = new List<LocalInfo>();
- var locVisited = new HashSet<Operand>();
+ return ref localInfo[(uint)local.GetValueUnsafe() - 1];
+ }
for (int index = cfg.PostOrderBlocks.Length - 1; index >= 0; index--)
{
@@ -97,59 +120,58 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
bool hasCall = false;
- for (Node node = block.Operations.First; node != null; node = node.ListNext)
+ for (Operation node = block.Operations.First; node != default; node = node.ListNext)
{
- if (node is Operation operation && operation.Instruction == Instruction.Call)
+ if (node.Instruction == Instruction.Call)
{
hasCall = true;
}
- for (int srcIndex = 0; srcIndex < node.SourcesCount; srcIndex++)
+ for (int i = 0; i < node.SourcesCount; i++)
{
- Operand source = node.GetSource(srcIndex);
+ Operand source = node.GetSource(i);
if (source.Kind == OperandKind.LocalVariable)
{
- locInfo[source.GetLocalNumber() - 1].SetBlockIndex(block.Index);
+ GetLocalInfo(source).SetBlockIndex(block.Index);
}
else if (source.Kind == OperandKind.Memory)
{
- MemoryOperand memOp = (MemoryOperand)source;
+ MemoryOperand memOp = source.GetMemory();
- if (memOp.BaseAddress != null)
+ if (memOp.BaseAddress != default)
{
- locInfo[memOp.BaseAddress.GetLocalNumber() - 1].SetBlockIndex(block.Index);
+ GetLocalInfo(memOp.BaseAddress).SetBlockIndex(block.Index);
}
- if (memOp.Index != null)
+ if (memOp.Index != default)
{
- locInfo[memOp.Index.GetLocalNumber() - 1].SetBlockIndex(block.Index);
+ GetLocalInfo(memOp.Index).SetBlockIndex(block.Index);
}
}
}
- for (int dstIndex = 0; dstIndex < node.DestinationsCount; dstIndex++)
+ for (int i = 0; i < node.DestinationsCount; i++)
{
- Operand dest = node.GetDestination(dstIndex);
+ Operand dest = node.GetDestination(i);
if (dest.Kind == OperandKind.LocalVariable)
{
- LocalInfo info;
-
- if (!locVisited.Add(dest))
+ if (IsVisited(dest))
{
- info = locInfo[dest.GetLocalNumber() - 1];
+ GetLocalInfo(dest).SetBlockIndex(block.Index);
}
else
{
- dest.NumberLocal(locInfo.Count + 1);
+ SetVisited(dest);
- info = new LocalInfo(dest.Type, UsesCount(dest));
+ if (localInfoCount > localInfo.Length)
+ {
+ Array.Resize(ref localInfo, localInfoCount * 2);
+ }
- locInfo.Add(info);
+ GetLocalInfo(dest) = new LocalInfo(dest.Type, UsesCount(dest), block.Index);
}
-
- info.SetBlockIndex(block.Index);
}
else if (dest.Kind == OperandKind.Register)
{
@@ -192,42 +214,26 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
intLocalFreeRegisters &= ~(intSpillTempRegisters | intCallerSavedRegisters);
vecLocalFreeRegisters &= ~(vecSpillTempRegisters | vecCallerSavedRegisters);
- for (Node node = block.Operations.First; node != null; node = node.ListNext)
+ for (Operation node = block.Operations.First; node != default; node = node.ListNext)
{
int intLocalUse = 0;
int vecLocalUse = 0;
- void AllocateRegister(Operand source, MemoryOperand memOp, int srcIndex)
+ Operand AllocateRegister(Operand local)
{
- LocalInfo info = locInfo[source.GetLocalNumber() - 1];
+ ref LocalInfo info = ref GetLocalInfo(local);
- info.UseCount++;
+ info.UsesAllocated++;
- Debug.Assert(info.UseCount <= info.Uses);
+ Debug.Assert(info.UsesAllocated <= info.Uses);
if (info.Register != -1)
{
- Operand reg = Register(info.Register, source.Type.ToRegisterType(), source.Type);
-
- if (memOp != null)
- {
- if (srcIndex == 0)
- {
- memOp.BaseAddress = reg;
- }
- else /* if (srcIndex == 1) */
- {
- memOp.Index = reg;
- }
- }
- else
- {
- node.SetSource(srcIndex, reg);
- }
+ Operand reg = Register(info.Register, local.Type.ToRegisterType(), local.Type);
- if (info.UseCount == info.Uses && !info.PreAllocated)
+ if (info.UsesAllocated == info.Uses)
{
- if (source.Type.IsInteger())
+ if (local.Type.IsInteger())
{
intLocalFreeRegisters |= 1 << info.Register;
}
@@ -236,72 +242,80 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
vecLocalFreeRegisters |= 1 << info.Register;
}
}
- }
- else if (node is Operation operation && operation.Instruction == Instruction.Copy)
- {
- Operation fillOp = Operation(Instruction.Fill, node.Destination, Const(info.SpillOffset));
- block.Operations.AddBefore(node, fillOp);
- block.Operations.Remove(node);
-
- node = fillOp;
+ return reg;
}
else
{
Operand temp = info.Temp;
- if (temp == null || info.Sequence != sequence)
+ if (temp == default || info.Sequence != sequence)
{
- temp = source.Type.IsInteger()
- ? GetSpillTemp(source, intSpillTempRegisters, ref intLocalUse)
- : GetSpillTemp(source, vecSpillTempRegisters, ref vecLocalUse);
+ temp = local.Type.IsInteger()
+ ? GetSpillTemp(local, intSpillTempRegisters, ref intLocalUse)
+ : GetSpillTemp(local, vecSpillTempRegisters, ref vecLocalUse);
info.Sequence = sequence;
info.Temp = temp;
}
- if (memOp != null)
- {
- if (srcIndex == 0)
- {
- memOp.BaseAddress = temp;
- }
- else /* if (srcIndex == 1) */
- {
- memOp.Index = temp;
- }
- }
- else
- {
- node.SetSource(srcIndex, temp);
- }
-
Operation fillOp = Operation(Instruction.Fill, temp, Const(info.SpillOffset));
block.Operations.AddBefore(node, fillOp);
+
+ return temp;
}
}
- for (int srcIndex = 0; srcIndex < node.SourcesCount; srcIndex++)
+ bool folded = false;
+
+ // If operation is a copy of a local and that local is living on the stack, we turn the copy into
+ // a fill, instead of inserting a fill before it.
+ if (node.Instruction == Instruction.Copy)
{
- Operand source = node.GetSource(srcIndex);
+ Operand source = node.GetSource(0);
if (source.Kind == OperandKind.LocalVariable)
{
- AllocateRegister(source, null, srcIndex);
+ ref LocalInfo info = ref GetLocalInfo(source);
+
+ if (info.Register == -1)
+ {
+ Operation fillOp = Operation(Instruction.Fill, node.Destination, Const(info.SpillOffset));
+
+ block.Operations.AddBefore(node, fillOp);
+ block.Operations.Remove(node);
+
+ node = fillOp;
+
+ folded = true;
+ }
}
- else if (source.Kind == OperandKind.Memory)
+ }
+
+ if (!folded)
+ {
+ for (int i = 0; i < node.SourcesCount; i++)
{
- MemoryOperand memOp = (MemoryOperand)source;
+ Operand source = node.GetSource(i);
- if (memOp.BaseAddress != null)
+ if (source.Kind == OperandKind.LocalVariable)
{
- AllocateRegister(memOp.BaseAddress, memOp, 0);
+ node.SetSource(i, AllocateRegister(source));
}
-
- if (memOp.Index != null)
+ else if (source.Kind == OperandKind.Memory)
{
- AllocateRegister(memOp.Index, memOp, 1);
+ MemoryOperand memOp = source.GetMemory();
+
+ if (memOp.BaseAddress != default)
+ {
+ memOp.BaseAddress = AllocateRegister(memOp.BaseAddress);
+ }
+
+ if (memOp.Index != default)
+ {
+ memOp.Index = AllocateRegister(memOp.Index);
+ }
}
}
}
@@ -309,18 +323,18 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
int intLocalAsg = 0;
int vecLocalAsg = 0;
- for (int dstIndex = 0; dstIndex < node.DestinationsCount; dstIndex++)
+ for (int i = 0; i < node.DestinationsCount; i++)
{
- Operand dest = node.GetDestination(dstIndex);
+ Operand dest = node.GetDestination(i);
if (dest.Kind != OperandKind.LocalVariable)
{
continue;
}
- LocalInfo info = locInfo[dest.GetLocalNumber() - 1];
+ ref LocalInfo info = ref GetLocalInfo(dest);
- if (info.UseCount == 0 && !info.PreAllocated)
+ if (info.UsesAllocated == 0)
{
int mask = dest.Type.IsInteger()
? intLocalFreeRegisters
@@ -350,19 +364,19 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
}
}
- info.UseCount++;
+ info.UsesAllocated++;
- Debug.Assert(info.UseCount <= info.Uses);
+ Debug.Assert(info.UsesAllocated <= info.Uses);
if (info.Register != -1)
{
- node.SetDestination(dstIndex, Register(info.Register, dest.Type.ToRegisterType(), dest.Type));
+ node.SetDestination(i, Register(info.Register, dest.Type.ToRegisterType(), dest.Type));
}
else
{
Operand temp = info.Temp;
- if (temp == null || info.Sequence != sequence)
+ if (temp == default || info.Sequence != sequence)
{
temp = dest.Type.IsInteger()
? GetSpillTemp(dest, intSpillTempRegisters, ref intLocalAsg)
@@ -372,9 +386,9 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
info.Temp = temp;
}
- node.SetDestination(dstIndex, temp);
+ node.SetDestination(i, temp);
- Operation spillOp = Operation(Instruction.Spill, null, Const(info.SpillOffset), temp);
+ Operation spillOp = Operation(Instruction.Spill, default, Const(info.SpillOffset), temp);
block.Operations.AddAfter(node, spillOp);
@@ -435,7 +449,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private static int UsesCount(Operand local)
{
- return local.Assignments.Count + local.Uses.Count;
+ return local.AssignmentsCount + local.UsesCount;
}
}
} \ No newline at end of file
diff --git a/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs b/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs
index 88adeeb0..fd1420a2 100644
--- a/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs
+++ b/ARMeilleure/CodeGen/RegisterAllocators/LinearScanAllocator.cs
@@ -29,11 +29,11 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
private LiveInterval[] _parentIntervals;
- private List<(IntrusiveList<Node>, Node)> _operationNodes;
+ private List<(IntrusiveList<Operation>, Operation)> _operationNodes;
private int _operationsCount;
- private class AllocationContext : IDisposable
+ private class AllocationContext
{
public RegisterMasks Masks { get; }
@@ -50,10 +50,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
StackAlloc = stackAlloc;
Masks = masks;
- BitMapPool.PrepareBitMapPool();
-
- Active = BitMapPool.Allocate(intervalsCount);
- Inactive = BitMapPool.Allocate(intervalsCount);
+ Active = new BitMap(Allocators.Default, intervalsCount);
+ Inactive = new BitMap(Allocators.Default, intervalsCount);
}
public void MoveActiveToInactive(int bit)
@@ -72,11 +70,6 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
dest.Set(bit);
}
-
- public void Dispose()
- {
- BitMapPool.ResetBitMapPool();
- }
}
public AllocationResult RunPass(
@@ -86,7 +79,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{
NumberLocals(cfg);
- using AllocationContext context = new AllocationContext(stackAlloc, regMasks, _intervals.Count);
+ var context = new AllocationContext(stackAlloc, regMasks, _intervals.Count);
BuildIntervals(cfg, context);
@@ -588,7 +581,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
int splitPosition = kv.Key;
- (IntrusiveList<Node> nodes, Node node) = GetOperationNode(splitPosition);
+ (IntrusiveList<Operation> nodes, Operation node) = GetOperationNode(splitPosition);
Operation[] sequence = copyResolver.Sequence();
@@ -621,9 +614,9 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
continue;
}
- bool hasSingleOrNoSuccessor = block.SuccessorCount <= 1;
+ bool hasSingleOrNoSuccessor = block.SuccessorsCount <= 1;
- for (int i = 0; i < block.SuccessorCount; i++)
+ for (int i = 0; i < block.SuccessorsCount; i++)
{
BasicBlock successor = block.GetSuccessor(i);
@@ -677,7 +670,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{
successor.Operations.AddFirst(sequence[0]);
- Node prependNode = sequence[0];
+ Operation prependNode = sequence[0];
for (int index = 1; index < sequence.Length; index++)
{
@@ -710,7 +703,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
for (int i = usePositions.Count - 1; i >= 0; i--)
{
int usePosition = -usePositions[i];
- (_, Node operation) = GetOperationNode(usePosition);
+ (_, Operation operation) = GetOperationNode(usePosition);
for (int index = 0; index < operation.SourcesCount; index++)
{
@@ -722,7 +715,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
}
else if (source.Kind == OperandKind.Memory)
{
- MemoryOperand memOp = (MemoryOperand)source;
+ MemoryOperand memOp = source.GetMemory();
if (memOp.BaseAddress == current.Local)
{
@@ -752,20 +745,20 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{
Debug.Assert(!interval.IsSpilled, "Spilled intervals are not allowed.");
- return OperandHelper.Register(
+ return Operand.Factory.Register(
interval.Register.Index,
interval.Register.Type,
interval.Local.Type);
}
- private (IntrusiveList<Node>, Node) GetOperationNode(int position)
+ private (IntrusiveList<Operation>, Operation) GetOperationNode(int position)
{
return _operationNodes[position / InstructionGap];
}
private void NumberLocals(ControlFlowGraph cfg)
{
- _operationNodes = new List<(IntrusiveList<Node>, Node)>();
+ _operationNodes = new List<(IntrusiveList<Operation>, Operation)>();
_intervals = new List<LiveInterval>();
@@ -783,13 +776,14 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
{
BasicBlock block = cfg.PostOrderBlocks[index];
- for (Node node = block.Operations.First; node != null; node = node.ListNext)
+ for (Operation node = block.Operations.First; node != default; node = node.ListNext)
{
_operationNodes.Add((block.Operations, node));
for (int i = 0; i < node.DestinationsCount; i++)
{
Operand dest = node.GetDestination(i);
+
if (dest.Kind == OperandKind.LocalVariable && visited.Add(dest))
{
dest.NumberLocal(_intervals.Count);
@@ -804,7 +798,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
if (block.Operations.Count == 0)
{
// Pretend we have a dummy instruction on the empty block.
- _operationNodes.Add((null, null));
+ _operationNodes.Add((default, default));
_operationsCount += InstructionGap;
}
@@ -825,10 +819,10 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
// Compute local live sets.
for (BasicBlock block = cfg.Blocks.First; block != null; block = block.ListNext)
{
- BitMap liveGen = BitMapPool.Allocate(mapSize);
- BitMap liveKill = BitMapPool.Allocate(mapSize);
+ BitMap liveGen = new BitMap(Allocators.Default, mapSize);
+ BitMap liveKill = new BitMap(Allocators.Default, mapSize);
- for (Node node = block.Operations.First; node != null; node = node.ListNext)
+ for (Operation node = block.Operations.First; node != default; node = node.ListNext)
{
Sources(node, (source) =>
{
@@ -857,8 +851,8 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
for (int index = 0; index < cfg.Blocks.Count; index++)
{
- blkLiveIn [index] = BitMapPool.Allocate(mapSize);
- blkLiveOut[index] = BitMapPool.Allocate(mapSize);
+ blkLiveIn [index] = new BitMap(Allocators.Default, mapSize);
+ blkLiveOut[index] = new BitMap(Allocators.Default, mapSize);
}
bool modified;
@@ -873,7 +867,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
BitMap liveOut = blkLiveOut[block.Index];
- for (int i = 0; i < block.SuccessorCount; i++)
+ for (int i = 0; i < block.SuccessorsCount; i++)
{
BasicBlock succ = block.GetSuccessor(i);
@@ -926,7 +920,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
continue;
}
- foreach (Node node in BottomOperations(block))
+ foreach (Operation node in BottomOperations(block))
{
operationPos -= InstructionGap;
@@ -947,7 +941,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
interval.AddUsePosition(operationPos);
});
- if (node is Operation operation && operation.Instruction == Instruction.Call)
+ if (node.Instruction == Instruction.Call)
{
AddIntervalCallerSavedReg(context.Masks.IntCallerSavedRegisters, operationPos, RegisterType.Integer);
AddIntervalCallerSavedReg(context.Masks.VecCallerSavedRegisters, operationPos, RegisterType.Vector);
@@ -993,11 +987,11 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
return (register.Index << 1) | (register.Type == RegisterType.Vector ? 1 : 0);
}
- private static IEnumerable<Node> BottomOperations(BasicBlock block)
+ private static IEnumerable<Operation> BottomOperations(BasicBlock block)
{
- Node node = block.Operations.Last;
+ Operation node = block.Operations.Last;
- while (node != null && !(node is PhiNode))
+ while (node != default)
{
yield return node;
@@ -1005,7 +999,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
}
}
- private static void Sources(Node node, Action<Operand> action)
+ private static void Sources(Operation node, Action<Operand> action)
{
for (int index = 0; index < node.SourcesCount; index++)
{
@@ -1017,14 +1011,14 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
}
else if (source.Kind == OperandKind.Memory)
{
- MemoryOperand memOp = (MemoryOperand)source;
+ MemoryOperand memOp = source.GetMemory();
- if (memOp.BaseAddress != null)
+ if (memOp.BaseAddress != default)
{
action(memOp.BaseAddress);
}
- if (memOp.Index != null)
+ if (memOp.Index != default)
{
action(memOp.Index);
}
diff --git a/ARMeilleure/CodeGen/RegisterAllocators/LiveInterval.cs b/ARMeilleure/CodeGen/RegisterAllocators/LiveInterval.cs
index 309c5ba3..be587652 100644
--- a/ARMeilleure/CodeGen/RegisterAllocators/LiveInterval.cs
+++ b/ARMeilleure/CodeGen/RegisterAllocators/LiveInterval.cs
@@ -34,7 +34,7 @@ namespace ARMeilleure.CodeGen.RegisterAllocators
public bool IsEmpty => _ranges.Count == 0;
- public LiveInterval(Operand local = null, LiveInterval parent = null)
+ public LiveInterval(Operand local = default, LiveInterval parent = null)
{
Local = local;
_parent = parent ?? this;