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