diff options
Diffstat (limited to 'Ryujinx.Graphics.Shader/Translation/Ssa.cs')
-rw-r--r-- | Ryujinx.Graphics.Shader/Translation/Ssa.cs | 77 |
1 files changed, 61 insertions, 16 deletions
diff --git a/Ryujinx.Graphics.Shader/Translation/Ssa.cs b/Ryujinx.Graphics.Shader/Translation/Ssa.cs index ff0fa2b7..8c63d72d 100644 --- a/Ryujinx.Graphics.Shader/Translation/Ssa.cs +++ b/Ryujinx.Graphics.Shader/Translation/Ssa.cs @@ -63,6 +63,51 @@ namespace Ryujinx.Graphics.Shader.Translation } } + private class LocalDefMap + { + private Operand[] _map; + private int[] _uses; + public int UseCount { get; private set; } + + public LocalDefMap() + { + _map = new Operand[RegisterConsts.TotalCount]; + _uses = new int[RegisterConsts.TotalCount]; + } + + public Operand Get(int key) + { + return _map[key]; + } + + public void Add(int key, Operand operand) + { + if (_map[key] == null) + { + _uses[UseCount++] = key; + } + + _map[key] = operand; + } + + public Operand GetUse(int index, out int key) + { + key = _uses[index]; + + return _map[key]; + } + + public void Clear() + { + for (int i = 0; i < UseCount; i++) + { + _map[_uses[i]] = null; + } + + UseCount = 0; + } + } + private struct Definition { public BasicBlock Block { get; } @@ -78,6 +123,7 @@ namespace Ryujinx.Graphics.Shader.Translation public static void Rename(BasicBlock[] blocks) { DefMap[] globalDefs = new DefMap[blocks.Length]; + LocalDefMap localDefs = new LocalDefMap(); for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) { @@ -89,13 +135,11 @@ namespace Ryujinx.Graphics.Shader.Translation // First pass, get all defs and locals uses. for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) { - Operand[] localDefs = new Operand[RegisterConsts.TotalCount]; - Operand RenameLocal(Operand operand) { if (operand != null && operand.Type == OperandType.Register) { - Operand local = localDefs[GetKeyFromRegister(operand.GetRegister())]; + Operand local = localDefs.Get(GetKeyFromRegister(operand.GetRegister())); operand = local ?? operand; } @@ -124,7 +168,7 @@ namespace Ryujinx.Graphics.Shader.Translation { Operand local = Local(); - localDefs[GetKeyFromRegister(dest.GetRegister())] = local; + localDefs.Add(GetKeyFromRegister(dest.GetRegister()), local); operation.SetDest(index, local); } @@ -134,16 +178,12 @@ namespace Ryujinx.Graphics.Shader.Translation node = node.Next; } - for (int index = 0; index < RegisterConsts.TotalCount; index++) + int localUses = localDefs.UseCount; + for (int index = 0; index < localUses; index++) { - Operand local = localDefs[index]; + Operand local = localDefs.GetUse(index, out int key); - if (local == null) - { - continue; - } - - Register reg = GetRegisterFromKey(index); + Register reg = GetRegisterFromKey(key); globalDefs[block.Index].TryAddOperand(reg, local); @@ -160,13 +200,13 @@ namespace Ryujinx.Graphics.Shader.Translation } } } + + localDefs.Clear(); } // Second pass, rename variables with definitions on different blocks. for (int blkIndex = 0; blkIndex < blocks.Length; blkIndex++) { - Operand[] localDefs = new Operand[RegisterConsts.TotalCount]; - BasicBlock block = blocks[blkIndex]; Operand RenameGlobal(Operand operand) @@ -175,7 +215,7 @@ namespace Ryujinx.Graphics.Shader.Translation { int key = GetKeyFromRegister(operand.GetRegister()); - Operand local = localDefs[key]; + Operand local = localDefs.Get(key); if (local != null) { @@ -184,7 +224,7 @@ namespace Ryujinx.Graphics.Shader.Translation operand = FindDefinitionForCurr(globalDefs, block, operand.GetRegister()); - localDefs[key] = operand; + localDefs.Add(key, operand); } return operand; @@ -200,6 +240,11 @@ namespace Ryujinx.Graphics.Shader.Translation } } } + + if (blkIndex < blocks.Length - 1) + { + localDefs.Clear(); + } } } |