Browse Source

* cpu-specific overrides of optimizer methods now get called
+ first simple rlwinm optimization for ppc

git-svn-id: trunk@1320 -

Jonas Maebe 20 years ago
parent
commit
ab3bc45fa4
5 changed files with 76 additions and 11 deletions
  1. 1 3
      compiler/aopt.pas
  2. 1 1
      compiler/aoptbase.pas
  3. 14 5
      compiler/aoptobj.pas
  4. 3 1
      compiler/arm/aoptcpu.pas
  5. 57 1
      compiler/powerpc/aoptcpu.pas

+ 1 - 3
compiler/aopt.pas

@@ -35,7 +35,7 @@ Unit aopt;
       TAsmOptimizer = class(TAoptObj)
 
         { _AsmL is the PAasmOutpout list that has to be optimized }
-        Constructor create(_AsmL: taasmoutput);
+        Constructor create(_AsmL: taasmoutput); virtual;
 
         { call the necessary optimizer procedures }
         Procedure Optimize;
@@ -262,6 +262,4 @@ Unit aopt;
       end;
 
 
-begin
-  casmoptimizer:=TAsmOptimizer;
 end.

+ 1 - 1
compiler/aoptbase.pas

@@ -44,7 +44,7 @@ unit aoptbase;
       TAoptBase = class
         { processor independent methods }
 
-        constructor create;
+        constructor create; virtual;
         destructor destroy;override;
         { returns true if register Reg is used by instruction p1 }
         Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;

+ 14 - 5
compiler/aoptobj.pas

@@ -249,7 +249,7 @@ Unit AoptObj;
         { that has to be optimized and _LabelInfo a pointer to a       }
         { TLabelInfo record                                            }
         Constructor create(_AsmL: TAasmOutput; _BlockStart, _BlockEnd: Tai;
-                           _LabelInfo: PLabelInfo);
+                           _LabelInfo: PLabelInfo); virtual;
 
         { processor independent methods }
 
@@ -290,12 +290,14 @@ Unit AoptObj;
         function getlabelwithsym(sym: tasmlabel): tai;
 
         { peephole optimizer }
-        procedure PrePeepHoleOpts;virtual;
-        procedure PeepHoleOptPass1;virtual;
-        procedure PeepHoleOptPass2;virtual;
-        procedure PostPeepHoleOpts;virtual;
+        procedure PrePeepHoleOpts;
+        procedure PeepHoleOptPass1;
+        procedure PeepHoleOptPass2;
+        procedure PostPeepHoleOpts;
 
         { processor dependent methods }
+        // if it returns true, perform a "continue"
+        function PeepHoleOptPass1Cpu(var p: tai): boolean; virtual;
       End;
 
        Function ArrayRefsEq(const r1, r2: TReference): Boolean;
@@ -997,6 +999,8 @@ Unit AoptObj;
         while (p <> BlockEnd) Do
           begin
             //!!!! UpDateUsedRegs(UsedRegs, tai(p.next));
+            if PeepHoleOptPass1Cpu(p) then
+              continue;
             case p.Typ Of
               ait_instruction:
                 begin
@@ -1094,4 +1098,9 @@ Unit AoptObj;
       end;
 
 
+    function TAOptObj.PeepHoleOptPass1Cpu(var p: tai): boolean;
+      begin
+        result := false;
+      end;
+
 End.

+ 3 - 1
compiler/arm/aoptcpu.pas

@@ -31,10 +31,12 @@ Interface
 uses cpubase, aoptobj, aoptcpub;
 
 Type
-  TAOptCpu = class(TAoptObj)
+  TCpuAsmOptimizer = class(TAsmOptimizer)
     { uses the same constructor as TAopObj }
   End;
 
 Implementation
 
+begin
+  casmoptimizer:=TCpuAsmOptimizer;
 End.

+ 57 - 1
compiler/powerpc/aoptcpu.pas

@@ -28,15 +28,71 @@ Interface
 
 {$i fpcdefs.inc}
 
-uses cpubase, aoptobj, aoptcpub, aopt;
+uses cpubase, aoptobj, aoptcpub, aopt, aasmtai;
 
 Type
   TCpuAsmOptimizer = class(TAsmOptimizer)
     { uses the same constructor as TAopObj }
+    function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
   End;
 
 Implementation
 
+  uses
+    cutils, aasmcpu;
+
+  function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
+    var
+      next1, next2: tai;
+      l1, l2: longint;
+    begin
+      result := false;
+      case p.typ of
+        ait_instruction:
+          begin
+            case taicpu(p).opcode of
+              A_RLWINM:
+                begin
+                  if getnextinstruction(p,next1) and
+                     (next1.typ = ait_instruction) and
+                     (taicpu(next1).opcode = A_RLWINM) and
+                     (taicpu(next1).oper[0]^.reg = taicpu(p).oper[0]^.reg) and
+                     // both source and target of next1 must equal target of p
+                     (taicpu(next1).oper[1]^.reg = taicpu(p).oper[0]^.reg) and
+                     (taicpu(next1).oper[2]^.val = 0) then
+                    begin
+                      l1 := taicpu(p).oper[4]^.val;
+                      if (l1 < taicpu(p).oper[3]^.val) then
+                        inc(l1,32);
+                      l2 := taicpu(next1).oper[4]^.val;
+                      if (l2 < taicpu(next1).oper[3]^.val) then
+                        inc(l2,32);
+
+                      if (taicpu(p).oper[3]^.val > l2) or
+                         (taicpu(next1).oper[3]^.val > l1) then
+                        begin
+                          // masks have no bits in common
+                          taicpu(p).opcode := A_LI;
+                          taicpu(p).loadconst(1,0);
+                          taicpu(p).clearop(2);
+                          taicpu(p).clearop(3);
+                          taicpu(p).clearop(4);
+                        end
+                      else
+                        begin
+                          taicpu(p).oper[3]^.val := max(taicpu(p).oper[3]^.val,taicpu(next1).oper[3]^.val);
+                          taicpu(p).oper[4]^.val := min(taicpu(p).oper[4]^.val,taicpu(next1).oper[4]^.val);
+                        end;
+                      asml.remove(next1);
+                      next1.free;
+                    end;
+                end;
+            end;
+          end;
+      end;
+    end;
+
 begin
   casmoptimizer:=TCpuAsmOptimizer;
 End.
+