浏览代码

* x86: Refactoring register update code in "OptPass2ADD" and "OptPass2SUB"

J. Gareth "Curious Kit" Moreton 5 月之前
父节点
当前提交
f85aa24ad0
共有 1 个文件被更改,包括 69 次插入58 次删除
  1. 69 58
      compiler/x86/aoptx86.pas

+ 69 - 58
compiler/x86/aoptx86.pas

@@ -15564,6 +15564,7 @@ unit aoptx86;
         NewRef: TReference;
         Distance: Cardinal;
         TempTracking: TAllUsedRegs;
+        DoAddMov2Lea: Boolean;
 
         { This entire nested function is used in an if-statement below, but we
           want to avoid all the used reg transfers and GetNextInstruction calls
@@ -15573,10 +15574,11 @@ unit aoptx86;
             hp2: tai;
           begin
             TransferUsedRegs(TmpUsedRegs);
-            hp2 := p;
-            repeat
-              UpdateUsedRegs(TmpUsedRegs, tai(hp2.Next));
-            until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1);
+            if (cs_opt_level3 in current_settings.optimizerswitches) then
+              UpdateUsedRegsBetween(TmpUsedRegs, p, hp1)
+            else
+              { p and hp1 will be adjacent }
+              UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
 
             Result := not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs);
           end;
@@ -15625,11 +15627,13 @@ unit aoptx86;
               begin
                 { Update the register tracking to the MOV instruction }
                 CopyUsedRegs(TempTracking);
-                hp2 := p;
-                repeat
-                  UpdateUsedRegs(tai(hp2.Next));
-                until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1);
+                if (cs_opt_level3 in current_settings.optimizerswitches) then
+                  UpdateUsedRegsBetween(UsedRegs, p, hp1)
+                else
+                  { p and hp1 will be adjacent }
+                  UpdateUsedRegs(UsedRegs, tai(p.Next));
 
+                hp2 := hp1;
                 { if hp1 <> hp2 after the call, then hp1 got removed, so let
                   OptPass2ADD get called again }
                 if OptPass2MOV(hp1) and (hp1 <> hp2) then
@@ -15750,18 +15754,22 @@ unit aoptx86;
               ) then
               begin
                 TransferUsedRegs(TmpUsedRegs);
-                hp2 := p;
-                repeat
-                  UpdateUsedRegs(TmpUsedRegs, tai(hp2.Next));
-                until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1);
+                if (cs_opt_level3 in current_settings.optimizerswitches) then
+                  UpdateUsedRegsBetween(TmpUsedRegs, p, hp1)
+                else
+                  { p and hp1 will be adjacent }
+                  UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
 
                 if (
+                    SetAndTest(
+                      (
+                        not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) and
+                        not RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)
+                      ),
+                      DoAddMov2Lea
+                    ) or
                     { Don't do AddMov2LeaAdd under -Os, but do allow AddMov2Lea }
-                    not (cs_opt_size in current_settings.optimizerswitches) or
-                    (
-                      not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) and
-                      not RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)
-                    )
+                    not (cs_opt_size in current_settings.optimizerswitches)
                   ) then
                   begin
                     { Change the MOV instruction to a LEA instruction, and update the
@@ -15775,8 +15783,18 @@ unit aoptx86;
                     taicpu(hp1).opcode := A_LEA;
                     taicpu(hp1).loadref(0, NewRef);
 
-                    if RegUsedAfterInstruction(NewRef.base, hp1, TmpUsedRegs) or
-                      RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs) then
+                    if DoAddMov2Lea then
+                      begin
+                        { Since %reg1 or the flags aren't used afterwards, we can delete p completely }
+                        DebugMsg(SPeepholeOptimization + 'AddMov2Lea', hp1);
+
+                        if (cs_opt_level3 in current_settings.optimizerswitches) then
+                          { hp1 may not be the immediate next instruction under -O3 }
+                          RemoveCurrentp(p)
+                        else
+                          RemoveCurrentp(p, hp1);
+                      end
+                    else
                       begin
                         hp2 := tai(hp1.Next); { for the benefit of AllocRegBetween }
 
@@ -15787,17 +15805,6 @@ unit aoptx86;
 
                         DebugMsg(SPeepholeOptimization + 'AddMov2LeaAdd', p);
                         p := hp1;
-                      end
-                    else
-                      begin
-                        { Since %reg1 or the flags aren't used afterwards, we can delete p completely }
-                        DebugMsg(SPeepholeOptimization + 'AddMov2Lea', hp1);
-
-                        if (cs_opt_level3 in current_settings.optimizerswitches) then
-                          { hp1 may not be the immediate next instruction under -O3 }
-                          RemoveCurrentp(p)
-                        else
-                          RemoveCurrentp(p, hp1);
                       end;
 
                     Result := True;
@@ -15923,6 +15930,7 @@ unit aoptx86;
         NewRef: TReference;
         Distance: Cardinal;
         TempTracking: TAllUsedRegs;
+        DoSubMov2Lea: Boolean;
 
       begin
         Result := False;
@@ -15968,11 +15976,13 @@ unit aoptx86;
               begin
                 { Update the register tracking to the MOV instruction }
                 CopyUsedRegs(TempTracking);
-                hp2 := p;
-                repeat
-                  UpdateUsedRegs(tai(hp2.Next));
-                until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1);
+                if (cs_opt_level3 in current_settings.optimizerswitches) then
+                  UpdateUsedRegsBetween(UsedRegs, p, hp1)
+                else
+                  { p and hp1 will be adjacent }
+                  UpdateUsedRegs(UsedRegs, tai(p.Next));
 
+                hp2 := hp1;
                 { if hp1 <> hp2 after the call, then hp1 got removed, so let
                   OptPass2SUB get called again }
                 if OptPass2MOV(hp1) and (hp1 <> hp2) then
@@ -16023,18 +16033,22 @@ unit aoptx86;
               ) then
               begin
                 TransferUsedRegs(TmpUsedRegs);
