BasicBlock.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. using System;
  2. using System.Collections.Generic;
  3. namespace ARMeilleure.IntermediateRepresentation
  4. {
  5. class BasicBlock : IIntrusiveListNode<BasicBlock>
  6. {
  7. private readonly List<BasicBlock> _successors = new List<BasicBlock>();
  8. public int Index { get; set; }
  9. public BasicBlock ListPrevious { get; set; }
  10. public BasicBlock ListNext { get; set; }
  11. public IntrusiveList<Node> Operations { get; }
  12. public List<BasicBlock> Predecessors { get; }
  13. public HashSet<BasicBlock> DominanceFrontiers { get; }
  14. public BasicBlock ImmediateDominator { get; set; }
  15. public int SuccessorCount => _successors.Count;
  16. public BasicBlock() : this(index: -1) { }
  17. public BasicBlock(int index)
  18. {
  19. Operations = new IntrusiveList<Node>();
  20. Predecessors = new List<BasicBlock>();
  21. DominanceFrontiers = new HashSet<BasicBlock>();
  22. Index = index;
  23. }
  24. public void AddSuccessor(BasicBlock block)
  25. {
  26. if (block == null)
  27. {
  28. throw new ArgumentNullException(nameof(block));
  29. }
  30. block.Predecessors.Add(this);
  31. _successors.Add(block);
  32. }
  33. public void RemoveSuccessor(int index)
  34. {
  35. BasicBlock oldBlock = _successors[index];
  36. oldBlock.Predecessors.Remove(this);
  37. _successors.RemoveAt(index);
  38. }
  39. public BasicBlock GetSuccessor(int index)
  40. {
  41. return _successors[index];
  42. }
  43. public void SetSuccessor(int index, BasicBlock block)
  44. {
  45. if (block == null)
  46. {
  47. throw new ArgumentNullException(nameof(block));
  48. }
  49. BasicBlock oldBlock = _successors[index];
  50. oldBlock.Predecessors.Remove(this);
  51. block.Predecessors.Add(this);
  52. _successors[index] = block;
  53. }
  54. public void Append(Node node)
  55. {
  56. var lastOp = Operations.Last as Operation;
  57. // Append node before terminal or to end if no terminal.
  58. switch (lastOp?.Instruction)
  59. {
  60. case Instruction.Return:
  61. case Instruction.Tailcall:
  62. case Instruction.BranchIf:
  63. Operations.AddBefore(lastOp, node);
  64. break;
  65. default:
  66. Operations.AddLast(node);
  67. break;
  68. }
  69. }
  70. public Node GetLastOp()
  71. {
  72. return Operations.Last;
  73. }
  74. }
  75. }