aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Shader/Translation/Ssa.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Graphics.Shader/Translation/Ssa.cs')
-rw-r--r--Ryujinx.Graphics.Shader/Translation/Ssa.cs77
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();
+ }
}
}