Browse Source

* x86: New RET/lbl/RET optimisation

J. Gareth "Curious Kit" Moreton 2 years ago
parent
commit
8520dabebb
4 changed files with 44 additions and 0 deletions
  1. 2 0
      compiler/i386/aoptcpu.pas
  2. 2 0
      compiler/i8086/aoptcpu.pas
  3. 38 0
      compiler/x86/aoptx86.pas
  4. 2 0
      compiler/x86_64/aoptcpu.pas

+ 2 - 0
compiler/i386/aoptcpu.pas

@@ -434,6 +434,8 @@ unit aoptcpu;
                   Result:=PostPeepholeOptADDSUB(p);
                 A_XOR:
                   Result:=PostPeepholeOptXor(p);
+                A_RET:
+                  Result:=PostPeepholeOptRET(p);
                 A_VPXOR:
                   Result:=PostPeepholeOptVPXOR(p);
                 else

+ 2 - 0
compiler/i8086/aoptcpu.pas

@@ -162,6 +162,8 @@ unit aoptcpu;
                 A_OR,
                 A_TEST:
                   Result:=PostPeepholeOptTestOr(p);
+                A_RET:
+                  Result:=PostPeepholeOptRET(p);
                 else
                   ;
               end;

+ 38 - 0
compiler/x86/aoptx86.pas

@@ -224,6 +224,7 @@ unit aoptx86;
         function PostPeepholeOptShr(var p : tai) : boolean;
         function PostPeepholeOptADDSUB(var p : tai) : Boolean;
         function PostPeepholeOptVPXOR(var p: tai): Boolean;
+        function PostPeepholeOptRET(var p: tai): Boolean;
 
         procedure ConvertJumpToRET(const p: tai; const ret_p: tai);
 
@@ -17549,6 +17550,43 @@ unit aoptx86;
       end;
 
 
+    function TX86AsmOptimizer.PostPeepholeOptRET(var p: tai): Boolean;
+      var
+        hp1, p_new: tai;
+      begin
+        Result := False;
+        { Check for:
+              ret
+            .Lbl:
+              ret
+
+          Remove first 'ret'
+        }
+        if GetNextInstruction(p, hp1) and
+          { Remember where the label is }
+          SetAndTest(hp1, p_new) and
+          (hp1.typ in [ait_align, ait_label]) and
+          SkipLabels(hp1, hp1) and
+          MatchInstruction(hp1, A_RET, []) and
+          { To be safe, make sure the RET instructions are identical }
+          (taicpu(p).ops = taicpu(hp1).ops) and
+          (
+            (taicpu(p).ops = 0) or
+            (
+              (taicpu(p).ops = 1) and
+              MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[0]^)
+            )
+          ) then
+          begin
+            DebugMsg(SPeepholeOptimization + 'Removed superfluous RET', p);
+            UpdateUsedRegs(tai(p.Next));
+            RemoveCurrentP(p, p_new);
+            Result := True;
+            Exit;
+          end;
+      end;
+
+
     class procedure TX86AsmOptimizer.OptimizeRefs(var p: taicpu);
       var
         OperIdx: Integer;

+ 2 - 0
compiler/x86_64/aoptcpu.pas

@@ -302,6 +302,8 @@ uses
                 A_ADD,
                 A_SUB:
                   Result:=PostPeepholeOptADDSUB(p);
+                A_RET:
+                  Result:=PostPeepholeOptRET(p);
                 A_VPXOR:
                   Result:=PostPeepholeOptVPXOR(p);
                 else