Dominance.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  2. using System.Collections.Generic;
  3. namespace Ryujinx.Graphics.Shader.Translation
  4. {
  5. static class Dominance
  6. {
  7. // Those methods are an implementation of the algorithms on "A Simple, Fast Dominance Algorithm".
  8. // https://www.cs.rice.edu/~keith/EMBED/dom.pdf
  9. public static void FindDominators(BasicBlock entry, int blocksCount)
  10. {
  11. HashSet<BasicBlock> visited = new HashSet<BasicBlock>();
  12. Stack<BasicBlock> blockStack = new Stack<BasicBlock>();
  13. List<BasicBlock> postOrderBlocks = new List<BasicBlock>(blocksCount);
  14. int[] postOrderMap = new int[blocksCount];
  15. visited.Add(entry);
  16. blockStack.Push(entry);
  17. while (blockStack.TryPop(out BasicBlock block))
  18. {
  19. if (block.Next != null && visited.Add(block.Next))
  20. {
  21. blockStack.Push(block);
  22. blockStack.Push(block.Next);
  23. }
  24. else if (block.Branch != null && visited.Add(block.Branch))
  25. {
  26. blockStack.Push(block);
  27. blockStack.Push(block.Branch);
  28. }
  29. else
  30. {
  31. postOrderMap[block.Index] = postOrderBlocks.Count;
  32. postOrderBlocks.Add(block);
  33. }
  34. }
  35. BasicBlock Intersect(BasicBlock block1, BasicBlock block2)
  36. {
  37. while (block1 != block2)
  38. {
  39. while (postOrderMap[block1.Index] < postOrderMap[block2.Index])
  40. {
  41. block1 = block1.ImmediateDominator;
  42. }
  43. while (postOrderMap[block2.Index] < postOrderMap[block1.Index])
  44. {
  45. block2 = block2.ImmediateDominator;
  46. }
  47. }
  48. return block1;
  49. }
  50. entry.ImmediateDominator = entry;
  51. bool modified;
  52. do
  53. {
  54. modified = false;
  55. for (int blkIndex = postOrderBlocks.Count - 2; blkIndex >= 0; blkIndex--)
  56. {
  57. BasicBlock block = postOrderBlocks[blkIndex];
  58. BasicBlock newIDom = null;
  59. foreach (BasicBlock predecessor in block.Predecessors)
  60. {
  61. if (predecessor.ImmediateDominator != null)
  62. {
  63. if (newIDom != null)
  64. {
  65. newIDom = Intersect(predecessor, newIDom);
  66. }
  67. else
  68. {
  69. newIDom = predecessor;
  70. }
  71. }
  72. }
  73. if (block.ImmediateDominator != newIDom)
  74. {
  75. block.ImmediateDominator = newIDom;
  76. modified = true;
  77. }
  78. }
  79. }
  80. while (modified);
  81. }
  82. public static void FindDominanceFrontiers(BasicBlock[] blocks)
  83. {
  84. for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++)
  85. {
  86. BasicBlock block = blocks[blkIndex];
  87. if (block.Predecessors.Count < 2)
  88. {
  89. continue;
  90. }
  91. for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++)
  92. {
  93. BasicBlock current = block.Predecessors[pBlkIndex];
  94. while (current != block.ImmediateDominator)
  95. {
  96. current.DominanceFrontiers.Add(block);
  97. current = current.ImmediateDominator;
  98. }
  99. }
  100. }
  101. }
  102. }
  103. }