| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364 |
- using Ryujinx.Graphics.Shader.IntermediateRepresentation;
- using System;
- namespace Ryujinx.Graphics.Shader.Translation.Optimizations
- {
- static class BranchElimination
- {
- public static bool RunPass(BasicBlock block)
- {
- if (block.HasBranch && IsRedundantBranch((Operation)block.GetLastOp(), Next(block)))
- {
- block.Branch = null;
- return true;
- }
- return false;
- }
- private static bool IsRedundantBranch(Operation current, BasicBlock nextBlock)
- {
- // Here we check that:
- // - The current block ends with a branch.
- // - The next block only contains a branch.
- // - The branch on the next block is unconditional.
- // - Both branches are jumping to the same location.
- // In this case, the branch on the current block can be removed,
- // as the next block is going to jump to the same place anyway.
- if (nextBlock == null)
- {
- return false;
- }
- if (!(nextBlock.Operations.First?.Value is Operation next))
- {
- return false;
- }
- if (next.Inst != Instruction.Branch)
- {
- return false;
- }
- return current.Dest == next.Dest;
- }
- private static BasicBlock Next(BasicBlock block)
- {
- block = block.Next;
- while (block != null && block.Operations.Count == 0)
- {
- if (block.HasBranch)
- {
- throw new InvalidOperationException("Found a bogus empty block that \"ends with a branch\".");
- }
- block = block.Next;
- }
- return block;
- }
- }
- }
|