Browse Source

* unify x86 peephole optimizer helpers

git-svn-id: trunk@31843 -
florian 10 years ago
parent
commit
53ea4fb7d4
5 changed files with 157 additions and 103 deletions
  1. 1 0
      .gitattributes
  2. 2 14
      compiler/i386/daopt386.pas
  3. 3 2
      compiler/i386/popt386.pas
  4. 150 0
      compiler/x86/aoptx86.pas
  5. 1 87
      compiler/x86_64/aoptcpu.pas

+ 1 - 0
.gitattributes

@@ -804,6 +804,7 @@ compiler/x86/aasmcpu.pas svneol=native#text/plain
 compiler/x86/agx86att.pas svneol=native#text/plain
 compiler/x86/agx86att.pas svneol=native#text/plain
 compiler/x86/agx86int.pas svneol=native#text/plain
 compiler/x86/agx86int.pas svneol=native#text/plain
 compiler/x86/agx86nsm.pas svneol=native#text/plain
 compiler/x86/agx86nsm.pas svneol=native#text/plain
+compiler/x86/aoptx86.pas svneol=native#text/pascal
 compiler/x86/cga.pas svneol=native#text/plain
 compiler/x86/cga.pas svneol=native#text/plain
 compiler/x86/cgx86.pas svneol=native#text/plain
 compiler/x86/cgx86.pas svneol=native#text/plain
 compiler/x86/cpubase.pas svneol=native#text/plain
 compiler/x86/cpubase.pas svneol=native#text/plain

+ 2 - 14
compiler/i386/daopt386.pas

@@ -171,8 +171,6 @@ type
 
 
 procedure InsertLLItem(AsmL: TAsmList; prev, foll, new_one: TLinkedListItem);
 procedure InsertLLItem(AsmL: TAsmList; prev, foll, new_one: TLinkedListItem);
 
 
-
-function RefsEqual(const R1, R2: TReference): Boolean;
 function isgp32reg(supreg: tsuperregister): Boolean;
 function isgp32reg(supreg: tsuperregister): Boolean;
 function reginref(supreg: tsuperregister; const ref: treference): boolean;
 function reginref(supreg: tsuperregister; const ref: treference): boolean;
 function RegReadByInstruction(supreg: tsuperregister; hp: tai): boolean;
 function RegReadByInstruction(supreg: tsuperregister; hp: tai): boolean;
@@ -270,7 +268,8 @@ Uses
     {$endif}
     {$endif}
   {$endif}
   {$endif}
 {$endif}
 {$endif}
-  globals, systems, verbose, symconst, cgobj,procinfo;
+  globals, systems, verbose, symconst, cgobj, procinfo,
+  aoptx86;
 
 
 Type
 Type
   TRefCompare = function(const r1, r2: treference; size1, size2: tcgsize): boolean;
   TRefCompare = function(const r1, r2: treference; size1, size2: tcgsize): boolean;
@@ -679,17 +678,6 @@ begin
 end;
 end;
 
 
 
 
-function refsequal(const r1, r2: treference): boolean;
-begin
-  refsequal :=
-    (r1.offset = r2.offset) and
-    (r1.segment = r2.segment) and (r1.base = r2.base) and
-    (r1.index = r2.index) and (r1.scalefactor = r2.scalefactor) and
-    (r1.symbol=r2.symbol) and (r1.refaddr = r2.refaddr) and
-    (r1.relsymbol = r2.relsymbol);
-end;
-
-
 {$push}
 {$push}
 {$q-}
 {$q-}
 
 

+ 3 - 2
compiler/i386/popt386.pas

@@ -44,7 +44,8 @@ uses
   cobjects,
   cobjects,
 {$endif finaldestdebug}
 {$endif finaldestdebug}
   cpuinfo,cpubase,cgutils,daopt386,
   cpuinfo,cpubase,cgutils,daopt386,
-  cgx86;
+  cgx86,
+  aoptx86;
 
 
 
 
 function isFoldableArithOp(hp1: taicpu; reg: tregister): boolean;
 function isFoldableArithOp(hp1: taicpu; reg: tregister): boolean;
@@ -122,7 +123,7 @@ begin
        (taicpu(hp1).opcode = A_FILD))) and
        (taicpu(hp1).opcode = A_FILD))) and
      (taicpu(hp1).oper[0]^.typ = top_ref) and
      (taicpu(hp1).oper[0]^.typ = top_ref) and
      (taicpu(hp1).opsize = taicpu(p).opsize) and
      (taicpu(hp1).opsize = taicpu(p).opsize) and
