aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/IntermediateRepresentation/Node.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/IntermediateRepresentation/Node.cs')
-rw-r--r--ARMeilleure/IntermediateRepresentation/Node.cs126
1 files changed, 104 insertions, 22 deletions
diff --git a/ARMeilleure/IntermediateRepresentation/Node.cs b/ARMeilleure/IntermediateRepresentation/Node.cs
index 37647c56..9ce78c09 100644
--- a/ARMeilleure/IntermediateRepresentation/Node.cs
+++ b/ARMeilleure/IntermediateRepresentation/Node.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
namespace ARMeilleure.IntermediateRepresentation
{
@@ -11,39 +12,80 @@ namespace ARMeilleure.IntermediateRepresentation
{
get
{
- return _destinations.Length != 0 ? GetDestination(0) : null;
+ return _destinations.Count != 0 ? GetDestination(0) : null;
}
set
{
if (value != null)
{
- SetDestinations(new Operand[] { value });
+ SetDestination(value);
}
else
{
- SetDestinations(new Operand[0]);
+ _destinations.Clear();
}
}
}
- private Operand[] _destinations;
- private Operand[] _sources;
+ private List<Operand> _destinations;
+ private List<Operand> _sources;
+ private bool _clearedDest;
- public int DestinationsCount => _destinations.Length;
- public int SourcesCount => _sources.Length;
+ public int DestinationsCount => _destinations.Count;
+ public int SourcesCount => _sources.Count;
- public Node(Operand destination, int sourcesCount)
+ private void Resize(List<Operand> list, int size)
{
+ if (list.Count > size)
+ {
+ list.RemoveRange(size, list.Count - size);
+ }
+ else
+ {
+ while (list.Count < size)
+ {
+ list.Add(null);
+ }
+ }
+ }
+
+ public Node()
+ {
+ _destinations = new List<Operand>();
+ _sources = new List<Operand>();
+ }
+
+ public Node(Operand destination, int sourcesCount) : this()
+ {
+ Destination = destination;
+
+ Resize(_sources, sourcesCount);
+ }
+
+ private void Reset(int sourcesCount)
+ {
+ _clearedDest = true;
+ _sources.Clear();
+ ListPrevious = null;
+ ListNext = null;
+
+ Resize(_sources, sourcesCount);
+ }
+
+ public Node With(Operand destination, int sourcesCount)
+ {
+ Reset(sourcesCount);
Destination = destination;
- _sources = new Operand[sourcesCount];
+ return this;
}
- public Node(Operand[] destinations, int sourcesCount)
+ public Node With(Operand[] destinations, int sourcesCount)
{
+ Reset(sourcesCount);
SetDestinations(destinations ?? throw new ArgumentNullException(nameof(destinations)));
- _sources = new Operand[sourcesCount];
+ return this;
}
public Operand GetDestination(int index)
@@ -58,10 +100,15 @@ namespace ARMeilleure.IntermediateRepresentation
public void SetDestination(int index, Operand destination)
{
- RemoveAssignment(_destinations[index]);
+ if (!_clearedDest)
+ {
+ RemoveAssignment(_destinations[index]);
+ }
AddAssignment(destination);
+ _clearedDest = false;
+
_destinations[index] = destination;
}
@@ -74,21 +121,37 @@ namespace ARMeilleure.IntermediateRepresentation
_sources[index] = source;
}
- public void SetDestinations(Operand[] destinations)
+ private void RemoveOldDestinations()
{
- if (_destinations != null)
+ if (_destinations != null && !_clearedDest)
{
- for (int index = 0; index < _destinations.Length; index++)
+ for (int index = 0; index < _destinations.Count; index++)
{
RemoveAssignment(_destinations[index]);
}
-
- _destinations = destinations;
}
- else
+ _clearedDest = false;
+ }
+
+ public void SetDestination(Operand destination)
+ {
+ RemoveOldDestinations();
+
+ Resize(_destinations, 1);
+
+ _destinations[0] = destination;
+
+ if (destination.Kind == OperandKind.LocalVariable)
{
- _destinations = new Operand[destinations.Length];
+ destination.Assignments.Add(this);
}
+ }
+
+ public void SetDestinations(Operand[] destinations)
+ {
+ RemoveOldDestinations();
+
+ Resize(_destinations, destinations.Length);
for (int index = 0; index < destinations.Length; index++)
{
@@ -100,14 +163,33 @@ namespace ARMeilleure.IntermediateRepresentation
}
}
- public void SetSources(Operand[] sources)
+ private void RemoveOldSources()
{
- for (int index = 0; index < _sources.Length; index++)
+ for (int index = 0; index < _sources.Count; index++)
{
RemoveUse(_sources[index]);
}
+ }
+
+ public void SetSource(Operand source)
+ {
+ RemoveOldSources();
+
+ Resize(_sources, 1);
+
+ _sources[0] = source;
+
+ if (source.Kind == OperandKind.LocalVariable)
+ {
+ source.Uses.Add(this);
+ }
+ }
+
+ public void SetSources(Operand[] sources)
+ {
+ RemoveOldSources();
- _sources = new Operand[sources.Length];
+ Resize(_sources, sources.Length);
for (int index = 0; index < sources.Length; index++)
{