Browse Source

* cleaned up scheduler code, created own scheduler class to avoid unneeded passes through the assembler

git-svn-id: trunk@22133 -
florian 13 years ago
parent
commit
2a14394cf5
2 changed files with 77 additions and 18 deletions
  1. 65 3
      compiler/aopt.pas
  2. 12 15
      compiler/arm/aoptcpu.pas

+ 65 - 3
compiler/aopt.pas

@@ -49,9 +49,18 @@ Unit aopt;
       End;
       TAsmOptimizerClass = class of TAsmOptimizer;
 
+      TAsmScheduler = class(TAoptObj)
+        { _AsmL is the PAasmOutpout list that has to be re-scheduled }
+        Constructor Create(_AsmL: TAsmList); virtual; reintroduce;
+        Procedure Optimize;
+        function SchedulerPass1Cpu(var p: tai): boolean; virtual; abstract;
+        procedure SchedulerPass1;
+      end;
+      TAsmSchedulerClass = class of TAsmScheduler;
+
     var
       casmoptimizer : TAsmOptimizerClass;
-      cpreregallocscheduler : TAsmOptimizerClass;
+      cpreregallocscheduler : TAsmSchedulerClass;
 
     procedure Optimize(AsmL:TAsmList);
     procedure PreRegallocSchedule(AsmL:TAsmList);
@@ -69,7 +78,7 @@ Unit aopt;
     Constructor TAsmOptimizer.create(_AsmL: TAsmList);
       Begin
         inherited create(_asml,nil,nil,nil);
-      {setup labeltable, always necessary}
+        { setup labeltable, always necessary }
         New(LabelInfo);
       End;
 
@@ -303,6 +312,59 @@ Unit aopt;
       End;
 
 
+    constructor TAsmScheduler.Create(_AsmL: TAsmList);
+      begin
+        inherited create(_asml,nil,nil,nil);
+      end;
+
+
+    procedure TAsmScheduler.SchedulerPass1;
+      var
+        p,hp1,hp2 : tai;
+      begin
+        p:=BlockStart;
+        while p<>BlockEnd Do
+          begin
+            if SchedulerPass1Cpu(p) then
+              continue;
+            p:=tai(p.next);
+          end;
+      end;
+
+
+    procedure TAsmScheduler.Optimize;
+      Var
+        HP: tai;
+        pass: longint;
+      Begin
+        pass:=0;
+        BlockStart := tai(AsmL.First);
+        While Assigned(BlockStart) Do
+          Begin
+            { Peephole optimizations }
+            SchedulerPass1;
+            { continue where we left off, BlockEnd is either the start of an }
+            { assembler block or nil}
+            BlockStart:=BlockEnd;
+            While Assigned(BlockStart) And
+                  (BlockStart.typ = ait_Marker) And
+                  (tai_Marker(BlockStart).Kind = mark_AsmBlockStart) Do
+              Begin
+                { we stopped at an assembler block, so skip it    }
+                While GetNextInstruction(BlockStart, BlockStart) And
+                      ((BlockStart.Typ <> Ait_Marker) Or
+                       (tai_Marker(Blockstart).Kind <> mark_AsmBlockEnd)) Do;
+                { blockstart now contains a tai_marker(mark_AsmBlockEnd) }
+                If not(GetNextInstruction(BlockStart, HP) And
+                   ((HP.typ <> ait_Marker) Or
+                    (Tai_Marker(HP).Kind <> mark_AsmBlockStart))) Then
+                  { skip the next assembler block }
+                  blockStart := hp;
+              End
+          End;
+      End;
+
+
     procedure Optimize(AsmL:TAsmList);
       var
         p : TAsmOptimizer;
@@ -315,7 +377,7 @@ Unit aopt;
 
     procedure PreRegallocSchedule(AsmL:TAsmList);
       var
-        p : TAsmOptimizer;
+        p : TAsmScheduler;
       begin
         p:=cpreregallocscheduler.Create(AsmL);
         p.Optimize;

+ 12 - 15
compiler/arm/aoptcpu.pas

@@ -25,16 +25,13 @@ Unit aoptcpu;
 
 {$i fpcdefs.inc}
 
-{ $define DEBUG_PREREGSCHEDULER}
+{$define DEBUG_PREREGSCHEDULER}
 
 Interface
 
 uses cgbase, cpubase, aasmtai, aasmcpu,aopt, aoptcpub, aoptobj;
 
 Type
-
-  { TCpuAsmOptimizer }
-
   TCpuAsmOptimizer = class(TAsmOptimizer)
     { uses the same constructor as TAopObj }
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
@@ -45,10 +42,8 @@ Type
                                      var AllUsedRegs: TAllUsedRegs): Boolean;
   End;
 
-  { TCpuPreRegallocScheduler }
-
-  TCpuPreRegallocScheduler = class(TAsmOptimizer)
-    function PeepHoleOptPass1Cpu(var p: tai): boolean;override;
+  TCpuPreRegallocScheduler = class(TAsmScheduler)
+    function SchedulerPass1Cpu(var p: tai): boolean;override;
     procedure SwapRegLive(p, hp1: taicpu);
   end;
 
@@ -1198,7 +1193,8 @@ Implementation
     end;
 
 
-  function TCpuPreRegallocScheduler.PeepHoleOptPass1Cpu(var p: tai): boolean;
+  function TCpuPreRegallocScheduler.SchedulerPass1Cpu(var p: tai): boolean;
+
   { TODO : schedule also forward }
   { TODO : schedule distance > 1 }
     var
@@ -1206,9 +1202,10 @@ Implementation
       list : TAsmList;
     begin
       result:=true;
+
       list:=TAsmList.Create;
-      p := BlockStart;
-      while (p <> BlockEnd) Do
+      p:=BlockStart;
+      while p<>BlockEnd Do
         begin
           if (p.typ=ait_instruction) and
             GetNextInstruction(p,hp1) and
@@ -1270,7 +1267,7 @@ Implementation
                       list.Concat(hp4);
                     end
                   else
-                  hp3:=tai(hp3.Previous);
+                    hp3:=tai(hp3.Previous);
                 end;
 
               list.Concat(p);
@@ -1288,7 +1285,7 @@ Implementation
                       list.Concat(hp4);
                     end
                   else
-                  hp5:=tai(hp5.Next);
+                    hp5:=tai(hp5.Next);
                 end;
 
               asml.Remove(hp1);
@@ -1297,12 +1294,12 @@ Implementation
 {$endif DEBUG_PREREGSCHEDULER}
               asml.InsertBefore(hp1,hp2);
               asml.InsertListBefore(hp2,list);
-              p := tai(p.next)
+              p:=tai(p.next)
             end
           else if p.typ=ait_instruction then
             p:=hp1
           else
-            p := tai(p.next);
+            p:=tai(p.next);
         end;
       list.Free;
     end;