-     refsEqual(taicpu(p).oper[0]^.ref^, taicpu(hp1).oper[0]^.ref^) then
+     RefsEqual(taicpu(p).oper[0]^.ref^, taicpu(hp1).oper[0]^.ref^) then
     begin
     begin
       { replacing fstp f;fld f by fst f is only valid for extended because of rounding }
       { replacing fstp f;fld f by fst f is only valid for extended because of rounding }
       if (taicpu(p).opsize=S_FX) and
       if (taicpu(p).opsize=S_FX) and

+ 150 - 0
compiler/x86/aoptx86.pas

@@ -0,0 +1,150 @@
+{
+    Copyright (c) 1998-2002 by Florian Klaempfl and Jonas Maebe
+
+    This unit contains the peephole optimizer.
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit aoptx86;
+
+{$i fpcdefs.inc}
+
+{ $define DEBUG_AOPTCPU}
+
+  interface
+
+    uses
+      globtype,
+      cpubase,
+      aasmtai,
+      cgbase,cgutils;
+
+    function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
+    function MatchInstruction(const instr: tai; const op1,op2: TAsmOp; const opsize: topsizes): boolean;
+    function MatchInstruction(const instr: tai; const op1,op2,op3: TAsmOp; const opsize: topsizes): boolean;
+
+    function MatchOperand(const oper: TOper; const reg: TRegister): boolean; inline;
+    function MatchOperand(const oper: TOper; const a: tcgint): boolean; inline;
+
+    function RefsEqual(const r1, r2: treference): boolean;
+
+    function MatchReference(const ref : treference;base,index : TRegister) : Boolean;
+
+    function MatchOpType(const instr : tai;ot0,ot1 : toptype) : Boolean;
+
+  implementation
+
+    uses
+      verbose,
+      aasmcpu;
+
+    function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
+      begin
+        result :=
+          (instr.typ = ait_instruction) and
+          (taicpu(instr).opcode = op) and
+          ((opsize = []) or (taicpu(instr).opsize in opsize));
+      end;
+
+
+    function MatchInstruction(const instr: tai; const op1,op2: TAsmOp; const opsize: topsizes): boolean;
+      begin
+        result :=
+          (instr.typ = ait_instruction) and
+          ((taicpu(instr).opcode = op1) or
+           (taicpu(instr).opcode = op2)
+          ) and
+          ((opsize = []) or (taicpu(instr).opsize in opsize));
+      end;
+
+
+    function MatchInstruction(const instr: tai; const op1,op2,op3: TAsmOp; const opsize: topsizes): boolean;
+      begin
+        result :=
+          (instr.typ = ait_instruction) and
+          ((taicpu(instr).opcode = op1) or
+           (taicpu(instr).opcode = op2) or
+           (taicpu(instr).opcode = op3)
+          ) and
+          ((opsize = []) or (taicpu(instr).opsize in opsize));
+      end;
+
+
+    function MatchOperand(const oper: TOper; const reg: TRegister): boolean; inline;
+      begin
+        result := (oper.typ = top_reg) and (oper.reg = reg);
+      end;
+
+
+    function MatchOperand(const oper: TOper; const a: tcgint): boolean; inline;
+      begin
+        result := (oper.typ = top_const) and (oper.val = a);
+      end;
+
+
+    function MatchOperand(const oper1: TOper; const oper2: TOper): boolean; inline;
+      begin
+        result := oper1.typ = oper2.typ;
+
+        if result then
+          case oper1.typ of
+            top_const:
+              Result:=oper1.val = oper2.val;
+            top_reg:
+              Result:=oper1.reg = oper2.reg;
+            top_ref:
+              Result:=RefsEqual(oper1.ref^, oper2.ref^);
+            else
+              internalerror(2013102801);
+          end
+      end;
+
+
+    function RefsEqual(const r1, r2: treference): boolean;
+      begin
+        RefsEqual :=
+          (r1.offset = r2.offset) and
+          (r1.segment = r2.segment) and (r1.base = r2.base) and
+          (r1.index = r2.index) and (r1.scalefactor = r2.scalefactor) and
+          (r1.symbol=r2.symbol) and (r1.refaddr = r2.refaddr) and
+          (r1.relsymbol = r2.relsymbol);
+      end;
+
+
+    function MatchReference(const ref : treference;base,index : TRegister) : Boolean;
+      begin
+       Result:=(ref.offset=0) and
+         (ref.scalefactor in [0,1]) and
+         (ref.segment=NR_NO) and
+         (ref.symbol=nil) and
+         (ref.relsymbol=nil) and
+         ((base=NR_INVALID) or
+          (ref.base=base)) and
+         ((index=NR_INVALID) or
+          (ref.index=index));
+      end;
+
+
+    function MatchOpType(const instr : tai;ot0,ot1 : toptype) : Boolean;
+      begin
+        Result:=(taicpu(instr).ops=2) and
+          (taicpu(instr).oper[0]^.typ=ot0) and
+          (taicpu(instr).oper[1]^.typ=ot1);
+      end;
+
+end.
+

+ 1 - 87
compiler/x86_64/aoptcpu.pas

@@ -43,6 +43,7 @@ uses
   cgbase, cgutils,
   cgbase, cgutils,
   aoptobj,
   aoptobj,
   aasmbase, aasmdata, aasmcpu,
   aasmbase, aasmdata, aasmcpu,
+  aoptx86,
   itcpugas;
   itcpugas;
 
 
 function isFoldableArithOp(hp1: taicpu; reg: tregister): boolean;
 function isFoldableArithOp(hp1: taicpu; reg: tregister): boolean;
@@ -64,93 +65,6 @@ begin
 end;
 end;
 
 
 
 
-function MatchInstruction(const instr: tai; const op: TAsmOp; const opsize: topsizes): boolean;
-  begin
-    result :=
-      (instr.typ = ait_instruction) and
-      (taicpu(instr).opcode = op) and
-      ((opsize = []) or (taicpu(instr).opsize in opsize));
-  end;
-
-
-function MatchInstruction(const instr: tai; const op1,op2: TAsmOp; const opsize: topsizes): boolean;
-  begin
-    result :=
-      (instr.typ = ait_instruction) and
-      ((taicpu(instr).opcode = op1) or
-       (taicpu(instr).opcode = op2)
-      ) and
-      ((opsize = []) or (taicpu(instr).opsize in opsize));
-  end;
-
-
-function MatchInstruction(const instr: tai; const op1,op2,op3: TAsmOp; const opsize: topsizes): boolean;
-  begin
-    result :=
-      (instr.typ = ait_instruction) and
-      ((taicpu(instr).opcode = op1) or
-       (taicpu(instr).opcode = op2) or
-       (taicpu(instr).opcode = op3)
-      ) and
-      ((opsize = []) or (taicpu(instr).opsize in opsize));
-  end;
-
-
-function MatchOperand(const oper: TOper; const reg: TRegister): boolean; inline;
-  begin
-    result := (oper.typ = top_reg) and (oper.reg = reg);
-  end;
-
-
-function MatchOperand(const oper: TOper; const a: tcgint): boolean; inline;
-  begin
-    result := (oper.typ = top_const) and (oper.val = a);
-  end;
-
-function refsequal(const r1, r2: treference): boolean;
-  begin
-    refsequal :=
-      (r1.offset = r2.offset) and
-      (r1.segment = r2.segment) and (r1.base = r2.base) and
-      (r1.index = r2.index) and (r1.scalefactor = r2.scalefactor) and
-      (r1.symbol=r2.symbol) and (r1.refaddr = r2.refaddr) and
-      (r1.relsymbol = r2.relsymbol);
-  end;
-
-
-function MatchOperand(const oper1: TOper; const oper2: TOper): boolean; inline;
-  begin
-    result := oper1.typ = oper2.typ;
-
-    if result then
-      case oper1.typ of
-        top_const:
-          Result:=oper1.val = oper2.val;
-        top_reg:
-          Result:=oper1.reg = oper2.reg;
-        top_ref:
-          Result:=RefsEqual(oper1.ref^, oper2.ref^);
-        else
-          internalerror(2013102801);
-      end
-  end;
-
-
-function MatchReference(const ref : treference;base,index : TRegister) : Boolean;
-  begin
-   Result:=(ref.offset=0) and
-     (ref.scalefactor in [0,1]) and
-     (ref.segment=NR_NO) and
-     (ref.symbol=nil) and
-     (ref.relsymbol=nil) and
-     ((base=NR_INVALID) or
-      (ref.base=base)) and
-     ((index=NR_INVALID) or
-      (ref.index=index));
-  end;
-
-
-
 function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
 function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
 var
 var
   hp1, hp2: tai;
   hp1, hp2: tai;