diff options
Diffstat (limited to 'ARMeilleure/IntermediateRepresentation/Node.cs')
-rw-r--r-- | ARMeilleure/IntermediateRepresentation/Node.cs | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/ARMeilleure/IntermediateRepresentation/Node.cs b/ARMeilleure/IntermediateRepresentation/Node.cs new file mode 100644 index 00000000..167acd07 --- /dev/null +++ b/ARMeilleure/IntermediateRepresentation/Node.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; + +namespace ARMeilleure.IntermediateRepresentation +{ + class Node + { + public Operand Destination + { + get + { + return _destinations.Length != 0 ? GetDestination(0) : null; + } + set + { + if (value != null) + { + SetDestinations(new Operand[] { value }); + } + else + { + SetDestinations(new Operand[0]); + } + } + } + + private Operand[] _destinations; + private Operand[] _sources; + + private LinkedListNode<Node>[] _asgUseNodes; + private LinkedListNode<Node>[] _srcUseNodes; + + public int DestinationsCount => _destinations.Length; + public int SourcesCount => _sources.Length; + + public Node(Operand destination, int sourcesCount) + { + Destination = destination; + + _sources = new Operand[sourcesCount]; + + _srcUseNodes = new LinkedListNode<Node>[sourcesCount]; + } + + public Node(Operand[] destinations, int sourcesCount) + { + SetDestinations(destinations ?? throw new ArgumentNullException(nameof(destinations))); + + _sources = new Operand[sourcesCount]; + + _srcUseNodes = new LinkedListNode<Node>[sourcesCount]; + } + + public Operand GetDestination(int index) + { + return _destinations[index]; + } + + public Operand GetSource(int index) + { + return _sources[index]; + } + + public void SetDestination(int index, Operand destination) + { + Operand oldOp = _destinations[index]; + + if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable) + { + oldOp.Assignments.Remove(_asgUseNodes[index]); + } + + if (destination != null && destination.Kind == OperandKind.LocalVariable) + { + _asgUseNodes[index] = destination.Assignments.AddLast(this); + } + + _destinations[index] = destination; + } + + public void SetSource(int index, Operand source) + { + Operand oldOp = _sources[index]; + + if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable) + { + oldOp.Uses.Remove(_srcUseNodes[index]); + } + + if (source != null && source.Kind == OperandKind.LocalVariable) + { + _srcUseNodes[index] = source.Uses.AddLast(this); + } + + _sources[index] = source; + } + + public void SetDestinations(Operand[] destinations) + { + if (_destinations != null) + { + for (int index = 0; index < _destinations.Length; index++) + { + Operand oldOp = _destinations[index]; + + if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable) + { + oldOp.Assignments.Remove(_asgUseNodes[index]); + } + } + + _destinations = destinations; + } + else + { + _destinations = new Operand[destinations.Length]; + } + + _asgUseNodes = new LinkedListNode<Node>[destinations.Length]; + + for (int index = 0; index < destinations.Length; index++) + { + Operand newOp = destinations[index]; + + _destinations[index] = newOp; + + if (newOp.Kind == OperandKind.LocalVariable) + { + _asgUseNodes[index] = newOp.Assignments.AddLast(this); + } + } + } + + public void SetSources(Operand[] sources) + { + for (int index = 0; index < _sources.Length; index++) + { + Operand oldOp = _sources[index]; + + if (oldOp != null && oldOp.Kind == OperandKind.LocalVariable) + { + oldOp.Uses.Remove(_srcUseNodes[index]); + } + } + + _sources = new Operand[sources.Length]; + + _srcUseNodes = new LinkedListNode<Node>[sources.Length]; + + for (int index = 0; index < sources.Length; index++) + { + Operand newOp = sources[index]; + + _sources[index] = newOp; + + if (newOp.Kind == OperandKind.LocalVariable) + { + _srcUseNodes[index] = newOp.Uses.AddLast(this); + } + } + } + } +}
\ No newline at end of file |