* basics for generic register usage information

git-svn-id: trunk@20886 -
This commit is contained in:
florian 2012-04-15 14:20:47 +00:00
parent 3d366bca44
commit 2a6a4831ea
2 changed files with 118 additions and 48 deletions

View File

@ -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

View File

@ -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;