* fixes some issues with reg. allocation information

git-svn-id: trunk@21303 -
This commit is contained in:
florian 2012-05-15 18:06:41 +00:00
parent 08784aca44
commit 748694a325
4 changed files with 117 additions and 27 deletions

View File

@ -61,6 +61,7 @@ Unit aopt;
uses
globtype, globals,
verbose,
cgbase,
aoptda,aoptcpu,aoptcpud;
Constructor TAsmOptimizer.create(_AsmL: TAsmList);
@ -110,11 +111,11 @@ Unit aopt;
Procedure TAsmOptimizer.BuildLabelTableAndFixRegAlloc;
{ Builds a table with the locations of the labels in the TAsmList. }
{ Also fixes some RegDeallocs like "# %eax released; push (%eax)" }
Var p{, hp1, hp2}: tai;
{UsedRegs: TRegSet;}
Var p,hp1, hp2: tai;
Regs: TAllUsedRegs;
LabelIdx : longint;
Begin
{UsedRegs := [];}
CreateUsedRegs(Regs);
With LabelInfo^ Do
If (LabelDif <> 0) Then
Begin
@ -137,13 +138,17 @@ Unit aopt;
end;
ait_regAlloc:
begin
{!!!!!!!!!
if tai_regalloc(p).ratype=ra_alloc then
Begin
If Not(tai_regalloc(p).Reg in UsedRegs) Then
UsedRegs := UsedRegs + [tai_regalloc(p).Reg]
If Not(RegInUsedRegs(tai_regalloc(p).Reg,Regs)) Then
IncludeRegInUsedRegs(tai_regalloc(p).Reg,Regs)
Else
Begin
hp1 := tai(p.previous);
AsmL.remove(p);
p.free;
p := hp1;
{ not sure if this is useful, it even skips previous deallocs of the register (FK)
hp1 := p;
hp2 := nil;
While GetLastInstruction(hp1, hp1) And
@ -154,11 +159,12 @@ Unit aopt;
hp1:=tai_regalloc.DeAlloc(tai_regalloc(p).Reg,hp2);
InsertLLItem(tai(hp2.previous), hp2, hp1);
End;
End;
}
End;
End
else
Begin
UsedRegs := UsedRegs - [tai_regalloc(p).Reg];
ExcludeRegFromUsedRegs(tai_regalloc(p).Reg,Regs);
hp1 := p;
hp2 := nil;
While Not(FindRegAlloc(tai_regalloc(p).Reg, tai(hp1.Next))) And
@ -172,8 +178,17 @@ Unit aopt;
InsertLLItem(hp2, tai(hp2.Next), p);
p := hp1;
End
else if findregalloc(tai_regalloc(p).reg, tai(p.next))
and getnextinstruction(p,hp1) then
begin
hp1 := tai(p.previous);
AsmL.remove(p);
p.free;
p := hp1;
// don't include here, since then the allocation will be removed when it's processed
// include(usedregs,supreg);
end;
End
};
End
End;
P := tai(p.Next);
@ -182,7 +197,8 @@ Unit aopt;
(p.typ in (SkipInstr - [ait_regalloc])) Do
P := tai(P.Next)
End;
End
End;
ReleaseUsedRegs(Regs);
End;
procedure tasmoptimizer.clear;

View File

