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 Simplify(Operation operation)
switch (operation.Inst)
case Instruction.Add:
case Instruction.BitwiseExclusiveOr:
TryEliminateBinaryOpCommutative(operation, 0);
break;
case Instruction.BitwiseAnd:
TryEliminateBitwiseAnd(operation);
case Instruction.BitwiseOr:
TryEliminateBitwiseOr(operation);
case Instruction.ConditionalSelect:
TryEliminateConditionalSelect(operation);
case Instruction.Divide:
TryEliminateBinaryOpY(operation, 1);
case Instruction.Multiply:
TryEliminateBinaryOpCommutative(operation, 1);
case Instruction.ShiftLeft:
case Instruction.ShiftRightS32:
case Instruction.ShiftRightU32:
case Instruction.Subtract:
TryEliminateBinaryOpY(operation, 0);
}
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)
// x | 0x00000000 == x, 0x00000000 | y == y,
// x | 0xFFFFFFFF == 0xFFFFFFFF, 0xFFFFFFFF | y == 0xFFFFFFFF
if (IsConstEqual(x, 0))
else if (IsConstEqual(y, 0))
else if (IsConstEqual(x, AllOnes) || IsConstEqual(y, AllOnes))
operation.TurnIntoCopy(Const(AllOnes));
private static void TryEliminateBinaryOpY(Operation operation, int comparand)
if (IsConstEqual(y, comparand))
private static void TryEliminateBinaryOpCommutative(Operation operation, int comparand)
if (IsConstEqual(x, comparand))
else if (IsConstEqual(y, comparand))
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;