Explorar el Código

* factored out OptPass1Sub
+ make use of OptPass1Sub on x86_64 and i8086 as well

git-svn-id: trunk@37572 -

florian hace 7 años
padre
commit
73fda1ccb6
Se han modificado 4 ficheros con 103 adiciones y 90 borrados
  1. 2 89
      compiler/i386/aoptcpu.pas
  2. 3 1
      compiler/i8086/aoptcpu.pas
  3. 96 0
      compiler/x86/aoptx86.pas
  4. 2 0
      compiler/x86_64/aoptcpu.pas

+ 2 - 89
compiler/i386/aoptcpu.pas

@@ -525,51 +525,6 @@ var
     GetFinalDestination := true;
   end;
 
-  function DoSubAddOpt(var p: tai): Boolean;
-  begin
-    DoSubAddOpt := False;
-    if GetLastInstruction(p, hp1) and
-       (hp1.typ = ait_instruction) and
-       (taicpu(hp1).opsize = taicpu(p).opsize) then
-      case taicpu(hp1).opcode Of
-        A_DEC:
-          if (taicpu(hp1).oper[0]^.typ = top_reg) and
-             (taicpu(hp1).oper[0]^.reg = taicpu(p).oper[1]^.reg) then
-            begin
-              taicpu(p).loadConst(0,taicpu(p).oper[0]^.val+1);
-              asml.remove(hp1);
-              hp1.free;
-            end;
-         A_SUB:
-           if (taicpu(hp1).oper[0]^.typ = top_const) and
-              (taicpu(hp1).oper[1]^.typ = top_reg) and
-              (taicpu(hp1).oper[1]^.reg = taicpu(p).oper[1]^.reg) then
-             begin
-               taicpu(p).loadConst(0,taicpu(p).oper[0]^.val+taicpu(hp1).oper[0]^.val);
-               asml.remove(hp1);
-               hp1.free;
-             end;
-         A_ADD:
-           if (taicpu(hp1).oper[0]^.typ = top_const) and
-              (taicpu(hp1).oper[1]^.typ = top_reg) and
-              (taicpu(hp1).oper[1]^.reg = taicpu(p).oper[1]^.reg) then
-             begin
-               taicpu(p).loadConst(0,taicpu(p).oper[0]^.val-taicpu(hp1).oper[0]^.val);
-               asml.remove(hp1);
-               hp1.free;
-               if (taicpu(p).oper[0]^.val = 0) then
-                 begin
-                   hp1 := tai(p.next);
-                   asml.remove(p);
-                   p.free;
-                   if not GetLastInstruction(hp1, p) then
-                     p := hp1;
-                   DoSubAddOpt := True;
-                 end
-             end;
-       end;
-  end;
-
 begin
   p := BlockStart;
   ClearUsedRegs;
@@ -1116,50 +1071,8 @@ begin
                         end
                     end;
                   A_SUB:
