mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-18 15:59:45 +02:00
* Speed optimisations for peephole register tracking functions
This commit is contained in:
parent
05d6e20acc
commit
3882066f23
@ -85,7 +85,7 @@ Unit AoptObj;
|
||||
p }
|
||||
procedure Update(p: Tai; IgnoreNewAllocs: Boolean=false);
|
||||
{ is Reg currently in use }
|
||||
Function IsUsed(Reg: TRegister): Boolean;
|
||||
Function IsUsed(Reg: TRegister): Boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
{ get all the currently used registers }
|
||||
Function GetUsedRegs: TRegSet; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
|
||||
@ -271,7 +271,7 @@ Unit AoptObj;
|
||||
|
||||
Procedure CreateUsedRegs(var regs: TAllUsedRegs);
|
||||
Procedure ClearUsedRegs;
|
||||
Procedure UpdateUsedRegs(p : Tai);
|
||||
Procedure UpdateUsedRegs(p : Tai); {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
class procedure UpdateUsedRegs(var Regs: TAllUsedRegs; p: Tai); static;
|
||||
|
||||
{ UpdateUsedRegsBetween updates the given TUsedRegs from p1 to p2 exclusive, calling GetNextInstruction
|
||||
@ -287,9 +287,9 @@ Unit AoptObj;
|
||||
procedure RestoreUsedRegs(const Regs : TAllUsedRegs);
|
||||
procedure TransferUsedRegs(var dest: TAllUsedRegs);
|
||||
class procedure ReleaseUsedRegs(const regs : TAllUsedRegs); static;
|
||||
class function RegInUsedRegs(reg : TRegister;regs : TAllUsedRegs) : boolean; static;
|
||||
class procedure IncludeRegInUsedRegs(reg : TRegister;var regs : TAllUsedRegs); static;
|
||||
class procedure ExcludeRegFromUsedRegs(reg: TRegister;var regs : TAllUsedRegs); static;
|
||||
class function RegInUsedRegs(reg : TRegister;var regs : TAllUsedRegs) : boolean; static;
|
||||
class procedure IncludeRegInUsedRegs(reg : TRegister;var regs : TAllUsedRegs); static; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
class procedure ExcludeRegFromUsedRegs(reg: TRegister;var regs : TAllUsedRegs); static; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
|
||||
class function GetAllocationString(const regs : TAllUsedRegs) : string; static;
|
||||
|
||||
@ -433,8 +433,14 @@ Unit AoptObj;
|
||||
protected
|
||||
{ Set to True if this is the second time that Pass 1 is being run }
|
||||
NotFirstIteration: Boolean;
|
||||
|
||||
{ Actually updates a used register }
|
||||
class procedure UpdateReg(var Regs : TAllUsedRegs; p: tai_regalloc); static; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
private
|
||||
procedure DebugMsg(const s: string; p: tai);
|
||||
|
||||
{ Utilty function for the UpdateUsedRegs family of methods }
|
||||
class function GetNextRegUpdatePoint(var p : Tai; pTerm: tai): Boolean; static;
|
||||
End;
|
||||
|
||||
Function ArrayRefsEq(const r1, r2: TReference): Boolean;
|
||||
@ -547,7 +553,7 @@ Unit AoptObj;
|
||||
End;
|
||||
|
||||
|
||||
Function TUsedRegs.IsUsed(Reg: TRegister): Boolean;
|
||||
Function TUsedRegs.IsUsed(Reg: TRegister): Boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
Begin
|
||||
IsUsed := (getregtype(Reg)=Typ) and (getsupreg(Reg) in UsedRegs);
|
||||
End;
|
||||
@ -1080,30 +1086,57 @@ Unit AoptObj;
|
||||
end;
|
||||
|
||||
|
||||
procedure TAOptObj.UpdateUsedRegs(p : Tai);
|
||||
procedure TAOptObj.UpdateUsedRegs(p : Tai); {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
begin
|
||||
UpdateUsedRegs(UsedRegs, p);
|
||||
end;
|
||||
|
||||
|
||||
class function TAOptObj.GetNextRegUpdatePoint(var p : Tai; pTerm: tai): Boolean;
|
||||
begin
|
||||
Result := False; { Needed to suppress compiler warning }
|
||||
while SetAndTest(Assigned(p) and (p <> pTerm), Result) and
|
||||
((p.typ in (SkipInstr - [ait_RegAlloc])) or
|
||||
((p.typ = ait_label) and
|
||||
labelCanBeSkipped(tai_label(p))) or
|
||||
((p.typ = ait_marker) and
|
||||
(tai_Marker(p).Kind in [mark_AsmBlockEnd,mark_NoLineInfoStart,mark_NoLineInfoEnd])) or
|
||||
(
|
||||
Assigned(pTerm) and { Causes p to stop on any live label or instruction if pTerm is nil }
|
||||
(p.typ in [ait_label, ait_instruction])
|
||||
)
|
||||
) do
|
||||
p := tai(p.next);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
class procedure TAOptObj.UpdateReg(var Regs : TAllUsedRegs; p: tai_regalloc);
|
||||
begin
|
||||
case tai_regalloc(p).ratype of
|
||||
ra_alloc :
|
||||
Include(Regs[getregtype(tai_regalloc(p).reg)].UsedRegs, getsupreg(tai_regalloc(p).reg));
|
||||
ra_dealloc :
|
||||
Exclude(Regs[getregtype(tai_regalloc(p).reg)].UsedRegs, getsupreg(tai_regalloc(p).reg));
|
||||
else
|
||||
;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
class procedure TAOptObj.UpdateUsedRegs(var Regs : TAllUsedRegs;p : Tai);
|
||||
begin
|
||||
{ this code is based on TUsedRegs.Update to avoid multiple passes through the asmlist,
|
||||
the code is duplicated here }
|
||||
repeat
|
||||
while assigned(p) and
|
||||
((p.typ in (SkipInstr - [ait_RegAlloc])) or
|
||||
((p.typ = ait_label) and
|
||||
labelCanBeSkipped(tai_label(p))) or
|
||||
((p.typ = ait_marker) and
|
||||
(tai_Marker(p).Kind in [mark_AsmBlockEnd,mark_NoLineInfoStart,mark_NoLineInfoEnd]))) do
|
||||
p := tai(p.next);
|
||||
if not GetNextRegUpdatePoint(p, nil) then
|
||||
Exit;
|
||||
|
||||
while assigned(p) and
|
||||
(p.typ=ait_RegAlloc) Do
|
||||
begin
|
||||
prefetch(pointer(p.Next)^);
|
||||
case tai_regalloc(p).ratype of
|
||||
ra_alloc :
|
||||
Include(UsedRegs[getregtype(tai_regalloc(p).reg)].UsedRegs, getsupreg(tai_regalloc(p).reg));
|
||||
ra_dealloc :
|
||||
Exclude(UsedRegs[getregtype(tai_regalloc(p).reg)].UsedRegs, getsupreg(tai_regalloc(p).reg));
|
||||
else
|
||||
;
|
||||
end;
|
||||
UpdateReg(Regs, tai_regalloc(p));
|
||||
p := tai(p.next);
|
||||
end;
|
||||
until not(assigned(p)) or
|
||||
@ -1113,27 +1146,34 @@ Unit AoptObj;
|
||||
end;
|
||||
|
||||
|
||||
class procedure TAOptObj.UpdateUsedRegs(var Regs : TAllUsedRegs;p : Tai);
|
||||
var
|
||||
i : TRegisterType;
|
||||
class procedure TAOptObj.UpdateUsedRegsBetween(var Regs: TAllUsedRegs; p1, p2: Tai);
|
||||
begin
|
||||
for i:=low(TRegisterType) to high(TRegisterType) do
|
||||
Regs[i].Update(p);
|
||||
end;
|
||||
{ this code is based on TUsedRegs.Update to avoid multiple passes through the asmlist,
|
||||
the code is duplicated here }
|
||||
repeat
|
||||
if not GetNextRegUpdatePoint(p1, p2) then
|
||||
Exit;
|
||||
|
||||
while assigned(p1) and (p1 <> p2) and
|
||||
(p1.typ=ait_RegAlloc) Do
|
||||
begin
|
||||
prefetch(pointer(p1.Next)^);
|
||||
UpdateReg(Regs, tai_regalloc(p1));
|
||||
p1 := tai(p1.next);
|
||||
end;
|
||||
|
||||
class procedure TAOptObj.UpdateUsedRegsBetween(var Regs: TAllUsedRegs; p1, p2: Tai); static;
|
||||
var
|
||||
i : TRegisterType;
|
||||
begin
|
||||
while (p1 <> p2) do
|
||||
begin
|
||||
for i:=low(TRegisterType) to high(TRegisterType) do
|
||||
Regs[i].Update(tai(p1.Next));
|
||||
{ Only stop if either p2 or a terminating marker is reached }
|
||||
until not Assigned(p1) or (p1 = p2) or
|
||||
not (p1.typ in (SkipInstr + [ait_label, ait_instruction])) or
|
||||
(
|
||||
(p1.typ = ait_marker) and
|
||||
not (tai_Marker(p1).Kind in [mark_AsmBlockEnd,mark_NoLineInfoStart,mark_NoLineInfoEnd])
|
||||
);
|
||||
|
||||
if (p1 <> p2) then
|
||||
{ Reached the end of the procedure or a terminating marker that wasn't p2 }
|
||||
InternalError(2022010701);
|
||||
|
||||
if not GetNextInstruction(p1, p1) then
|
||||
InternalError(2022010701);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
@ -1180,21 +1220,21 @@ Unit AoptObj;
|
||||
end;
|
||||
|
||||
|
||||
class Function TAOptObj.RegInUsedRegs(reg : TRegister;regs : TAllUsedRegs) : boolean;
|
||||
class Function TAOptObj.RegInUsedRegs(reg : TRegister; var regs : TAllUsedRegs) : boolean;
|
||||
begin
|
||||
result:=regs[getregtype(reg)].IsUsed(reg);
|
||||
end;
|
||||
|
||||
|
||||
class procedure TAOptObj.IncludeRegInUsedRegs(reg: TRegister;
|
||||
var regs: TAllUsedRegs);
|
||||
var regs: TAllUsedRegs); {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
begin
|
||||
include(regs[getregtype(reg)].UsedRegs,getsupreg(Reg));
|
||||
end;
|
||||
|
||||
|
||||
class procedure TAOptObj.ExcludeRegFromUsedRegs(reg: TRegister;
|
||||
var regs: TAllUsedRegs);
|
||||
var regs: TAllUsedRegs); {$ifdef USEINLINE}inline;{$endif USEINLINE}
|
||||
begin
|
||||
exclude(regs[getregtype(reg)].UsedRegs,getsupreg(Reg));
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user