Browse Source

Optimize: merge more patterns

Akeit0 1 year ago
parent
commit
a3bf5df47a
1 changed files with 40 additions and 9 deletions
  1. 40 9
      src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs

+ 40 - 9
src/Lua/CodeAnalysis/Compilation/FunctionCompilationContext.cs

@@ -127,7 +127,12 @@ public class FunctionCompilationContext : IDisposable
         switch (opcode)
         switch (opcode)
         {
         {
             case OpCode.Move:
             case OpCode.Move:
-               if (lastInstruction.A!=lastLocal&&lastInstruction.A ==instruction.B)
+                //last A is not local variable
+               if (lastInstruction.A!=lastLocal && 
+                   //available to merge
+                   lastInstruction.A == instruction.B &&
+                   //not already merged
+                   lastInstruction.A != lastInstruction.B)
                {
                {
                     switch (lastInstruction.OpCode)
                     switch (lastInstruction.OpCode)
                     {
                     {
@@ -150,15 +155,14 @@ public class FunctionCompilationContext : IDisposable
             case OpCode.GetTable:
             case OpCode.GetTable:
             {
             {
                 //Merge MOVE GetTable
                 //Merge MOVE GetTable
-                if (lastInstruction.OpCode == OpCode.Move&&lastLocal != lastInstruction.A)
+                if (lastInstruction.OpCode == OpCode.Move && lastLocal != lastInstruction.A)
                 {
                 {
-                        var b = instruction.B;
-                        if (instruction.A==b&&lastInstruction.A == b)
-                        {
-                            lastInstruction=Instruction.GetTable(instruction.A, lastInstruction.B, instruction.C);
-                            incrementStackPosition = false;
-                            return;
-                        }
+                    if (lastInstruction.A == instruction.B)
+                    {
+                        lastInstruction=Instruction.GetTable(instruction.A, lastInstruction.B, instruction.C);
+                        incrementStackPosition = false;
+                        return;
+                    }
                     
                     
                 }
                 }
                 break;
                 break;
@@ -181,6 +185,7 @@ public class FunctionCompilationContext : IDisposable
                             {
                             {
                                 last2Instruction=Instruction.SetTable((byte)(lastB), instruction.B, last2Instruction.B);
                                 last2Instruction=Instruction.SetTable((byte)(lastB), instruction.B, last2Instruction.B);
                                 instructions.RemoveAtSwapback(instructions.Length - 1);
                                 instructions.RemoveAtSwapback(instructions.Length - 1);
+                                instructionPositions.RemoveAtSwapback(instructionPositions.Length - 1);
                                 incrementStackPosition = false;
                                 incrementStackPosition = false;
                                 return;
                                 return;
                             }
                             }
@@ -197,6 +202,24 @@ public class FunctionCompilationContext : IDisposable
                         return;
                         return;
                     }
                     }
                 }
                 }
+                else if (lastInstruction.OpCode == OpCode.GetTabUp&&instructions.Length >= 2)
+                {
+                    ref var last2Instruction = ref instructions[^2];
+                    var last2OpCode = last2Instruction.OpCode;
+                    if (last2OpCode is OpCode.LoadK or OpCode.Move)
+                    {
+                        
+                        var last2A = last2Instruction.A;
+                        if (last2A != lastLocal && instruction.C == last2A)
+                        {
+                            var c = last2OpCode==OpCode.LoadK?last2Instruction.Bx+256:last2Instruction.B;
+                            last2Instruction = lastInstruction;
+                            lastInstruction = instruction with { C = (ushort)c};
+                            incrementStackPosition = false;
+                            return;
+                        }
+                    }
+                }
                 break;
                 break;
             }
             }
             case OpCode.Unm:
             case OpCode.Unm:
@@ -209,6 +232,14 @@ public class FunctionCompilationContext : IDisposable
                     return;
                     return;
                 }
                 }
                 break;
                 break;
+            case OpCode.Return:
+                if (lastInstruction.OpCode == OpCode.Move && instruction.B ==2 && lastInstruction.B < 256)
+                {
+                    lastInstruction = instruction with { A = (byte)lastInstruction.B };
+                    incrementStackPosition = false;
+                    return;
+                }
+                break;
         }
         }
         
         
         instructions.Add(instruction);
         instructions.Add(instruction);