-                    { * change "subl $2, %esp; pushw x" to "pushl x"}
-                    { * change "sub/add const1, reg" or "dec reg" followed by
-                        "sub const2, reg" to one "sub ..., reg" }
-                    begin
-                      if (taicpu(p).oper[0]^.typ = top_const) and
-                         (taicpu(p).oper[1]^.typ = top_reg) then
-                        if (taicpu(p).oper[0]^.val = 2) and
-                           (taicpu(p).oper[1]^.reg = NR_ESP) and
-                           { Don't do the sub/push optimization if the sub }
-                           { comes from setting up the stack frame (JM)    }
-                           (not getLastInstruction(p,hp1) or
-                           (hp1.typ <> ait_instruction) or
-                           (taicpu(hp1).opcode <> A_MOV) or
-                           (taicpu(hp1).oper[0]^.typ <> top_reg) or
-                           (taicpu(hp1).oper[0]^.reg <> NR_ESP) or
-                           (taicpu(hp1).oper[1]^.typ <> top_reg) or
-                           (taicpu(hp1).oper[1]^.reg <> NR_EBP)) then
-                          begin
-                            hp1 := tai(p.next);
-                            while Assigned(hp1) and
-                                  (tai(hp1).typ in [ait_instruction]+SkipInstr) and
-                                  not RegReadByInstruction(NR_ESP,hp1) and
-                                  not RegModifiedByInstruction(NR_ESP,hp1) do
-                              hp1 := tai(hp1.next);
-                            if Assigned(hp1) and
-                               (tai(hp1).typ = ait_instruction) and
-                               (taicpu(hp1).opcode = A_PUSH) and
-                               (taicpu(hp1).opsize = S_W) then
-                              begin
-                                taicpu(hp1).changeopsize(S_L);
-                                if taicpu(hp1).oper[0]^.typ=top_reg then
-                                  setsubreg(taicpu(hp1).oper[0]^.reg,R_SUBWHOLE);
-                                hp1 := tai(p.next);
-                                asml.remove(p);
-                                p.free;
-                                p := hp1;
-                                continue
-                              end;
-                            if DoSubAddOpt(p) then
-                              continue;
-                          end
-                        else if DoSubAddOpt(p) then
-                          continue
-                    end;
+                    if OptPass1Sub(p) then
+                      continue;
                   A_VMOVAPS,
                   A_VMOVAPD:
                     if OptPass1VMOVAP(p) then

+ 3 - 1
compiler/i8086/aoptcpu.pas

@@ -109,7 +109,9 @@ unit aoptcpu;
                         result:=true;
                       end;
                   end;
-              end
+                A_SUB:
+                  result:=OptPass1Sub(p);
+              end;
             end
         end;
       end;

+ 96 - 0
compiler/x86/aoptx86.pas

@@ -55,6 +55,8 @@ unit aoptx86;
         class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean;
         procedure RemoveLastDeallocForFuncRes(p : tai);
 
+        function DoSubAddOpt(var p : tai) : Boolean;
+
         function PrePeepholeOptSxx(var p : tai) : boolean;
 
         function OptPass1AND(var p : tai) : boolean;
@@ -66,6 +68,7 @@ unit aoptx86;
         function OptPass1MOVXX(var p : tai) : boolean;
         function OptPass1OP(const p : tai) : boolean;
         function OptPass1LEA(var p : tai) : boolean;
+        function OptPass1Sub(var p : tai) : boolean;
 
         function OptPass2MOV(var p : tai) : boolean;
         function OptPass2Imul(var p : tai) : boolean;
@@ -1875,6 +1878,99 @@ unit aoptx86;
       end;
 
 
+    function TX86AsmOptimizer.DoSubAddOpt(var p: tai): Boolean;
+      var
+        hp1 : tai;
+      begin
+        DoSubAddOpt := False;
+        if GetLastInstruction(p, hp1) and
+           (hp1.typ = ait_instruction) and
+           (taicpu(hp1).opsize = taicpu(p).opsize) then
+          case taicpu(hp1).opcode Of
+            A_DEC:
+              if (taicpu(hp1).oper[0]^.typ = top_reg) and
+                MatchOperand(taicpu(hp1).oper[1]^,taicpu(p).oper[1]^) then
+                begin
+                  taicpu(p).loadConst(0,taicpu(p).oper[0]^.val+1);
+                  asml.remove(hp1);
+                  hp1.free;
+                end;
+             A_SUB:
+               if MatchOpType(taicpu(hp1),top_const,top_reg) and
+                 MatchOperand(taicpu(hp1).oper[1]^,taicpu(p).oper[1]^) then
+                 begin
+                   taicpu(p).loadConst(0,taicpu(p).oper[0]^.val+taicpu(hp1).oper[0]^.val);
+                   asml.remove(hp1);
+                   hp1.free;
+                 end;
+             A_ADD:
+               if MatchOpType(taicpu(hp1),top_const,top_reg) and
+                 MatchOperand(taicpu(hp1).oper[1]^,taicpu(p).oper[1]^) then
+                 begin
+                   taicpu(p).loadConst(0,taicpu(p).oper[0]^.val-taicpu(hp1).oper[0]^.val);
+                   asml.remove(hp1);
+                   hp1.free;
+                   if (taicpu(p).oper[0]^.val = 0) then
+                     begin
+                       hp1 := tai(p.next);
+                       asml.remove(p);
+                       p.free;
+                       if not GetLastInstruction(hp1, p) then
+                         p := hp1;
+                       DoSubAddOpt := True;
+                     end
+                 end;
+           end;
+      end;
+
+
+    function TX86AsmOptimizer.OptPass1Sub(var p : tai) : boolean;
+      var
+        hp1 : tai;
+      begin
+        Result:=false;
+        { * change "subl $2, %esp; pushw x" to "pushl x"}
+        { * change "sub/add const1, reg" or "dec reg" followed by
+            "sub const2, reg" to one "sub ..., reg" }
+        if MatchOpType(taicpu(p),top_const,top_reg) then
+          begin
+{$ifdef i386}
+            if (taicpu(p).oper[0]^.val = 2) and
+               (taicpu(p).oper[1]^.reg = NR_ESP) and
+               { Don't do the sub/push optimization if the sub }
+               { comes from setting up the stack frame (JM)    }
+               (not(GetLastInstruction(p,hp1)) or
+               not(MatchInstruction(hp1,A_MOV,[S_L]) and
+                 MatchOperand(taicpu(hp1).oper[0]^,NR_ESP) and
+                 MatchOperand(taicpu(hp1).oper[0]^,NR_EBP))) then
+              begin
+                hp1 := tai(p.next);
+                while Assigned(hp1) and
+                      (tai(hp1).typ in [ait_instruction]+SkipInstr) and
+                      not RegReadByInstruction(NR_ESP,hp1) and
+                      not RegModifiedByInstruction(NR_ESP,hp1) do
+                  hp1 := tai(hp1.next);
+                if Assigned(hp1) and
+                  MatchInstruction(hp1,A_PUSH,[S_W]) then
+                  begin
+                    taicpu(hp1).changeopsize(S_L);
+                    if taicpu(hp1).oper[0]^.typ=top_reg then
+                      setsubreg(taicpu(hp1).oper[0]^.reg,R_SUBWHOLE);
+                    hp1 := tai(p.next);
+                    asml.remove(p);
+                    p.free;
+                    p := hp1;
+                    Result:=true;
+                    exit;
+                  end;
+              end;
+{$endif i386}
+            if DoSubAddOpt(p) then
+              Result:=true;
+          end;
+      end;
+
+
     function TX86AsmOptimizer.OptPass2MOV(var p : tai) : boolean;
       var
        TmpUsedRegs : TAllUsedRegs;

+ 2 - 0
compiler/x86_64/aoptcpu.pas

@@ -106,6 +106,8 @@ uses
                 result:=OptPass1MOVXX(p);
               A_LEA:
                 result:=OptPass1LEA(p);
+              A_SUB:
+                result:=OptPass1Sub(p);
             end;
           end;
         end;