Browse Source

* FoldLea optimizes more cases

git-svn-id: trunk@35251 -
florian 8 years ago
parent
commit
ebb2b81f79
1 changed files with 25 additions and 5 deletions
  1. 25 5
      compiler/x86/aoptx86.pas

+ 25 - 5
compiler/x86/aoptx86.pas

@@ -68,6 +68,10 @@ unit aoptx86;
 
 
     function MatchReference(const ref : treference;base,index : TRegister) : Boolean;
     function MatchReference(const ref : treference;base,index : TRegister) : Boolean;
 
 
+    { returns true, if ref is a reference using only the registers passed as base and index
+      and having an offset }
+    function MatchReferenceWithOffset(const ref : treference;base,index : TRegister) : Boolean;
+
     function MatchOpType(const instr : tai;ot0,ot1 : toptype) : Boolean;
     function MatchOpType(const instr : tai;ot0,ot1 : toptype) : Boolean;
 
 
   implementation
   implementation
@@ -185,6 +189,19 @@ unit aoptx86;
       end;
       end;
 
 
 
 
+    function MatchReferenceWithOffset(const ref : treference;base,index : TRegister) : Boolean;
+      begin
+       Result:=(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;
     function MatchOpType(const instr : tai;ot0,ot1 : toptype) : Boolean;
       begin
       begin
         Result:=(taicpu(instr).ops=2) and
         Result:=(taicpu(instr).ops=2) and
@@ -1102,18 +1119,19 @@ unit aoptx86;
            ((taicpu(hp1).opcode=A_LEA) and
            ((taicpu(hp1).opcode=A_LEA) and
              GetNextInstruction(hp1,hp2) and
              GetNextInstruction(hp1,hp2) and
              MatchInstruction(hp2,A_MOV,[]) and
              MatchInstruction(hp2,A_MOV,[]) 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
             ((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)
              (taicpu(hp1).oper[0]^.ref^.index<>taicpu(p).oper[1]^.reg)
               ) or
               ) or
              (MatchReference(taicpu(hp1).oper[0]^.ref^,NR_INVALID,
              (MatchReference(taicpu(hp1).oper[0]^.ref^,NR_INVALID,
               taicpu(p).oper[1]^.reg) and
               taicpu(p).oper[1]^.reg) and
-             (taicpu(hp1).oper[0]^.ref^.base<>taicpu(p).oper[1]^.reg))
+             (taicpu(hp1).oper[0]^.ref^.base<>taicpu(p).oper[1]^.reg)) or
+             (MatchReferenceWithOffset(taicpu(hp1).oper[0]^.ref^,taicpu(p).oper[1]^.reg,NR_NO)) or
+             (MatchReferenceWithOffset(taicpu(hp1).oper[0]^.ref^,NR_NO,taicpu(p).oper[1]^.reg))
             ) and
             ) and
             ((MatchOperand(taicpu(p).oper[1]^,taicpu(hp2).oper[0]^)) or not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp1,UsedRegs)))
             ((MatchOperand(taicpu(p).oper[1]^,taicpu(hp2).oper[0]^)) or not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp1,UsedRegs)))
            )
            )
           ) and
           ) and
-          MatchOperand(taicpu(p).oper[1]^,taicpu(hp2).oper[0]^) and
+          MatchOperand(taicpu(hp1).oper[taicpu(hp1).ops-1]^,taicpu(hp2).oper[0]^) and
           (taicpu(hp2).oper[1]^.typ = top_ref) then
           (taicpu(hp2).oper[1]^.typ = top_ref) then
           begin
           begin
             CopyUsedRegs(TmpUsedRegs);
             CopyUsedRegs(TmpUsedRegs);
@@ -1132,10 +1150,12 @@ unit aoptx86;
                   A_LEA :
                   A_LEA :
                     begin
                     begin
                       taicpu(hp1).opcode:=A_ADD;
                       taicpu(hp1).opcode:=A_ADD;
-                      if taicpu(hp1).oper[0]^.ref^.index<>taicpu(p).oper[1]^.reg then
+                      if (taicpu(hp1).oper[0]^.ref^.index<>taicpu(p).oper[1]^.reg) and (taicpu(hp1).oper[0]^.ref^.index<>NR_NO) then
                         taicpu(hp1).loadreg(0,taicpu(hp1).oper[0]^.ref^.index)
                         taicpu(hp1).loadreg(0,taicpu(hp1).oper[0]^.ref^.index)
+                      else if (taicpu(hp1).oper[0]^.ref^.base<>taicpu(p).oper[1]^.reg) and (taicpu(hp1).oper[0]^.ref^.base<>NR_NO) then
+                        taicpu(hp1).loadreg(0,taicpu(hp1).oper[0]^.ref^.base)
                       else
                       else
-                        taicpu(hp1).loadreg(0,taicpu(hp1).oper[0]^.ref^.base);
+                        taicpu(hp1).loadconst(0,taicpu(hp1).oper[0]^.ref^.offset);
                       taicpu(hp1).loadRef(1,taicpu(p).oper[0]^.ref^);
                       taicpu(hp1).loadRef(1,taicpu(p).oper[0]^.ref^);
                       DebugMsg('Peephole FoldLea done',hp1);
                       DebugMsg('Peephole FoldLea done',hp1);
                     end
                     end