Dominance.cs 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  2. namespace Ryujinx.Graphics.Shader.Translation
  3. {
  4. static class Dominance
  5. {
  6. // Those methods are an implementation of the algorithms on "A Simple, Fast Dominance Algorithm".
  7. // https://www.cs.rice.edu/~keith/EMBED/dom.pdf
  8. public static void FindDominators(ControlFlowGraph cfg)
  9. {
  10. BasicBlock Intersect(BasicBlock block1, BasicBlock block2)
  11. {
  12. while (block1 != block2)
  13. {
  14. while (cfg.PostOrderMap[block1.Index] < cfg.PostOrderMap[block2.Index])
  15. {
  16. block1 = block1.ImmediateDominator;
  17. }
  18. while (cfg.PostOrderMap[block2.Index] < cfg.PostOrderMap[block1.Index])
  19. {
  20. block2 = block2.ImmediateDominator;
  21. }
  22. }
  23. return block1;
  24. }
  25. cfg.Blocks[0].ImmediateDominator = cfg.Blocks[0];
  26. bool modified;
  27. do
  28. {
  29. modified = false;
  30. for (int blkIndex = cfg.PostOrderBlocks.Length - 2; blkIndex >= 0; blkIndex--)
  31. {
  32. BasicBlock block = cfg.PostOrderBlocks[blkIndex];
  33. BasicBlock newIDom = null;
  34. foreach (BasicBlock predecessor in block.Predecessors)
  35. {
  36. if (predecessor.ImmediateDominator != null)
  37. {
  38. if (newIDom != null)
  39. {
  40. newIDom = Intersect(predecessor, newIDom);
  41. }
  42. else
  43. {
  44. newIDom = predecessor;
  45. }
  46. }
  47. }
  48. if (block.ImmediateDominator != newIDom)
  49. {
  50. block.ImmediateDominator = newIDom;
  51. modified = true;
  52. }
  53. }
  54. }
  55. while (modified);
  56. }
  57. public static void FindDominanceFrontiers(BasicBlock[] blocks)
  58. {
  59. for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++)
  60. {
  61. BasicBlock block = blocks[blkIndex];
  62. if (block.Predecessors.Count < 2)
  63. {
  64. continue;
  65. }
  66. for (int pBlkIndex = 0; pBlkIndex < block.Predecessors.Count; pBlkIndex++)
  67. {
  68. BasicBlock current = block.Predecessors[pBlkIndex];
  69. while (current != block.ImmediateDominator)
  70. {
  71. current.DominanceFrontiers.Add(block);
  72. current = current.ImmediateDominator;
  73. }
  74. }
  75. }
  76. }
  77. }
  78. }