Sfoglia il codice sorgente

+ MIPS: started the peephole optimizer.

git-svn-id: trunk@25148 -
sergei 12 anni fa
parent
commit
8e6d4b41e2
1 ha cambiato i file con 166 aggiunte e 1 eliminazioni
  1. 166 1
      compiler/mips/aoptcpu.pas

+ 166 - 1
compiler/mips/aoptcpu.pas

@@ -28,14 +28,179 @@ unit aoptcpu;
   Interface
   Interface
 
 
     uses
     uses
-      cpubase, aoptobj, aoptcpub, aopt;
+      cgbase, cpubase, aoptobj, aoptcpub, aopt, aasmtai;
 
 
     Type
     Type
       TCpuAsmOptimizer = class(TAsmOptimizer)
       TCpuAsmOptimizer = class(TAsmOptimizer)
+        function TryRemoveMov(var p: tai): boolean;
+        function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
       End;
       End;
 
 
   Implementation
   Implementation
 
 
+     uses
+       aasmcpu;
+
+
+  function MatchInstruction(const instr: tai; const op: TAsmOp): boolean;
+    begin
+      result :=
+        (instr.typ = ait_instruction) and
+        (taicpu(instr).opcode = op);
+    end;
+
+
+  function MatchOperand(const oper: TOper; reg: TRegister): boolean;
+    begin
+      result:=(oper.typ=top_reg) and (oper.reg=reg);
+    end;
+
+
+  function IsSameReg(this,next: taicpu): boolean;
+    begin
+      result:=(next.oper[0]^.typ=top_reg) and
+        (next.oper[1]^.typ=top_reg) and
+        (next.oper[0]^.reg=next.oper[1]^.reg) and
+        (next.oper[0]^.reg=this.oper[0]^.reg);
+    end;
+
+
+  function TCpuAsmOptimizer.TryRemoveMov(var p: tai): boolean;
+    var
+      next,hp1: tai;
+      alloc,dealloc: tai_regalloc;
+    begin
+      { Fold
+          op   $reg1,...
+          move $reg2,$reg1
+          dealloc $reg1
+        into
+          op   $reg2,...
+      }
+      result:=false;
+      if GetNextInstruction(p,next) and
+         MatchInstruction(next,A_MOVE) and
+         MatchOperand(taicpu(next).oper[1]^,taicpu(p).oper[0]^.reg) then
+        begin
+          dealloc:=FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.Next));
+          if assigned(dealloc) then
+            begin
+              { taicpu(p).oper[0]^.reg is not used anymore, try to find its allocation
+                and remove it if possible }
+              GetLastInstruction(p,hp1);
+
+              asml.Remove(dealloc);
+              alloc:=FindRegAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next));
+              if assigned(alloc) then
+                begin
+                  asml.Remove(alloc);
+                  alloc.free;
+                  dealloc.free;
+                end
+              else
+                asml.InsertAfter(dealloc,p);
+
+              { try to move the allocation of the target register }
+              GetLastInstruction(next,hp1);
+              alloc:=FindRegAlloc(taicpu(next).oper[0]^.reg,tai(hp1.Next));
+              if assigned(alloc) then
+                begin
+                  asml.Remove(alloc);
+                  asml.InsertBefore(alloc,p);
+                  { adjust used regs }
+                  IncludeRegInUsedRegs(taicpu(next).oper[0]^.reg,UsedRegs);
+                end;
+
+              { finally get rid of the mov }
+              taicpu(p).loadreg(0,taicpu(next).oper[0]^.reg);
+              asml.remove(next);
+              next.free;
+            end;
+        end;
+    end;
+
+
+  function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
+    var
+      next,next2: tai;
+    begin
+      result:=false;
+      case p.typ of
+        ait_instruction:
+          begin
+            case taicpu(p).opcode of
+              A_SRL:
+                begin
+                  { Remove 'andi' in sequences
+                      srl   Rx,Ry,16
+                      andi  Rx,Rx,65535
+
+                      srl   Rx,Ry,24
+                      andi  Rx,Rx,255
+                    since 'srl' clears all relevant upper bits }
+                  if (taicpu(p).oper[2]^.typ=top_const) and
+                    GetNextInstruction(p,next) and
+                    MatchInstruction(next,A_ANDI) and
+                    IsSameReg(taicpu(p),taicpu(next)) and
+                    (taicpu(next).oper[2]^.typ=top_const) and
+                    ((
+                      (taicpu(p).oper[2]^.val>=16) and
+                      (taicpu(next).oper[2]^.val=65535)
+                    ) or (
+                      (taicpu(p).oper[2]^.val>=24) and
+                      (taicpu(next).oper[2]^.val=255)
+                    )) then
+                    begin
+                      asml.remove(next);
+                      next.free;
+                    end
+                  else
+                    TryRemoveMov(p);
+                end;
+
+              A_ANDI:
+                begin
+                  { Remove sign extension after 'andi' if bit 7/15 of const operand is clear }
+                  if (taicpu(p).oper[2]^.typ=top_const) and
+                    GetNextInstruction(p,next) and
+                    MatchInstruction(next,A_SLL) and
+                    GetNextInstruction(next,next2) and
+                    MatchInstruction(next2,A_SRA) and
+                    IsSameReg(taicpu(p),taicpu(next)) and
+                    IsSameReg(taicpu(p),taicpu(next2)) and
+                    (taicpu(next).oper[2]^.typ=top_const) and
+                    (taicpu(next2).oper[2]^.typ=top_const) and
+                    (taicpu(next).oper[2]^.val=taicpu(next2).oper[2]^.val) and
+                    ((
+                      (taicpu(p).oper[2]^.val<=$7fff) and
+                      (taicpu(next).oper[2]^.val=16)
+                    ) or (
+                      (taicpu(p).oper[2]^.val<=$7f) and
+                      (taicpu(next).oper[2]^.val=24)
+                    )) then
+                    begin
+                      asml.remove(next);
+                      asml.remove(next2);
+                      next.free;
+                      next2.free;
+                    end
+                  else
+                    TryRemoveMov(p);
+                end;
+
+              A_ADD,A_ADDU,
+              A_ADDI,A_ADDIU,
+              A_SUB,A_SUBU,
+              A_SRA,A_SRAV,
+              A_SRLV,
+              A_SLL,A_SLLV,
+              A_AND,A_OR,A_XOR,A_ORI,A_XORI:
+                TryRemoveMov(p);
+            end;
+          end;
+      end;
+    end;
+
 begin
 begin
   casmoptimizer:=TCpuAsmOptimizer;
   casmoptimizer:=TCpuAsmOptimizer;
 end.
 end.