Utils.cs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. using Ryujinx.Graphics.Shader.IntermediateRepresentation;
  2. namespace Ryujinx.Graphics.Shader.Translation.Optimizations
  3. {
  4. static class Utils
  5. {
  6. private static Operation FindBranchSource(BasicBlock block)
  7. {
  8. foreach (BasicBlock sourceBlock in block.Predecessors)
  9. {
  10. if (sourceBlock.Operations.Count > 0)
  11. {
  12. Operation lastOp = sourceBlock.Operations.Last.Value as Operation;
  13. if (lastOp != null &&
  14. ((sourceBlock.Next == block && lastOp.Inst == Instruction.BranchIfFalse) ||
  15. (sourceBlock.Branch == block && lastOp.Inst == Instruction.BranchIfTrue)))
  16. {
  17. return lastOp;
  18. }
  19. }
  20. }
  21. return null;
  22. }
  23. private static bool BlockConditionsMatch(BasicBlock currentBlock, BasicBlock queryBlock)
  24. {
  25. // Check if all the conditions for the query block are satisfied by the current block.
  26. // Just checks the top-most conditional for now.
  27. Operation currentBranch = FindBranchSource(currentBlock);
  28. Operation queryBranch = FindBranchSource(queryBlock);
  29. Operand currentCondition = currentBranch?.GetSource(0);
  30. Operand queryCondition = queryBranch?.GetSource(0);
  31. // The condition should be the same operand instance.
  32. return currentBranch != null && queryBranch != null &&
  33. currentBranch.Inst == queryBranch.Inst &&
  34. currentCondition == queryCondition;
  35. }
  36. public static Operand FindLastOperation(Operand source, BasicBlock block)
  37. {
  38. if (source.AsgOp is PhiNode phiNode)
  39. {
  40. // This source can have a different value depending on a previous branch.
  41. // Ensure that conditions met for that branch are also met for the current one.
  42. // Prefer the latest sources for the phi node.
  43. for (int i = phiNode.SourcesCount - 1; i >= 0; i--)
  44. {
  45. BasicBlock phiBlock = phiNode.GetBlock(i);
  46. if (BlockConditionsMatch(block, phiBlock))
  47. {
  48. return phiNode.GetSource(i);
  49. }
  50. }
  51. }
  52. return source;
  53. }
  54. }
  55. }