@ -47,7 +47,7 @@ unit aoptbase;
constructor create; virtual;
destructor destroy;override;
{ returns true if register Reg is used by instruction p1 }
Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;
Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;virtual;
{ returns true if register Reg occurs in operand op }
Function RegInOp(Reg: TRegister; const op: toper): Boolean;
{ returns true if register Reg is used in the reference Ref }
@ -201,12 +201,12 @@ unit aoptbase;
Current := Tai(Current.previous);
While Assigned(Current) And
(((Current.typ = ait_Marker) And
Not(Tai_Marker(Current).Kind in [mark_AsmBlockEnd,mark_NoPropInfoEnd])) or
Not(Tai_Marker(Current).Kind in [mark_AsmBlockEnd{,mark_NoPropInfoEnd}])) or
(Current.typ In SkipInstr) or
((Current.typ = ait_label) And
labelCanBeSkipped(Tai_Label(Current)))) Do
Current := Tai(Current.previous);
If Assigned(Current) And
{ If Assigned(Current) And
(Current.typ = ait_Marker) And
(Tai_Marker(Current).Kind = mark_NoPropInfoEnd) Then
Begin
@ -214,10 +214,10 @@ unit aoptbase;
((Current.typ <> ait_Marker) Or
(Tai_Marker(Current).Kind <> mark_NoPropInfoStart)) Do
Current := Tai(Current.previous);
End;
End; }
Until Not(Assigned(Current)) Or
(Current.typ <> ait_Marker) Or
(Tai_Marker(Current).Kind <> mark_NoPropInfoStart);
not(tai_Marker(current).Kind in [mark_NoPropInfoStart,mark_NoPropInfoEnd]);
If Not(Assigned(Current)) or
(Current.typ In SkipInstr) or
((Current.typ = ait_label) And

View File

@ -164,17 +164,17 @@ Unit AoptObj;
TInstrSinceLastMod);
{ destroy the contents of all registers }
Procedure DestroyAllRegs(var InstrSinceLastMod: TInstrSinceLastMod);
{ a register's contents are modified, but not destroyed (the new value }
{ depends on the old one) }
{ a register's contents are modified, but not destroyed (the new value
depends on the old one) }
Procedure ModifyReg(reg: TRegister; var InstrSinceLastMod:
TInstrSinceLastMod);
{ an operand's contents are modified, but not destroyed (the new value }
{ depends on the old one) }
{ an operand's contents are modified, but not destroyed (the new value
depends on the old one) }
Procedure ModifyOp(const oper: TOper; var InstrSinceLastMod:
TInstrSinceLastMod);
{ increase the write state of a register (call every time a register is }
{ written to) }
{ increase the write state of a register (call every time a register is
written to) }
Procedure IncWState(Reg: TRegister);
{ increase the read state of a register (call every time a register is }
{ read from) }
@ -262,11 +262,15 @@ Unit AoptObj;
{ processor independent methods }
Procedure CreateUsedRegs(var regs: TAllUsedRegs);
Procedure ClearUsedRegs;
Procedure UpdateUsedRegs(p : Tai);
procedure UpdateUsedRegs(var Regs: TAllUsedRegs; p: Tai);
Function CopyUsedRegs(var dest : TAllUsedRegs) : boolean;
Procedure ReleaseUsedRegs(const regs : TAllUsedRegs);
Function RegInUsedRegs(reg : TRegister;regs : TAllUsedRegs) : boolean;
Procedure IncludeRegInUsedRegs(reg : TRegister;var regs : TAllUsedRegs);
Procedure ExcludeRegFromUsedRegs(reg: TRegister;var regs : TAllUsedRegs);
{ returns true if the label L is found between hp and the next }
{ instruction }
@ -778,15 +782,12 @@ Unit AoptObj;
Constructor TAoptObj.create(_AsmL: TAsmList; _BlockStart, _BlockEnd: Tai;
_LabelInfo: PLabelInfo);
var
i : TRegisterType;
Begin
AsmL := _AsmL;
BlockStart := _BlockStart;
BlockEnd := _BlockEnd;
LabelInfo := _LabelInfo;
for i:=low(TRegisterType) to high(TRegisterType) do
UsedRegs[i]:=TUsedRegs.Create(i);
CreateUsedRegs(UsedRegs);
End;
destructor TAOptObj.Destroy;
@ -799,6 +800,15 @@ Unit AoptObj;
end;
procedure TAOptObj.CreateUsedRegs(var regs: TAllUsedRegs);
var
i : TRegisterType;
begin
for i:=low(TRegisterType) to high(TRegisterType) do
Regs[i]:=TUsedRegs.Create(i);
end;
procedure TAOptObj.ClearUsedRegs;
var
i : TRegisterType;
@ -835,6 +845,7 @@ Unit AoptObj;
dest[i]:=TUsedRegs.Create_Regset(i,UsedRegs[i].GetUsedRegs);
end;
procedure TAOptObj.ReleaseUsedRegs(const regs: TAllUsedRegs);
var
i : TRegisterType;
@ -844,6 +855,26 @@ Unit AoptObj;
end;
Function TAOptObj.RegInUsedRegs(reg : TRegister;regs : TAllUsedRegs) : boolean;
begin
result:=regs[getregtype(reg)].IsUsed(reg);
end;
procedure TAOptObj.IncludeRegInUsedRegs(reg: TRegister;
var regs: TAllUsedRegs);
begin
include(regs[getregtype(reg)].UsedRegs,getsupreg(Reg));
end;
procedure TAOptObj.ExcludeRegFromUsedRegs(reg: TRegister;
var regs: TAllUsedRegs);
begin
exclude(regs[getregtype(reg)].UsedRegs,getsupreg(Reg));
end;
Function TAOptObj.FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
Var TempP: Tai;
Begin

