PhiFunctions.cs 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  2. using System.Collections.Generic;
  3. namespace Ryujinx.Graphics.Shader.StructuredIr
  4. {
  5. static class PhiFunctions
  6. {
  7. public static void Remove(BasicBlock[] blocks)
  8. {
  9. for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++)
  10. {
  11. BasicBlock block = blocks[blkIndex];
  12. LinkedListNode<INode> node = block.Operations.First;
  13. while (node != null)
  14. {
  15. LinkedListNode<INode> nextNode = node.Next;
  16. if (!(node.Value is PhiNode phi))
  17. {
  18. node = nextNode;
  19. continue;
  20. }
  21. for (int index = 0; index < phi.SourcesCount; index++)
  22. {
  23. Operand src = phi.GetSource(index);
  24. BasicBlock srcBlock = phi.GetBlock(index);
  25. Operation copyOp = new Operation(Instruction.Copy, phi.Dest, src);
  26. AddBeforeBranch(srcBlock, copyOp);
  27. }
  28. block.Operations.Remove(node);
  29. node = nextNode;
  30. }
  31. }
  32. }
  33. private static void AddBeforeBranch(BasicBlock block, INode node)
  34. {
  35. INode lastOp = block.GetLastOp();
  36. if (lastOp is Operation operation && IsControlFlowInst(operation.Inst))
  37. {
  38. block.Operations.AddBefore(block.Operations.Last, node);
  39. }
  40. else
  41. {
  42. block.Operations.AddLast(node);
  43. }
  44. }
  45. private static bool IsControlFlowInst(Instruction inst)
  46. {
  47. switch (inst)
  48. {
  49. case Instruction.Branch:
  50. case Instruction.BranchIfFalse:
  51. case Instruction.BranchIfTrue:
  52. case Instruction.Discard:
  53. case Instruction.Return:
  54. return true;
  55. }
  56. return false;
  57. }
  58. }
  59. }