Просмотр исходного кода

+ x86: LeaLea2Lea optimization

git-svn-id: trunk@43177 -
florian 5 лет назад
Родитель
Сommit
00c2fd4005
1 измененных файлов с 42 добавлено и 0 удалено
  1. 42 0
      compiler/x86/aoptx86.pas

+ 42 - 0
compiler/x86/aoptx86.pas

@@ -39,6 +39,7 @@ unit aoptx86;
         function RegLoadedWithNewValue(reg : tregister; hp : tai) : boolean; override;
         function InstructionLoadsFromReg(const reg : TRegister; const hp : tai) : boolean; override;
         function RegReadByInstruction(reg : TRegister; hp : tai) : boolean;
+        function GetNextInstructionUsingReg(Current: tai; out Next: tai; reg: TRegister): Boolean;
       protected
         { checks whether loading a new value in reg1 overwrites the entirety of reg2 }
         function Reg1WriteOverwritesReg2Entirely(reg1, reg2: tregister): boolean;
@@ -274,6 +275,19 @@ unit aoptx86;
       end;
 
 
+  function TX86AsmOptimizer.GetNextInstructionUsingReg(Current: tai; out Next: tai; reg: TRegister): Boolean;
+    begin
+      Next:=Current;
+      repeat
+        Result:=GetNextInstruction(Next,Next);
+      until not (Result) or
+            not(cs_opt_level3 in current_settings.optimizerswitches) or
+            (Next.typ<>ait_instruction) or
+            RegInInstruction(reg,Next) or
+            is_calljmp(taicpu(Next).opcode);
+    end;
+
+
   function TX86AsmOptimizer.InstructionLoadsFromReg(const reg: TRegister;const hp: tai): boolean;
     begin
       Result:=RegReadByInstruction(reg,hp);
@@ -2181,6 +2195,34 @@ unit aoptx86;
                 result:=true;
               end;
           end;
+        { changes
+            lea offset1(regX), reg1
+            lea offset2(reg1), reg1
+            to
+            lea offset1+offset2(regX), reg1 }
+        if GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[1]^.reg) and
+          MatchInstruction(hp1,A_LEA,[S_L]) and
+          MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[1]^) and
+          (taicpu(hp1).oper[0]^.ref^.base=taicpu(p).oper[1]^.reg) and
+          (taicpu(p).oper[0]^.ref^.index=NR_NO) and
+          (taicpu(p).oper[0]^.ref^.relsymbol=nil) and
+          (taicpu(p).oper[0]^.ref^.scalefactor in [0,1]) and
+          (taicpu(p).oper[0]^.ref^.segment=NR_NO) and
+          (taicpu(p).oper[0]^.ref^.symbol=nil) and
+          (taicpu(p).oper[0]^.ref^.index=taicpu(hp1).oper[0]^.ref^.index) and
+          (taicpu(p).oper[0]^.ref^.relsymbol=taicpu(hp1).oper[0]^.ref^.relsymbol) and
+          (taicpu(p).oper[0]^.ref^.scalefactor=taicpu(hp1).oper[0]^.ref^.scalefactor) and
+          (taicpu(p).oper[0]^.ref^.segment=taicpu(hp1).oper[0]^.ref^.segment) and
+          (taicpu(p).oper[0]^.ref^.symbol=taicpu(hp1).oper[0]^.ref^.symbol) then
+          begin
+            DebugMsg(SPeepholeOptimization + 'LeaLea2Lea done',p);
+            inc(taicpu(hp1).oper[0]^.ref^.offset,taicpu(p).oper[0]^.ref^.offset);
+            taicpu(hp1).oper[0]^.ref^.base:=taicpu(p).oper[0]^.ref^.base;
+            asml.Remove(p);
+            p.Free;
+            p:=hp1;
+            result:=true;
+          end;
       end;