mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-05 16:49:26 +01:00
* basics for generic register usage information
git-svn-id: trunk@20886 -
This commit is contained in:
parent
3d366bca44
commit
2a6a4831ea
@ -91,11 +91,12 @@ unit aoptbase;
|
|||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function labelCanBeSkipped(p: tai_label): boolean;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
globtype,globals, aoptcpub;
|
globtype,globals,aoptcpub;
|
||||||
|
|
||||||
constructor taoptbase.create;
|
constructor taoptbase.create;
|
||||||
begin
|
begin
|
||||||
@ -148,11 +149,13 @@ unit aoptbase;
|
|||||||
Result:=true;
|
Result:=true;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
|
||||||
function labelCanBeSkipped(p: tai_label): boolean;
|
function labelCanBeSkipped(p: tai_label): boolean;
|
||||||
begin
|
begin
|
||||||
labelCanBeSkipped := not(p.labsym.is_used) or (p.labsym.labeltype<>alt_jump);
|
labelCanBeSkipped := not(p.labsym.is_used) or (p.labsym.labeltype<>alt_jump);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
Function TAOptBase.GetNextInstruction(Current: tai; Var Next: tai): Boolean;
|
Function TAOptBase.GetNextInstruction(Current: tai; Var Next: tai): Boolean;
|
||||||
Begin
|
Begin
|
||||||
Repeat
|
Repeat
|
||||||
|
|||||||
@ -59,28 +59,34 @@ Unit AoptObj;
|
|||||||
TRefCompare = Function(const r1, r2: TReference): Boolean;
|
TRefCompare = Function(const r1, r2: TReference): Boolean;
|
||||||
//!!! FIXME
|
//!!! FIXME
|
||||||
TRegArray = Array[byte] of tsuperregister;
|
TRegArray = Array[byte] of tsuperregister;
|
||||||
|
|
||||||
|
|
||||||
TRegSet = Set of byte;
|
TRegSet = Set of byte;
|
||||||
{ possible actions on an operand: read, write or modify (= read & write) }
|
{ possible actions on an operand: read, write or modify (= read & write) }
|
||||||
TOpAction = (OpAct_Read, OpAct_Write, OpAct_Modify, OpAct_Unknown);
|
TOpAction = (OpAct_Read, OpAct_Write, OpAct_Modify, OpAct_Unknown);
|
||||||
|
|
||||||
{ ************************************************************************* }
|
{ ************************************************************************* }
|
||||||
{ * Object to hold information on which regiters are in use and which not * }
|
{ * Object to hold information on which regiters are in use and which not * }
|
||||||
{ ************************************************************************* }
|
{ ************************************************************************* }
|
||||||
|
|
||||||
|
{ TUsedRegs }
|
||||||
|
|
||||||
TUsedRegs = class
|
TUsedRegs = class
|
||||||
Constructor create;
|
Constructor create(aTyp : TRegisterType);
|
||||||
Constructor create_regset(Const _RegSet: TRegSet);
|
Constructor create_regset(aTyp : TRegisterType;Const _RegSet: TRegSet);
|
||||||
|
|
||||||
Destructor Destroy;override;
|
Destructor Destroy;override;
|
||||||
{ update the info with the pairegalloc objects coming after }
|
|
||||||
{ p }
|
Procedure Clear;
|
||||||
|
{ update the info with the pairegalloc objects coming after
|
||||||
|
p }
|
||||||
Procedure Update(p: Tai);
|
Procedure Update(p: Tai);
|
||||||
{ is Reg currently in use }
|
{ is Reg currently in use }
|
||||||
Function IsUsed(Reg: TRegister): Boolean;
|
Function IsUsed(Reg: TRegister): Boolean;
|
||||||
{ get all the currently used registers }
|
{ get all the currently used registers }
|
||||||
Function GetUsedRegs: TRegSet;
|
Function GetUsedRegs: TRegSet;
|
||||||
|
|
||||||
Private
|
Private
|
||||||
|
Typ : TRegisterType;
|
||||||
UsedRegs: TRegSet;
|
UsedRegs: TRegSet;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
@ -120,10 +126,10 @@ Unit AoptObj;
|
|||||||
{ gets one of these assigned: a pointer to it is stored in the OptInfo field }
|
{ gets one of these assigned: a pointer to it is stored in the OptInfo field }
|
||||||
{ ************************************************************************** }
|
{ ************************************************************************** }
|
||||||
|
|
||||||
|
{ TPaiProp }
|
||||||
|
|
||||||
TPaiProp = class(TAoptBaseCpu)
|
TPaiProp = class(TAoptBaseCpu)
|
||||||
Regs: TRegContent;
|
Regs: TRegContent;
|
||||||
{ info about allocation of general purpose integer registers }
|
|
||||||
UsedRegs: TUsedRegs;
|
|
||||||
{ can this instruction be removed? }
|
{ can this instruction be removed? }
|
||||||
CanBeRemoved: Boolean;
|
CanBeRemoved: Boolean;
|
||||||
|
|
||||||
@ -227,6 +233,8 @@ Unit AoptObj;
|
|||||||
{ ********** General optimizer object, used to derive others from ********* }
|
{ ********** General optimizer object, used to derive others from ********* }
|
||||||
{ ************************************************************************* }
|
{ ************************************************************************* }
|
||||||
|
|
||||||
|
{ TAOptObj }
|
||||||
|
|
||||||
TAOptObj = class(TAoptBaseCpu)
|
TAOptObj = class(TAoptBaseCpu)
|
||||||
{ the PAasmOutput list this optimizer instance works on }
|
{ the PAasmOutput list this optimizer instance works on }
|
||||||
AsmL: TAsmList;
|
AsmL: TAsmList;
|
||||||
@ -240,15 +248,22 @@ Unit AoptObj;
|
|||||||
BlockStart, BlockEnd: Tai;
|
BlockStart, BlockEnd: Tai;
|
||||||
|
|
||||||
DFA: TAOptDFA;
|
DFA: TAOptDFA;
|
||||||
|
|
||||||
|
UsedRegs: array[TRegisterType] of TUsedRegs;
|
||||||
|
|
||||||
{ _AsmL is the PAasmOutpout list that has to be optimized, }
|
{ _AsmL is the PAasmOutpout list that has to be optimized, }
|
||||||
{ _BlockStart and _BlockEnd the start and the end of the block }
|
{ _BlockStart and _BlockEnd the start and the end of the block }
|
||||||
{ that has to be optimized and _LabelInfo a pointer to a }
|
{ that has to be optimized and _LabelInfo a pointer to a }
|
||||||
{ TLabelInfo record }
|
{ TLabelInfo record }
|
||||||
Constructor create(_AsmL: TAsmList; _BlockStart, _BlockEnd: Tai;
|
Constructor create(_AsmL: TAsmList; _BlockStart, _BlockEnd: Tai;
|
||||||
_LabelInfo: PLabelInfo); virtual; reintroduce;
|
_LabelInfo: PLabelInfo); virtual; reintroduce;
|
||||||
|
Destructor Destroy;override;
|
||||||
|
|
||||||
{ processor independent methods }
|
{ processor independent methods }
|
||||||
|
|
||||||
|
Procedure ClearUsedRegs;
|
||||||
|
Procedure UpdateUsedRegs(p : Tai);
|
||||||
|
|
||||||
{ returns true if the label L is found between hp and the next }
|
{ returns true if the label L is found between hp and the next }
|
||||||
{ instruction }
|
{ instruction }
|
||||||
Function FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
|
Function FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
|
||||||
@ -312,57 +327,76 @@ Unit AoptObj;
|
|||||||
{ ******************************** TUsedRegs ****************************** }
|
{ ******************************** TUsedRegs ****************************** }
|
||||||
{ ************************************************************************* }
|
{ ************************************************************************* }
|
||||||
|
|
||||||
Constructor TUsedRegs.create;
|
Constructor TUsedRegs.create(aTyp : TRegisterType);
|
||||||
Begin
|
Begin
|
||||||
|
Typ:=aTyp;
|
||||||
UsedRegs := [];
|
UsedRegs := [];
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Constructor TUsedRegs.create_regset(Const _RegSet: TRegSet);
|
|
||||||
|
Constructor TUsedRegs.create_regset(aTyp : TRegisterType;Const _RegSet: TRegSet);
|
||||||
Begin
|
Begin
|
||||||
|
Typ:=aTyp;
|
||||||
UsedRegs := _RegSet;
|
UsedRegs := _RegSet;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Procedure TUsedRegs.Update(p: Tai);
|
|
||||||
{updates UsedRegs with the RegAlloc Information coming after P}
|
{
|
||||||
|
updates UsedRegs with the RegAlloc Information coming after P
|
||||||
|
}
|
||||||
|
Procedure TUsedRegs.Update(p: Tai);
|
||||||
Begin
|
Begin
|
||||||
Repeat
|
repeat
|
||||||
While Assigned(p) And
|
while assigned(p) and
|
||||||
((p.typ in (SkipInstr - [ait_RegAlloc])) or
|
((p.typ in (SkipInstr - [ait_RegAlloc])) or
|
||||||
((p.typ = ait_label) And
|
((p.typ = ait_label) and
|
||||||
Not(Tai_Label(p).labsym.is_used))) Do
|
labelCanBeSkipped(tai_label(p))) or
|
||||||
p := Tai(p.next);
|
((p.typ = ait_marker) and
|
||||||
While Assigned(p) And
|
(tai_Marker(p).Kind in [mark_AsmBlockEnd,mark_NoLineInfoStart,mark_NoLineInfoEnd]))) do
|
||||||
|
p := tai(p.next);
|
||||||
|
while assigned(p) and
|
||||||
(p.typ=ait_RegAlloc) Do
|
(p.typ=ait_RegAlloc) Do
|
||||||
Begin
|
begin
|
||||||
{!!!!!!!! FIXME
|
if (getregtype(tai_regalloc(p).reg) = typ) then
|
||||||
if tai_regalloc(p).ratype=ra_alloc then
|
begin
|
||||||
UsedRegs := UsedRegs + [tai_regalloc(p).Reg]
|
case tai_regalloc(p).ratype of
|
||||||
else
|
ra_alloc :
|
||||||
UsedRegs := UsedRegs - [tai_regalloc(p).Reg];
|
Include(UsedRegs, getsupreg(tai_regalloc(p).reg));
|
||||||
p := Tai(p.next);
|
ra_dealloc :
|
||||||
}
|
Exclude(UsedRegs, getsupreg(tai_regalloc(p).reg));
|
||||||
End;
|
end;
|
||||||
Until Not(Assigned(p)) Or
|
end;
|
||||||
(Not(p.typ in SkipInstr) And
|
p := tai(p.next);
|
||||||
Not((p.typ = ait_label) And
|
end;
|
||||||
Not(Tai_Label(p).labsym.is_used)));
|
until not(assigned(p)) or
|
||||||
|
(not(p.typ in SkipInstr) and
|
||||||
|
not((p.typ = ait_label) and
|
||||||
|
labelCanBeSkipped(tai_label(p))));
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function TUsedRegs.IsUsed(Reg: TRegister): Boolean;
|
|
||||||
|
Function TUsedRegs.IsUsed(Reg: TRegister): Boolean;
|
||||||
Begin
|
Begin
|
||||||
//!!!!!!!!!!! IsUsed := Reg in UsedRegs
|
IsUsed := (getregtype(Reg)=Typ) and (getsupreg(Reg) in UsedRegs);
|
||||||
Result:=False; { unimplemented }
|
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function TUsedRegs.GetUsedRegs: TRegSet;
|
|
||||||
|
Function TUsedRegs.GetUsedRegs: TRegSet;
|
||||||
Begin
|
Begin
|
||||||
GetUsedRegs := UsedRegs;
|
GetUsedRegs := UsedRegs;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Destructor TUsedRegs.Destroy;
|
|
||||||
Begin
|
Destructor TUsedRegs.Destroy;
|
||||||
inherited destroy;
|
Begin
|
||||||
end;
|
inherited destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TUsedRegs.Clear;
|
||||||
|
begin
|
||||||
|
UsedRegs := [];
|
||||||
|
end;
|
||||||
|
|
||||||
{ ************************************************************************* }
|
{ ************************************************************************* }
|
||||||
{ **************************** TPaiProp *********************************** }
|
{ **************************** TPaiProp *********************************** }
|
||||||
@ -377,6 +411,7 @@ Unit AoptObj;
|
|||||||
{ DirFlag: TFlagContents; I386 specific}
|
{ DirFlag: TFlagContents; I386 specific}
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
|
||||||
Function TPaiProp.RegInSequence(Reg, which: TRegister): Boolean;
|
Function TPaiProp.RegInSequence(Reg, which: TRegister): Boolean;
|
||||||
{
|
{
|
||||||
Var p: Tai;
|
Var p: Tai;
|
||||||
@ -736,13 +771,45 @@ Unit AoptObj;
|
|||||||
|
|
||||||
Constructor TAoptObj.create(_AsmL: TAsmList; _BlockStart, _BlockEnd: Tai;
|
Constructor TAoptObj.create(_AsmL: TAsmList; _BlockStart, _BlockEnd: Tai;
|
||||||
_LabelInfo: PLabelInfo);
|
_LabelInfo: PLabelInfo);
|
||||||
|
var
|
||||||
|
i : TRegisterType;
|
||||||
Begin
|
Begin
|
||||||
AsmL := _AsmL;
|
AsmL := _AsmL;
|
||||||
BlockStart := _BlockStart;
|
BlockStart := _BlockStart;
|
||||||
BlockEnd := _BlockEnd;
|
BlockEnd := _BlockEnd;
|
||||||
LabelInfo := _LabelInfo
|
LabelInfo := _LabelInfo;
|
||||||
|
for i:=low(TRegisterType) to high(TRegisterType) do
|
||||||
|
UsedRegs[i]:=TUsedRegs.Create(i);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
destructor TAOptObj.Destroy;
|
||||||
|
var
|
||||||
|
i : TRegisterType;
|
||||||
|
begin
|
||||||
|
for i:=low(TRegisterType) to high(TRegisterType) do
|
||||||
|
UsedRegs[i].Destroy;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TAOptObj.ClearUsedRegs;
|
||||||
|
var
|
||||||
|
i : TRegisterType;
|
||||||
|
begin
|
||||||
|
for i:=low(TRegisterType) to high(TRegisterType) do
|
||||||
|
UsedRegs[i].Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TAOptObj.UpdateUsedRegs(p : Tai);
|
||||||
|
var
|
||||||
|
i : TRegisterType;
|
||||||
|
begin
|
||||||
|
for i:=low(TRegisterType) to high(TRegisterType) do
|
||||||
|
UsedRegs[i].Update(p);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
Function TAOptObj.FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
|
Function TAOptObj.FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
|
||||||
Var TempP: Tai;
|
Var TempP: Tai;
|
||||||
Begin
|
Begin
|
||||||
@ -1008,10 +1075,10 @@ Unit AoptObj;
|
|||||||
p,hp1,hp2 : tai;
|
p,hp1,hp2 : tai;
|
||||||
begin
|
begin
|
||||||
p := BlockStart;
|
p := BlockStart;
|
||||||
//!!!! UsedRegs := [];
|
ClearUsedRegs;
|
||||||
while (p <> BlockEnd) Do
|
while (p <> BlockEnd) Do
|
||||||
begin
|
begin
|
||||||
//!!!! UpDateUsedRegs(UsedRegs, tai(p.next));
|
UpdateUsedRegs(tai(p.next));
|
||||||
if PeepHoleOptPass1Cpu(p) then
|
if PeepHoleOptPass1Cpu(p) then
|
||||||
continue;
|
continue;
|
||||||
case p.Typ Of
|
case p.Typ Of
|
||||||
@ -1116,7 +1183,7 @@ Unit AoptObj;
|
|||||||
end; { if is_jmp }
|
end; { if is_jmp }
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
//!!!!!!!! updateUsedRegs(UsedRegs,p);
|
UpdateUsedRegs(p);
|
||||||
p:=tai(p.next);
|
p:=tai(p.next);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1132,13 +1199,13 @@ Unit AoptObj;
|
|||||||
p: tai;
|
p: tai;
|
||||||
begin
|
begin
|
||||||
p := BlockStart;
|
p := BlockStart;
|
||||||
//!!!! UsedRegs := [];
|
ClearUsedRegs;
|
||||||
while (p <> BlockEnd) Do
|
while (p <> BlockEnd) Do
|
||||||
begin
|
begin
|
||||||
//!!!! UpDateUsedRegs(UsedRegs, tai(p.next));
|
UpdateUsedRegs(tai(p.next));
|
||||||
if PostPeepHoleOptsCpu(p) then
|
if PostPeepHoleOptsCpu(p) then
|
||||||
continue;
|
continue;
|
||||||
//!!!!!!!! updateUsedRegs(UsedRegs,p);
|
UpdateUsedRegs(p);
|
||||||
p:=tai(p.next);
|
p:=tai(p.next);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user