aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/IntermediateRepresentation
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/IntermediateRepresentation')
-rw-r--r--ARMeilleure/IntermediateRepresentation/MemoryOperand.cs12
-rw-r--r--ARMeilleure/IntermediateRepresentation/Node.cs126
-rw-r--r--ARMeilleure/IntermediateRepresentation/Operand.cs46
-rw-r--r--ARMeilleure/IntermediateRepresentation/OperandHelper.cs59
-rw-r--r--ARMeilleure/IntermediateRepresentation/Operation.cs64
-rw-r--r--ARMeilleure/IntermediateRepresentation/OperationHelper.cs59
6 files changed, 303 insertions, 63 deletions
diff --git a/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs b/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs
index 742842fa..56d07288 100644
--- a/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs
+++ b/ARMeilleure/IntermediateRepresentation/MemoryOperand.cs
@@ -5,21 +5,25 @@ namespace ARMeilleure.IntermediateRepresentation
public Operand BaseAddress { get; set; }
public Operand Index { get; set; }
- public Multiplier Scale { get; }
+ public Multiplier Scale { get; private set; }
- public int Displacement { get; }
+ public int Displacement { get; private set; }
- public MemoryOperand(
+ public MemoryOperand() { }
+
+ public MemoryOperand With(
OperandType type,
Operand baseAddress,
Operand index = null,
Multiplier scale = Multiplier.x1,
- int displacement = 0) : base(OperandKind.Memory, type)
+ int displacement = 0)
{
+ With(OperandKind.Memory, type);
BaseAddress = baseAddress;
Index = index;
Scale = scale;
Displacement = displacement;
+ return this;
}
}
} \ No newline at end of file
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++)
{
diff --git a/ARMeilleure/IntermediateRepresentation/Operand.cs b/ARMeilleure/IntermediateRepresentation/Operand.cs
index fe5bf073..2d5e762a 100644
--- a/ARMeilleure/IntermediateRepresentation/Operand.cs
+++ b/ARMeilleure/IntermediateRepresentation/Operand.cs
@@ -5,16 +5,16 @@ namespace ARMeilleure.IntermediateRepresentation
{
class Operand
{
- public OperandKind Kind { get; }
+ public OperandKind Kind { get; private set; }
- public OperandType Type { get; }
+ public OperandType Type { get; private set; }
public ulong Value { get; private set; }
public List<Node> Assignments { get; }
public List<Node> Uses { get; }
- private Operand()
+ public Operand()
{
Assignments = new List<Node>();
Uses = new List<Node>();
@@ -26,42 +26,50 @@ namespace ARMeilleure.IntermediateRepresentation
Type = type;
}
- public Operand(int value) : this(OperandKind.Constant, OperandType.I32)
+ public Operand With(OperandKind kind, OperandType type = OperandType.None, ulong value = 0)
{
- Value = (uint)value;
+ Kind = kind;
+ Type = type;
+ Value = value;
+
+ Assignments.Clear();
+ Uses.Clear();
+ return this;
}
- public Operand(uint value) : this(OperandKind.Constant, OperandType.I32)
+ public Operand With(int value)
{
- Value = (uint)value;
+ return With(OperandKind.Constant, OperandType.I32, (uint)value);
}
- public Operand(long value) : this(OperandKind.Constant, OperandType.I64)
+ public Operand With(uint value)
{
- Value = (ulong)value;
+ return With(OperandKind.Constant, OperandType.I32, value);
}
- public Operand(ulong value) : this(OperandKind.Constant, OperandType.I64)
+ public Operand With(long value)
{
- Value = value;
+ return With(OperandKind.Constant, OperandType.I64, (ulong)value);
}
- public Operand(float value) : this(OperandKind.Constant, OperandType.FP32)
+ public Operand With(ulong value)
{
- Value = (ulong)BitConverter.SingleToInt32Bits(value);
+ return With(OperandKind.Constant, OperandType.I64, value);
}
- public Operand(double value) : this(OperandKind.Constant, OperandType.FP64)
+ public Operand With(float value)
{
- Value = (ulong)BitConverter.DoubleToInt64Bits(value);
+ return With(OperandKind.Constant, OperandType.FP32, (ulong)BitConverter.SingleToInt32Bits(value));
}
- public Operand(int index, RegisterType regType, OperandType type) : this()
+ public Operand With(double value)
{
- Kind = OperandKind.Register;
- Type = type;
+ return With(OperandKind.Constant, OperandType.FP64, (ulong)BitConverter.DoubleToInt64Bits(value));
+ }
- Value = (ulong)((int)regType << 24 | index);
+ public Operand With(int index, RegisterType regType, OperandType type)
+ {
+ return With(OperandKind.Register, type, (ulong)((int)regType << 24 | index));
}
public Register GetRegister()
diff --git a/ARMeilleure/IntermediateRepresentation/OperandHelper.cs b/ARMeilleure/IntermediateRepresentation/OperandHelper.cs
index 4a930e03..cfdb32d9 100644
--- a/ARMeilleure/IntermediateRepresentation/OperandHelper.cs
+++ b/ARMeilleure/IntermediateRepresentation/OperandHelper.cs
@@ -1,68 +1,99 @@
-using ARMeilleure.State;
-using System;
+using ARMeilleure.Common;
namespace ARMeilleure.IntermediateRepresentation
{
static class OperandHelper
{
+ private static MemoryOperand MemoryOperand()
+ {
+ return ThreadStaticPool<MemoryOperand>.Instance.Allocate();
+ }
+
+ private static Operand Operand()
+ {
+ return ThreadStaticPool<Operand>.Instance.Allocate();
+ }
+
public static Operand Const(OperandType type, long value)
{
- return type == OperandType.I32 ? new Operand((int)value) : new Operand(value);
+ return type == OperandType.I32 ? Operand().With((int)value) : Operand().With(value);
}
public static Operand Const(bool value)
{
- return new Operand(value ? 1 : 0);
+ return Operand().With(value ? 1 : 0);
}
public static Operand Const(int value)
{
- return new Operand(value);
+ return Operand().With(value);
}
public static Operand Const(uint value)
{
- return new Operand(value);
+ return Operand().With(value);
}
public static Operand Const(long value)
{
- return new Operand(value);
+ return Operand().With(value);
}
public static Operand Const(ulong value)
{
- return new Operand(value);
+ return Operand().With(value);
}
public static Operand ConstF(float value)
{
- return new Operand(value);
+ return Operand().With(value);
}
public static Operand ConstF(double value)
{
- return new Operand(value);
+ return Operand().With(value);
}
public static Operand Label()
{
- return new Operand(OperandKind.Label);
+ return Operand().With(OperandKind.Label);
}
public static Operand Local(OperandType type)
{
- return new Operand(OperandKind.LocalVariable, type);
+ return Operand().With(OperandKind.LocalVariable, type);
}
public static Operand Register(int index, RegisterType regType, OperandType type)
{
- return new Operand(index, regType, type);
+ return Operand().With(index, regType, type);
}
public static Operand Undef()
{
- return new Operand(OperandKind.Undefined);
+ return Operand().With(OperandKind.Undefined);
+ }
+
+ public static MemoryOperand MemoryOp(
+ OperandType type,
+ Operand baseAddress,
+ Operand index = null,
+ Multiplier scale = Multiplier.x1,
+ int displacement = 0)
+ {
+ return MemoryOperand().With(type, baseAddress, index, scale, displacement);
+ }
+
+ public static void PrepareOperandPool(bool highCq)
+ {
+ ThreadStaticPool<Operand>.PreparePool(highCq ? 1 : 0);
+ ThreadStaticPool<MemoryOperand>.PreparePool(highCq ? 1 : 0);
+ }
+
+ public static void ResetOperandPool(bool highCq)
+ {
+ ThreadStaticPool<Operand>.ReturnPool(highCq ? 1 : 0);
+ ThreadStaticPool<MemoryOperand>.ReturnPool(highCq ? 1 : 0);
}
}
} \ No newline at end of file
diff --git a/ARMeilleure/IntermediateRepresentation/Operation.cs b/ARMeilleure/IntermediateRepresentation/Operation.cs
index 620bf3f6..4cdbe326 100644
--- a/ARMeilleure/IntermediateRepresentation/Operation.cs
+++ b/ARMeilleure/IntermediateRepresentation/Operation.cs
@@ -4,10 +4,12 @@ namespace ARMeilleure.IntermediateRepresentation
{
public Instruction Instruction { get; private set; }
+ public Operation() : base() { }
+
public Operation(
Instruction instruction,
Operand destination,
- params Operand[] sources) : base(destination, sources.Length)
+ Operand[] sources) : base(destination, sources.Length)
{
Instruction = instruction;
@@ -17,24 +19,78 @@ namespace ARMeilleure.IntermediateRepresentation
}
}
- public Operation(
+ public Operation With(Instruction instruction, Operand destination)
+ {
+ With(destination, 0);
+ Instruction = instruction;
+ return this;
+ }
+
+ public Operation With(Instruction instruction, Operand destination, Operand[] sources)
+ {
+ With(destination, sources.Length);
+ Instruction = instruction;
+
+ for (int index = 0; index < sources.Length; index++)
+ {
+ SetSource(index, sources[index]);
+ }
+ return this;
+ }
+
+ public Operation With(Instruction instruction, Operand destination,
+ Operand source0)
+ {
+ With(destination, 1);
+ Instruction = instruction;
+
+ SetSource(0, source0);
+ return this;
+ }
+
+ public Operation With(Instruction instruction, Operand destination,
+ Operand source0, Operand source1)
+ {
+ With(destination, 2);
+ Instruction = instruction;
+
+ SetSource(0, source0);
+ SetSource(1, source1);
+ return this;
+ }
+
+ public Operation With(Instruction instruction, Operand destination,
+ Operand source0, Operand source1, Operand source2)
+ {
+ With(destination, 3);
+ Instruction = instruction;
+
+ SetSource(0, source0);
+ SetSource(1, source1);
+ SetSource(2, source2);
+ return this;
+ }
+
+ public Operation With(
Instruction instruction,
Operand[] destinations,
- Operand[] sources) : base(destinations, sources.Length)
+ Operand[] sources)
{
+ With(destinations, sources.Length);
Instruction = instruction;
for (int index = 0; index < sources.Length; index++)
{
SetSource(index, sources[index]);
}
+ return this;
}
public void TurnIntoCopy(Operand source)
{
Instruction = Instruction.Copy;
- SetSources(new Operand[] { source });
+ SetSource(source);
}
}
} \ No newline at end of file
diff --git a/ARMeilleure/IntermediateRepresentation/OperationHelper.cs b/ARMeilleure/IntermediateRepresentation/OperationHelper.cs
new file mode 100644
index 00000000..20c7d4ef
--- /dev/null
+++ b/ARMeilleure/IntermediateRepresentation/OperationHelper.cs
@@ -0,0 +1,59 @@
+using ARMeilleure.Common;
+
+namespace ARMeilleure.IntermediateRepresentation
+{
+ static class OperationHelper
+ {
+ public static Operation Operation()
+ {
+ return ThreadStaticPool<Operation>.Instance.Allocate();
+ }
+
+ public static Operation Operation(Instruction instruction, Operand destination)
+ {
+ return Operation().With(instruction, destination);
+ }
+
+ public static Operation Operation(Instruction instruction, Operand destination,
+ Operand[] sources)
+ {
+ return Operation().With(instruction, destination, sources);
+ }
+
+ public static Operation Operation(Instruction instruction, Operand destination,
+ Operand source0)
+ {
+ return Operation().With(instruction, destination, source0);
+ }
+
+ public static Operation Operation(Instruction instruction, Operand destination,
+ Operand source0, Operand source1)
+ {
+ return Operation().With(instruction, destination, source0, source1);
+ }
+
+ public static Operation Operation(Instruction instruction, Operand destination,
+ Operand source0, Operand source1, Operand source2)
+ {
+ return Operation().With(instruction, destination, source0, source1, source2);
+ }
+
+ public static Operation Operation(
+ Instruction instruction,
+ Operand[] destinations,
+ Operand[] sources)
+ {
+ return Operation().With(instruction, destinations, sources);
+ }
+
+ public static void PrepareOperationPool(bool highCq)
+ {
+ ThreadStaticPool<Operation>.PreparePool(highCq ? 1 : 0);
+ }
+
+ public static void ResetOperationPool(bool highCq)
+ {
+ ThreadStaticPool<Operation>.ReturnPool(highCq ? 1 : 0);
+ }
+ }
+}