BasicBlock.cs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. using System.Collections.Generic;
  2. namespace Ryujinx.Graphics.Shader.IntermediateRepresentation
  3. {
  4. class BasicBlock
  5. {
  6. public int Index { get; set; }
  7. public LinkedList<INode> Operations { get; }
  8. private BasicBlock _next;
  9. private BasicBlock _branch;
  10. public BasicBlock Next
  11. {
  12. get => _next;
  13. set => _next = AddSuccessor(_next, value);
  14. }
  15. public BasicBlock Branch
  16. {
  17. get => _branch;
  18. set => _branch = AddSuccessor(_branch, value);
  19. }
  20. public bool HasBranch => _branch != null;
  21. public bool Reachable => Index == 0 || Predecessors.Count != 0;
  22. public List<BasicBlock> Predecessors { get; }
  23. public HashSet<BasicBlock> DominanceFrontiers { get; }
  24. public BasicBlock ImmediateDominator { get; set; }
  25. public BasicBlock()
  26. {
  27. Operations = new LinkedList<INode>();
  28. Predecessors = new List<BasicBlock>();
  29. DominanceFrontiers = new HashSet<BasicBlock>();
  30. }
  31. public BasicBlock(int index) : this()
  32. {
  33. Index = index;
  34. }
  35. private BasicBlock AddSuccessor(BasicBlock oldBlock, BasicBlock newBlock)
  36. {
  37. oldBlock?.Predecessors.Remove(this);
  38. newBlock?.Predecessors.Add(this);
  39. return newBlock;
  40. }
  41. public INode GetLastOp()
  42. {
  43. return Operations.Last?.Value;
  44. }
  45. public void Append(INode node)
  46. {
  47. INode lastOp = GetLastOp();
  48. if (lastOp is Operation operation && IsControlFlowInst(operation.Inst))
  49. {
  50. Operations.AddBefore(Operations.Last, node);
  51. }
  52. else
  53. {
  54. Operations.AddLast(node);
  55. }
  56. }
  57. private static bool IsControlFlowInst(Instruction inst)
  58. {
  59. switch (inst)
  60. {
  61. case Instruction.Branch:
  62. case Instruction.BranchIfFalse:
  63. case Instruction.BranchIfTrue:
  64. case Instruction.Discard:
  65. case Instruction.Return:
  66. return true;
  67. }
  68. return false;
  69. }
  70. }
  71. }