Ver código fonte

* factored out OpPass2MOV code, x86-64 uses it as well now

git-svn-id: trunk@33932 -
florian 9 anos atrás
pai
commit
5e8e21c1be
3 arquivos alterados com 105 adições e 80 exclusões
  1. 2 80
      compiler/i386/aoptcpu.pas
  2. 87 0
      compiler/x86/aoptx86.pas
  3. 16 0
      compiler/x86_64/aoptcpu.pas

+ 2 - 80
compiler/i386/aoptcpu.pas

@@ -1682,7 +1682,6 @@ var
   p,hp1,hp2,hp3: tai;
   l : longint;
   condition : tasmcond;
-  TmpUsedRegs: TAllUsedRegs;
   carryadd_opcode: Tasmop;
 
 begin
@@ -1936,85 +1935,8 @@ begin
                       end;
                   end;
               A_MOV:
-                begin
-                  if (taicpu(p).oper[0]^.typ = top_reg) and
-                     (taicpu(p).oper[1]^.typ = top_reg) and
-                     GetNextInstruction(p, hp1) and
-                     (hp1.typ = ait_Instruction) and
-                     ((taicpu(hp1).opcode = A_MOV) or
-                      (taicpu(hp1).opcode = A_MOVZX) or
-                      (taicpu(hp1).opcode = A_MOVSX)) and
-                     (taicpu(hp1).oper[0]^.typ = top_ref) and
-                     (taicpu(hp1).oper[1]^.typ = top_reg) and
-                     ((taicpu(hp1).oper[0]^.ref^.base = taicpu(p).oper[1]^.reg) or
-                      (taicpu(hp1).oper[0]^.ref^.index = taicpu(p).oper[1]^.reg)) and
-                     (getsupreg(taicpu(hp1).oper[1]^.reg) = getsupreg(taicpu(p).oper[1]^.reg)) then
-              {mov reg1, reg2
-               mov/zx/sx (reg2, ..), reg2      to   mov/zx/sx (reg1, ..), reg2}
-                    begin
-                      if (taicpu(hp1).oper[0]^.ref^.base = taicpu(p).oper[1]^.reg) then
-                        taicpu(hp1).oper[0]^.ref^.base := taicpu(p).oper[0]^.reg;
-                      if (taicpu(hp1).oper[0]^.ref^.index = taicpu(p).oper[1]^.reg) then
-                        taicpu(hp1).oper[0]^.ref^.index := taicpu(p).oper[0]^.reg;
-                      asml.remove(p);
-                      p.free;
-                      p := hp1;
-                      continue;
-                    end
-                  else if (taicpu(p).oper[0]^.typ = top_ref) and
-                     GetNextInstruction(p,hp1) and
-                     (hp1.typ = ait_instruction) and
-                     (IsFoldableArithOp(taicpu(hp1),taicpu(p).oper[1]^.reg) or
-                      ((taicpu(hp1).opcode=A_LEA) and
-                       (taicpu(hp1).oper[1]^.reg = taicpu(p).oper[1]^.reg) and
-                       ((MatchReference(taicpu(hp1).oper[0]^.ref^,taicpu(p).oper[1]^.reg,NR_INVALID) and
-                        (taicpu(hp1).oper[0]^.ref^.index<>taicpu(p).oper[1]^.reg)) or
-                        (MatchReference(taicpu(hp1).oper[0]^.ref^,NR_INVALID,taicpu(p).oper[1]^.reg) and
-                        (taicpu(hp1).oper[0]^.ref^.base<>taicpu(p).oper[1]^.reg))
-                       )
-                      )
-                     ) and
-                     GetNextInstruction(hp1,hp2) and
-                     MatchInstruction(hp2,A_MOV,[]) and
-                     MatchOperand(taicpu(p).oper[1]^,taicpu(hp2).oper[0]^) and
-                     (taicpu(hp2).oper[1]^.typ = top_ref) then
-                    begin
-                      CopyUsedRegs(TmpUsedRegs);
-                      UpdateUsedRegs(TmpUsedRegs,tai(hp1.next));
-                      if (RefsEqual(taicpu(hp2).oper[1]^.ref^, taicpu(p).oper[0]^.ref^) and
-                         not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,
-                              hp2, TmpUsedRegs))) then
-  { change   mov            (ref), reg            }
-  {          add/sub/or/... reg2/$const, reg      }
-  {          mov            reg, (ref)            }
-  {          # release reg                        }
-  { to       add/sub/or/... reg2/$const, (ref)    }
-                        begin
-                          case taicpu(hp1).opcode of
-                            A_INC,A_DEC,A_NOT,A_NEG:
-                              taicpu(hp1).loadRef(0,taicpu(p).oper[0]^.ref^);
-                            A_LEA:
-                              begin
-                                taicpu(hp1).opcode:=A_ADD;
-                                if taicpu(hp1).oper[0]^.ref^.index<>taicpu(p).oper[1]^.reg then
-                                  taicpu(hp1).loadreg(0,taicpu(hp1).oper[0]^.ref^.index)
-                                else
-                                  taicpu(hp1).loadreg(0,taicpu(hp1).oper[0]^.ref^.base);
-                                taicpu(hp1).loadRef(1,taicpu(p).oper[0]^.ref^);
-                                DebugMsg('Peephole FoldLea done',hp1);
-                              end
-                            else
-                              taicpu(hp1).loadRef(1,taicpu(p).oper[0]^.ref^);
-                          end;
-                          asml.remove(p);
-                          asml.remove(hp2);
-                          p.free;
-                          hp2.free;
-                          p := hp1
-                        end;
-                      ReleaseUsedRegs(TmpUsedRegs);
-                    end
-                end;
+                if OptPass2MOV(p) then
+                  continue;
             end;
           end;
       end;

+ 87 - 0
compiler/x86/aoptx86.pas

@@ -44,6 +44,8 @@ unit aoptx86;
         function OptPass1VOP(const p : tai) : boolean;
         function OptPass1MOV(var p : tai) : boolean;
 
+        function OptPass2MOV(var p : tai) : boolean;
+
         procedure DebugMsg(const s : string; p : tai);inline;
 
         procedure AllocRegBetween(reg : tregister; p1,p2 : tai;var initialusedregs : TAllUsedRegs);
@@ -1028,6 +1030,91 @@ unit aoptx86;
       end;
 
 
+    function TX86AsmOptimizer.OptPass2MOV(var p : tai) : boolean;
+      var
+       TmpUsedRegs : TAllUsedRegs;
+       hp1,hp2: tai;
+      begin
+        Result:=false;
+        if MatchOpType(taicpu(p),top_reg,top_reg) and
+          GetNextInstruction(p, hp1) and
+          MatchInstruction(hp1,A_MOV,A_MOVZX,A_MOVSX,[]) and
+          MatchOpType(taicpu(hp1),top_ref,top_reg) and
+          ((taicpu(hp1).oper[0]^.ref^.base = taicpu(p).oper[1]^.reg)
+           or
+           (taicpu(hp1).oper[0]^.ref^.index = taicpu(p).oper[1]^.reg)
+            ) and
+          (getsupreg(taicpu(hp1).oper[1]^.reg) = getsupreg(taicpu(p).oper[1]^.reg)) then
+          { mov reg1, reg2
+            mov/zx/sx (reg2, ..), reg2      to   mov/zx/sx (reg1, ..), reg2}
+          begin
+            if (taicpu(hp1).oper[0]^.ref^.base = taicpu(p).oper[1]^.reg) then
+              taicpu(hp1).oper[0]^.ref^.base := taicpu(p).oper[0]^.reg;
+            if (taicpu(hp1).oper[0]^.ref^.index = taicpu(p).oper[1]^.reg) then
+              taicpu(hp1).oper[0]^.ref^.index := taicpu(p).oper[0]^.reg;
+            asml.remove(p);
+            p.free;
+            p := hp1;
+            Result:=true;
+            exit;
+          end
+        else if (taicpu(p).oper[0]^.typ = top_ref) and
+          GetNextInstruction(p,hp1) and
+          (hp1.typ = ait_instruction) and
+          (IsFoldableArithOp(taicpu(hp1),taicpu(p).oper[1]^.reg) or
+           ((taicpu(hp1).opcode=A_LEA) and
+            (taicpu(hp1).oper[1]^.reg = taicpu(p).oper[1]^.reg) and
+            ((MatchReference(taicpu(hp1).oper[0]^.ref^,taicpu(p).oper[1]^.reg,NR_INVALID) and
+             (taicpu(hp1).oper[0]^.ref^.index<>taicpu(p).oper[1]^.reg)
+              ) or
+             (MatchReference(taicpu(hp1).oper[0]^.ref^,NR_INVALID,
+              taicpu(p).oper[1]^.reg) and
+             (taicpu(hp1).oper[0]^.ref^.base<>taicpu(p).oper[1]^.reg))
+            )
+           )
+          ) and
+          GetNextInstruction(hp1,hp2) and
+          MatchInstruction(hp2,A_MOV,[]) and
+          MatchOperand(taicpu(p).oper[1]^,taicpu(hp2).oper[0]^) and
+          (taicpu(hp2).oper[1]^.typ = top_ref) then
+          begin
+            CopyUsedRegs(TmpUsedRegs);
+            UpdateUsedRegs(TmpUsedRegs,tai(hp1.next));
+            if (RefsEqual(taicpu(hp2).oper[1]^.ref^, taicpu(p).oper[0]^.ref^) and
+              not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2, TmpUsedRegs))) then
+              { change   mov            (ref), reg
+                         add/sub/or/... reg2/$const, reg
+                         mov            reg, (ref)
+                         # release reg
+                to       add/sub/or/... reg2/$const, (ref)    }
+              begin
+                case taicpu(hp1).opcode of
+                  A_INC,A_DEC,A_NOT,A_NEG :
+                    taicpu(hp1).loadRef(0,taicpu(p).oper[0]^.ref^);
+                  A_LEA :
+                    begin
+                      taicpu(hp1).opcode:=A_ADD;
+                      if taicpu(hp1).oper[0]^.ref^.index<>taicpu(p).oper[1]^.reg then
+                        taicpu(hp1).loadreg(0,taicpu(hp1).oper[0]^.ref^.index)
+                      else
+                        taicpu(hp1).loadreg(0,taicpu(hp1).oper[0]^.ref^.base);
+                      taicpu(hp1).loadRef(1,taicpu(p).oper[0]^.ref^);
+                      DebugMsg('Peephole FoldLea done',hp1);
+                    end
+                  else
+                    taicpu(hp1).loadRef(1,taicpu(p).oper[0]^.ref^);
+                end;
+                asml.remove(p);
+                asml.remove(hp2);
+                p.free;
+                hp2.free;
+                p := hp1
+              end;
+            ReleaseUsedRegs(TmpUsedRegs);
+          end;
+      end;
+
+
     procedure TX86AsmOptimizer.PostPeepholeOptMov(const p : tai);
       begin
        if MatchOperand(taicpu(p).oper[0]^,0) and

+ 16 - 0
compiler/x86_64/aoptcpu.pas

@@ -32,6 +32,7 @@ uses cgbase, cpubase, aasmtai, aopt, aoptx86, aoptcpub;
 type
   TCpuAsmOptimizer = class(TX86AsmOptimizer)
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
+    function PeepHoleOptPass2Cpu(var p: tai): boolean; override;
     function PostPeepHoleOptsCpu(var p : tai) : boolean; override;
   end;
 
@@ -440,6 +441,21 @@ begin
 end;
 
 
+    function TCpuAsmOptimizer.PeepHoleOptPass2Cpu(var p : tai) : boolean;
+      begin
+        Result := False;
+        case p.typ of
+          ait_instruction:
+            begin
+              case taicpu(p).opcode of
+                A_MOV:
+                  Result:=OptPass2MOV(p);
+              end;
+            end;
+        end;
+      end;
+
+
     function TCpuAsmOptimizer.PostPeepHoleOptsCpu(var p: tai): boolean;
       begin
         result := false;