mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-26 17:50:54 +02:00
* cleaned up scheduler code, created own scheduler class to avoid unneeded passes through the assembler
git-svn-id: trunk@22133 -
This commit is contained in:
parent
a3bf956c33
commit
2a14394cf5
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user