-                hp2 := p;
-                repeat
-                  UpdateUsedRegs(TmpUsedRegs, tai(hp2.Next));
-                until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1);
+                if (cs_opt_level3 in current_settings.optimizerswitches) then
+                  UpdateUsedRegsBetween(TmpUsedRegs, p, hp1)
+                else
+                  { p and hp1 will be adjacent }
+                  UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
 
                 if (
+                    SetAndTest(
+                      (
+                        not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) and
+                        not RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)
+                      ),
+                      DoSubMov2Lea
+                    ) or
                     { Don't do SubMov2LeaSub under -Os, but do allow SubMov2Lea }
-                    not (cs_opt_size in current_settings.optimizerswitches) or
-                    (
-                      not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) and
-                      not RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)
-                    )
+                    not (cs_opt_size in current_settings.optimizerswitches)
                   ) then
                   begin
                     { Change the MOV instruction to a LEA instruction, and update the
@@ -16047,10 +16061,18 @@ unit aoptx86;
                     taicpu(hp1).opcode := A_LEA;
                     taicpu(hp1).loadref(0, NewRef);
 
-                    TransferUsedRegs(TmpUsedRegs);
-                    UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
-                    if RegUsedAfterInstruction(NewRef.base, hp1, TmpUsedRegs) or
-                      RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs) then
+                    if DoSubMov2Lea then
+                      begin
+                        { Since %reg1 or the flags aren't used afterwards, we can delete p completely }
+                        DebugMsg(SPeepholeOptimization + 'SubMov2Lea', hp1);
+
+                        if (cs_opt_level3 in current_settings.optimizerswitches) then
+                          { hp1 may not be the immediate next instruction under -O3 }
+                          RemoveCurrentp(p)
+                        else
+                          RemoveCurrentp(p, hp1);
+                      end
+                    else
                       begin
                         hp2 := tai(hp1.Next); { for the benefit of AllocRegBetween }
 
@@ -16061,17 +16083,6 @@ unit aoptx86;
 
                         DebugMsg(SPeepholeOptimization + 'SubMov2LeaSub', p);
                         p := hp1;
-                      end
-                    else
-                      begin
-                        { Since %reg1 or the flags aren't used afterwards, we can delete p completely }
-                        DebugMsg(SPeepholeOptimization + 'SubMov2Lea', hp1);
-
-                        if (cs_opt_level3 in current_settings.optimizerswitches) then
-                          { hp1 may not be the immediate next instruction under -O3 }
-                          RemoveCurrentp(p)
-                        else
-                          RemoveCurrentp(p, hp1);
                       end;
 
                     Result := True;