Browse Source

* (slight modified) patch by J. Gareth Moreton to reduce number of assembler optimizer passes, resolves #37959

git-svn-id: trunk@47146 -
florian 4 years ago
parent
commit
91a6223281
2 changed files with 20 additions and 14 deletions
  1. 1 13
      compiler/aopt.pas
  2. 19 1
      compiler/aoptobj.pas

+ 1 - 13
compiler/aopt.pas

@@ -273,28 +273,16 @@ Unit aopt;
     Procedure TAsmOptimizer.Optimize;
     Procedure TAsmOptimizer.Optimize;
       Var
       Var
         HP: tai;
         HP: tai;
-        pass: longint;
       Begin
       Begin
-        pass:=0;
         BlockStart := tai(AsmL.First);
         BlockStart := tai(AsmL.First);
         pass_1;
         pass_1;
         While Assigned(BlockStart) Do
         While Assigned(BlockStart) Do
           Begin
           Begin
             if (cs_opt_peephole in current_settings.optimizerswitches) then
             if (cs_opt_peephole in current_settings.optimizerswitches) then
               begin
               begin
-                if pass = 0 then
-                  PrePeepHoleOpts;
-                { Peephole optimizations }
+                PrePeepHoleOpts;
                 PeepHoleOptPass1;
                 PeepHoleOptPass1;
-                { Only perform them twice in the first pass }
-                if pass = 0 then
-                  PeepHoleOptPass1;
-              end;
-            { more peephole optimizations }
-            if (cs_opt_peephole in current_settings.optimizerswitches) then
-              begin
                 PeepHoleOptPass2;
                 PeepHoleOptPass2;
-                { if pass = last_pass then }
                 PostPeepHoleOpts;
                 PostPeepHoleOpts;
               end;
               end;
             { free memory }
             { free memory }

+ 19 - 1
compiler/aoptobj.pas

@@ -2464,13 +2464,28 @@ Unit AoptObj;
 
 
 
 
     procedure TAOptObj.PeepHoleOptPass1;
     procedure TAOptObj.PeepHoleOptPass1;
+      const
+        MaxPasses: array[1..4] of Cardinal = (1, 2, 8, 8);
       var
       var
         p : tai;
         p : tai;
         stoploop, FirstInstruction, JumpOptsAvailable: boolean;
         stoploop, FirstInstruction, JumpOptsAvailable: boolean;
+        PassCount, MaxCount: Cardinal;
       begin
       begin
         JumpOptsAvailable := CanDoJumpOpts();
         JumpOptsAvailable := CanDoJumpOpts();
 
 
         StartPoint := BlockStart;
         StartPoint := BlockStart;
+        PassCount := 0;
+
+        { Determine the maximum number of passes allowed based on the compiler switches }
+        if (cs_opt_level4 in current_settings.optimizerswitches) then
+          { it should never take more than 8 passes, but the limit is finite to protect against faulty optimisations }
+          MaxCount := MaxPasses[4]
+        else if (cs_opt_level3 in current_settings.optimizerswitches) then
+          MaxCount := MaxPasses[3]
+        else if (cs_opt_level2 in current_settings.optimizerswitches) then
+          MaxCount := MaxPasses[2] { The original double run of Pass 1 }
+        else
+          MaxCount := MaxPasses[1];
 
 
         repeat
         repeat
           stoploop:=true;
           stoploop:=true;
@@ -2523,7 +2538,10 @@ Unit AoptObj;
                 p := tai(UpdateUsedRegsAndOptimize(p).Next);
                 p := tai(UpdateUsedRegsAndOptimize(p).Next);
 
 
             end;
             end;
-        until stoploop or not(cs_opt_level3 in current_settings.optimizerswitches);
+
+          Inc(PassCount);
+
+        until stoploop or (PassCount >= MaxCount);
       end;
       end;