Node.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. using System;
  2. using System.Collections.Generic;
  3. namespace ARMeilleure.IntermediateRepresentation
  4. {
  5. class Node : IIntrusiveListNode<Node>
  6. {
  7. public Node ListPrevious { get; set; }
  8. public Node ListNext { get; set; }
  9. public Operand Destination
  10. {
  11. get
  12. {
  13. return _destinations.Count != 0 ? GetDestination(0) : null;
  14. }
  15. set
  16. {
  17. if (value != null)
  18. {
  19. SetDestination(value);
  20. }
  21. else
  22. {
  23. _destinations.Clear();
  24. }
  25. }
  26. }
  27. private List<Operand> _destinations;
  28. private List<Operand> _sources;
  29. private bool _clearedDest;
  30. public int DestinationsCount => _destinations.Count;
  31. public int SourcesCount => _sources.Count;
  32. private void Resize(List<Operand> list, int size)
  33. {
  34. if (list.Count > size)
  35. {
  36. list.RemoveRange(size, list.Count - size);
  37. }
  38. else
  39. {
  40. while (list.Count < size)
  41. {
  42. list.Add(null);
  43. }
  44. }
  45. }
  46. public Node()
  47. {
  48. _destinations = new List<Operand>();
  49. _sources = new List<Operand>();
  50. }
  51. public Node(Operand destination, int sourcesCount) : this()
  52. {
  53. Destination = destination;
  54. Resize(_sources, sourcesCount);
  55. }
  56. private void Reset(int sourcesCount)
  57. {
  58. _clearedDest = true;
  59. _sources.Clear();
  60. ListPrevious = null;
  61. ListNext = null;
  62. Resize(_sources, sourcesCount);
  63. }
  64. public Node With(Operand destination, int sourcesCount)
  65. {
  66. Reset(sourcesCount);
  67. Destination = destination;
  68. return this;
  69. }
  70. public Node With(Operand[] destinations, int sourcesCount)
  71. {
  72. Reset(sourcesCount);
  73. SetDestinations(destinations ?? throw new ArgumentNullException(nameof(destinations)));
  74. return this;
  75. }
  76. public Operand GetDestination(int index)
  77. {
  78. return _destinations[index];
  79. }
  80. public Operand GetSource(int index)
  81. {
  82. return _sources[index];
  83. }
  84. public void SetDestination(int index, Operand destination)
  85. {
  86. if (!_clearedDest)
  87. {
  88. RemoveAssignment(_destinations[index]);
  89. }
  90. AddAssignment(destination);
  91. _clearedDest = false;
  92. _destinations[index] = destination;
  93. }
  94. public void SetSource(int index, Operand source)
  95. {
  96. RemoveUse(_sources[index]);
  97. AddUse(source);
  98. _sources[index] = source;
  99. }
  100. private void RemoveOldDestinations()
  101. {
  102. if (_destinations != null && !_clearedDest)
  103. {
  104. for (int index = 0; index < _destinations.Count; index++)
  105. {
  106. RemoveAssignment(_destinations[index]);
  107. }
  108. }
  109. _clearedDest = false;
  110. }
  111. public void SetDestination(Operand destination)
  112. {
  113. RemoveOldDestinations();
  114. Resize(_destinations, 1);
  115. _destinations[0] = destination;
  116. if (destination.Kind == OperandKind.LocalVariable)
  117. {
  118. destination.Assignments.Add(this);
  119. }
  120. }
  121. public void SetDestinations(Operand[] destinations)
  122. {
  123. RemoveOldDestinations();
  124. Resize(_destinations, destinations.Length);
  125. for (int index = 0; index < destinations.Length; index++)
  126. {
  127. Operand newOp = destinations[index];
  128. _destinations[index] = newOp;
  129. AddAssignment(newOp);
  130. }
  131. }
  132. private void RemoveOldSources()
  133. {
  134. for (int index = 0; index < _sources.Count; index++)
  135. {
  136. RemoveUse(_sources[index]);
  137. }
  138. }
  139. public void SetSource(Operand source)
  140. {
  141. RemoveOldSources();
  142. Resize(_sources, 1);
  143. _sources[0] = source;
  144. if (source.Kind == OperandKind.LocalVariable)
  145. {
  146. source.Uses.Add(this);
  147. }
  148. }
  149. public void SetSources(Operand[] sources)
  150. {
  151. RemoveOldSources();
  152. Resize(_sources, sources.Length);
  153. for (int index = 0; index < sources.Length; index++)
  154. {
  155. Operand newOp = sources[index];
  156. _sources[index] = newOp;
  157. AddUse(newOp);
  158. }
  159. }
  160. private void AddAssignment(Operand op)
  161. {
  162. if (op == null)
  163. {
  164. return;
  165. }
  166. if (op.Kind == OperandKind.LocalVariable)
  167. {
  168. op.Assignments.Add(this);
  169. }
  170. else if (op.Kind == OperandKind.Memory)
  171. {
  172. MemoryOperand memOp = (MemoryOperand)op;
  173. if (memOp.BaseAddress != null)
  174. {
  175. memOp.BaseAddress.Assignments.Add(this);
  176. }
  177. if (memOp.Index != null)
  178. {
  179. memOp.Index.Assignments.Add(this);
  180. }
  181. }
  182. }
  183. private void RemoveAssignment(Operand op)
  184. {
  185. if (op == null)
  186. {
  187. return;
  188. }
  189. if (op.Kind == OperandKind.LocalVariable)
  190. {
  191. op.Assignments.Remove(this);
  192. }
  193. else if (op.Kind == OperandKind.Memory)
  194. {
  195. MemoryOperand memOp = (MemoryOperand)op;
  196. if (memOp.BaseAddress != null)
  197. {
  198. memOp.BaseAddress.Assignments.Remove(this);
  199. }
  200. if (memOp.Index != null)
  201. {
  202. memOp.Index.Assignments.Remove(this);
  203. }
  204. }
  205. }
  206. private void AddUse(Operand op)
  207. {
  208. if (op == null)
  209. {
  210. return;
  211. }
  212. if (op.Kind == OperandKind.LocalVariable)
  213. {
  214. op.Uses.Add(this);
  215. }
  216. else if (op.Kind == OperandKind.Memory)
  217. {
  218. MemoryOperand memOp = (MemoryOperand)op;
  219. if (memOp.BaseAddress != null)
  220. {
  221. memOp.BaseAddress.Uses.Add(this);
  222. }
  223. if (memOp.Index != null)
  224. {
  225. memOp.Index.Uses.Add(this);
  226. }
  227. }
  228. }
  229. private void RemoveUse(Operand op)
  230. {
  231. if (op == null)
  232. {
  233. return;
  234. }
  235. if (op.Kind == OperandKind.LocalVariable)
  236. {
  237. op.Uses.Remove(this);
  238. }
  239. else if (op.Kind == OperandKind.Memory)
  240. {
  241. MemoryOperand memOp = (MemoryOperand)op;
  242. if (memOp.BaseAddress != null)
  243. {
  244. memOp.BaseAddress.Uses.Remove(this);
  245. }
  246. if (memOp.Index != null)
  247. {
  248. memOp.Index.Uses.Remove(this);
  249. }
  250. }
  251. }
  252. }
  253. }