diff --git a/compiler/aopt.pas b/compiler/aopt.pas index e0366d420d..66af1a6f7e 100644 --- a/compiler/aopt.pas +++ b/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; diff --git a/compiler/arm/aoptcpu.pas b/compiler/arm/aoptcpu.pas index c383b05a87..57c22eb96e 100644 --- a/compiler/arm/aoptcpu.pas +++ b/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;