| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- using Ryujinx.Graphics.Shader.IntermediateRepresentation;
- using static Ryujinx.Graphics.Shader.IntermediateRepresentation.OperandHelper;
- namespace Ryujinx.Graphics.Shader.Translation.Optimizations
- {
- static class Simplification
- {
- private const int AllOnes = ~0;
- public static void RunPass(Operation operation)
- {
- switch (operation.Inst)
- {
- case Instruction.Add:
- case Instruction.BitwiseExclusiveOr:
- TryEliminateBinaryOpCommutative(operation, 0);
- break;
- case Instruction.BitwiseAnd:
- TryEliminateBitwiseAnd(operation);
- break;
- case Instruction.BitwiseOr:
- TryEliminateBitwiseOr(operation);
- break;
- case Instruction.ConditionalSelect:
- TryEliminateConditionalSelect(operation);
- break;
- case Instruction.Divide:
- TryEliminateBinaryOpY(operation, 1);
- break;
- case Instruction.Multiply:
- TryEliminateBinaryOpCommutative(operation, 1);
- break;
- case Instruction.ShiftLeft:
- case Instruction.ShiftRightS32:
- case Instruction.ShiftRightU32:
- case Instruction.Subtract:
- TryEliminateBinaryOpY(operation, 0);
- break;
- }
- }
- private static void TryEliminateBitwiseAnd(Operation operation)
- {
- // Try to recognize and optimize those 3 patterns (in order):
- // x & 0xFFFFFFFF == x, 0xFFFFFFFF & y == y,
- // x & 0x00000000 == 0x00000000, 0x00000000 & y == 0x00000000
- Operand x = operation.GetSource(0);
- Operand y = operation.GetSource(1);
- if (IsConstEqual(x, AllOnes))
- {
- operation.TurnIntoCopy(y);
- }
- else if (IsConstEqual(y, AllOnes))
- {
- operation.TurnIntoCopy(x);
- }
- else if (IsConstEqual(x, 0) || IsConstEqual(y, 0))
- {
- operation.TurnIntoCopy(Const(0));
- }
- }
- private static void TryEliminateBitwiseOr(Operation operation)
- {
- // Try to recognize and optimize those 3 patterns (in order):
- // x | 0x00000000 == x, 0x00000000 | y == y,
- // x | 0xFFFFFFFF == 0xFFFFFFFF, 0xFFFFFFFF | y == 0xFFFFFFFF
- Operand x = operation.GetSource(0);
- Operand y = operation.GetSource(1);
- if (IsConstEqual(x, 0))
- {
- operation.TurnIntoCopy(y);
- }
- else if (IsConstEqual(y, 0))
- {
- operation.TurnIntoCopy(x);
- }
- else if (IsConstEqual(x, AllOnes) || IsConstEqual(y, AllOnes))
- {
- operation.TurnIntoCopy(Const(AllOnes));
- }
- }
- private static void TryEliminateBinaryOpY(Operation operation, int comparand)
- {
- Operand x = operation.GetSource(0);
- Operand y = operation.GetSource(1);
- if (IsConstEqual(y, comparand))
- {
- operation.TurnIntoCopy(x);
- }
- }
- private static void TryEliminateBinaryOpCommutative(Operation operation, int comparand)
- {
- Operand x = operation.GetSource(0);
- Operand y = operation.GetSource(1);
- if (IsConstEqual(x, comparand))
- {
- operation.TurnIntoCopy(y);
- }
- else if (IsConstEqual(y, comparand))
- {
- operation.TurnIntoCopy(x);
- }
- }
- private static void TryEliminateConditionalSelect(Operation operation)
- {
- Operand cond = operation.GetSource(0);
- if (cond.Type != OperandType.Constant)
- {
- return;
- }
- // The condition is constant, we can turn it into a copy, and select
- // the source based on the condition value.
- int srcIndex = cond.Value != 0 ? 1 : 2;
- Operand source = operation.GetSource(srcIndex);
- operation.TurnIntoCopy(source);
- }
- private static bool IsConstEqual(Operand operand, int comparand)
- {
- if (operand.Type != OperandType.Constant)
- {
- return false;
- }
- return operand.Value == comparand;
- }
- }
- }
|