View File

@ -28,13 +28,17 @@ Unit aoptcpu;
Interface
uses cpubase, aasmtai, aopt, aoptcpub;
uses cgbase, cpubase, aasmtai, aopt, aoptcpub, aoptobj;
Type
{ TCpuAsmOptimizer }
TCpuAsmOptimizer = class(TAsmOptimizer)
{ uses the same constructor as TAopObj }
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
procedure PeepHoleOptPass2;override;
Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;override;
End;
TCpuPreRegallocScheduler = class(TAsmOptimizer)
@ -51,7 +55,7 @@ Implementation
uses
cutils,
verbose,
cgbase,cgutils,
cgutils,
aasmbase,aasmdata,aasmcpu;
function CanBeCond(p : tai) : boolean;
@ -118,6 +122,7 @@ Implementation
var
hp1,hp2: tai;
i: longint;
TmpUsedRegs: TAllUsedRegs;
begin
result := false;
case p.typ of
@ -216,6 +221,36 @@ Implementation
taicpu(hp1).loadreg(1,taicpu(p).oper[0]^.reg);
end;
result := true;
end
else
{ Remove superfluous mov after ldr
changes
ldr reg1, ref
mov reg2, reg1
to
ldr reg2, ref
conditions are:
* reg1 must be released after mov
* mov can not contain shifterops
* ldr+mov have the same conditions
* mov does not set flags
}
if GetNextInstruction(p, hp1) and
MatchInstruction(hp1, A_MOV, [taicpu(p).condition], [PF_None]) and
(taicpu(hp1).ops=2) and {We can't optimize if there is a shiftop}
MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) then
begin
CopyUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next));
If not(RegUsedAfterInstruction(taicpu(p).oper[0]^.reg,hp1,TmpUsedRegs)) then
begin
asml.insertbefore(tai_comment.Create(strpnew('Peephole LdrMov2Ldr removed superfluous mov')), hp1);
taicpu(p).loadreg(0,taicpu(hp1).oper[0]^.reg);
asml.remove(hp1);
hp1.free;
end;
ReleaseUsedRegs(TmpUsedRegs);
end;
end;
A_MOV:
@ -562,6 +597,14 @@ Implementation
end;
end;
function TCpuAsmOptimizer.RegInInstruction(Reg: TRegister; p1: tai): Boolean;
begin
If (p1.typ = ait_instruction) and (taicpu(p1).opcode=A_BL) then
Result:=true
else
Result:=inherited RegInInstruction(Reg, p1);
end;
const
{ set of opcode which might or do write to memory }
{ TODO : extend armins.dat to contain r/w info }