+ generic TAOptObj.AllocRegBetween

- removed x86 specific AllocRegBetween

git-svn-id: trunk@38445 -
This commit is contained in:
florian 2018-03-07 22:17:35 +00:00
parent 6e79c8ba86
commit 78878f59b1
2 changed files with 120 additions and 112 deletions

View File

@ -315,6 +315,10 @@ Unit AoptObj;
nil }
Function FindRegDeAlloc(Reg: TRegister; StartPai: Tai): tai_regalloc;
{ allocates register reg between (and including) instructions p1 and p2
the type of p1 and p2 must not be in SkipInstr }
procedure AllocRegBetween(reg : tregister; p1,p2 : tai; var initialusedregs : TAllUsedRegs);
{ reg used after p? }
function RegUsedAfterInstruction(reg: Tregister; p: tai; var AllUsedRegs: TAllUsedRegs): Boolean;
@ -370,7 +374,8 @@ Unit AoptObj;
cutils,
globals,
verbose,
aoptutils;
aoptutils,
procinfo;
function JumpTargetOp(ai: taicpu): poper; inline;
@ -1146,6 +1151,120 @@ Unit AoptObj;
End;
{ allocates register reg between (and including) instructions p1 and p2
the type of p1 and p2 must not be in SkipInstr }
procedure TAOptObj.AllocRegBetween(reg: tregister; p1, p2: tai; var initialusedregs: TAllUsedRegs);
var
hp, start: tai;
removedsomething,
firstRemovedWasAlloc,
lastRemovedWasDealloc: boolean;
begin
{$ifdef EXTDEBUG}
{ if assigned(p1.optinfo) and
(ptaiprop(p1.optinfo)^.usedregs <> initialusedregs) then
internalerror(2004101010); }
{$endif EXTDEBUG}
start := p1;
if (reg = NR_STACK_POINTER_REG) or
(reg = current_procinfo.framepointer) or
not(assigned(p1)) then
{ this happens with registers which are loaded implicitely, outside the }
{ current block (e.g. esi with self) }
exit;
{ make sure we allocate it for this instruction }
getnextinstruction(p2,p2);
lastRemovedWasDealloc := false;
removedSomething := false;
firstRemovedWasAlloc := false;
{$ifdef allocregdebug}
hp := tai_comment.Create(strpnew('allocating '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+
' from here...'));
insertllitem(asml,p1.previous,p1,hp);
hp := tai_comment.Create(strpnew('allocated '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+
' till here...'));
insertllitem(asml,p2,p2.next,hp);
{$endif allocregdebug}
{ do it the safe way: always allocate the full super register,
as we do no register re-allocation in the peephole optimizer,
this does not hurt
}
case getregtype(reg) of
R_MMREGISTER:
reg:=newreg(R_MMREGISTER,getsupreg(reg),R_SUBMMWHOLE);
R_INTREGISTER:
reg:=newreg(R_INTREGISTER,getsupreg(reg),R_SUBWHOLE);
R_FPUREGISTER:
reg:=newreg(R_FPUREGISTER,getsupreg(reg),R_SUBWHOLE);
R_ADDRESSREGISTER:
reg:=newreg(R_ADDRESSREGISTER,getsupreg(reg),R_SUBWHOLE);
else
Internalerror(2018030701);
end;
if not(RegInUsedRegs(reg,initialusedregs)) then
begin
hp := tai_regalloc.alloc(reg,nil);
insertllItem(p1.previous,p1,hp);
IncludeRegInUsedRegs(reg,initialusedregs);
end;
while assigned(p1) and
(p1 <> p2) do
begin
if assigned(p1.optinfo) then
internalerror(2014022301); // IncludeRegInUsedRegs(reg,ptaiprop(p1.optinfo)^.usedregs);
p1 := tai(p1.next);
repeat
while assigned(p1) and
(p1.typ in (SkipInstr-[ait_regalloc])) Do
p1 := tai(p1.next);
{ remove all allocation/deallocation info about the register in between }
if assigned(p1) and
(p1.typ = ait_regalloc) then
begin
{ same super register, different sub register? }
if SuperRegistersEqual(reg,tai_regalloc(p1).reg) and (tai_regalloc(p1).reg<>reg) then
begin
if (getsubreg(tai_regalloc(p1).reg)>getsubreg(reg)) or (getsubreg(reg)=R_SUBH) then
internalerror(2016101501);
tai_regalloc(p1).reg:=reg;
end;
if tai_regalloc(p1).reg=reg then
begin
if not removedSomething then
begin
firstRemovedWasAlloc := tai_regalloc(p1).ratype=ra_alloc;
removedSomething := true;
end;
lastRemovedWasDealloc := (tai_regalloc(p1).ratype=ra_dealloc);
hp := tai(p1.Next);
asml.Remove(p1);
p1.free;
p1 := hp;
end
else
p1 := tai(p1.next);
end;
until not(assigned(p1)) or
not(p1.typ in SkipInstr);
end;
if assigned(p1) then
begin
if firstRemovedWasAlloc then
begin
hp := tai_regalloc.Alloc(reg,nil);
insertLLItem(start.previous,start,hp);
end;
if lastRemovedWasDealloc then
begin
hp := tai_regalloc.DeAlloc(reg,nil);
insertLLItem(p1.previous,p1,hp);
end;
end;
end;
function TAOptObj.RegUsedAfterInstruction(reg: Tregister; p: tai;var AllUsedRegs: TAllUsedRegs): Boolean;
begin
AllUsedRegs[getregtype(reg)].Update(tai(p.Next),true);

View File

@ -50,7 +50,6 @@ unit aoptx86;
procedure DebugMsg(const s : string; p : tai);inline;
procedure AllocRegBetween(reg : tregister; p1,p2 : tai;var initialusedregs : TAllUsedRegs);
class function IsExitCode(p : tai) : boolean;
class function isFoldableArithOp(hp1 : taicpu; reg : tregister) : boolean;
procedure RemoveLastDeallocForFuncRes(p : tai);
@ -609,116 +608,6 @@ unit aoptx86;
end;
{ allocates register reg between (and including) instructions p1 and p2
the type of p1 and p2 must not be in SkipInstr
note that this routine is both called from the peephole optimizer
where optinfo is not yet initialised) and from the cse (where it is) }
procedure TX86AsmOptimizer.AllocRegBetween(reg: tregister; p1, p2: tai; var initialusedregs: TAllUsedRegs);
var
hp, start: tai;
removedsomething,
firstRemovedWasAlloc,
lastRemovedWasDealloc: boolean;
begin
{$ifdef EXTDEBUG}
{ if assigned(p1.optinfo) and
(ptaiprop(p1.optinfo)^.usedregs <> initialusedregs) then
internalerror(2004101010); }
{$endif EXTDEBUG}
start := p1;
if (reg = NR_ESP) or
(reg = current_procinfo.framepointer) or
not(assigned(p1)) then
{ this happens with registers which are loaded implicitely, outside the }
{ current block (e.g. esi with self) }
exit;
{ make sure we allocate it for this instruction }
getnextinstruction(p2,p2);
lastRemovedWasDealloc := false;
removedSomething := false;
firstRemovedWasAlloc := false;
{$ifdef allocregdebug}
hp := tai_comment.Create(strpnew('allocating '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+
' from here...'));
insertllitem(asml,p1.previous,p1,hp);
hp := tai_comment.Create(strpnew('allocated '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+
' till here...'));
insertllitem(asml,p2,p2.next,hp);
{$endif allocregdebug}
{ do it the safe way: always allocate the full super register,
as we do no register re-allocation in the peephole optimizer,
this does not hurt
}
case getregtype(reg) of
R_MMREGISTER:
reg:=newreg(R_MMREGISTER,getsupreg(reg),R_SUBMMWHOLE);
R_INTREGISTER:
reg:=newreg(R_INTREGISTER,getsupreg(reg),R_SUBWHOLE);
end;
if not(RegInUsedRegs(reg,initialusedregs)) then
begin
hp := tai_regalloc.alloc(reg,nil);
insertllItem(p1.previous,p1,hp);
IncludeRegInUsedRegs(reg,initialusedregs);
end;
while assigned(p1) and
(p1 <> p2) do
begin
if assigned(p1.optinfo) then
internalerror(2014022301); // IncludeRegInUsedRegs(reg,ptaiprop(p1.optinfo)^.usedregs);
p1 := tai(p1.next);
repeat
while assigned(p1) and
(p1.typ in (SkipInstr-[ait_regalloc])) Do
p1 := tai(p1.next);
{ remove all allocation/deallocation info about the register in between }
if assigned(p1) and
(p1.typ = ait_regalloc) then
begin
{ same super register, different sub register? }
if SuperRegistersEqual(reg,tai_regalloc(p1).reg) and (tai_regalloc(p1).reg<>reg) then
begin
if (getsubreg(tai_regalloc(p1).reg)>getsubreg(reg)) or (getsubreg(reg)=R_SUBH) then
internalerror(2016101501);
tai_regalloc(p1).reg:=reg;
end;
if tai_regalloc(p1).reg=reg then
begin
if not removedSomething then
begin
firstRemovedWasAlloc := tai_regalloc(p1).ratype=ra_alloc;
removedSomething := true;
end;
lastRemovedWasDealloc := (tai_regalloc(p1).ratype=ra_dealloc);
hp := tai(p1.Next);
asml.Remove(p1);
p1.free;
p1 := hp;
end
else
p1 := tai(p1.next);
end;
until not(assigned(p1)) or
not(p1.typ in SkipInstr);
end;
if assigned(p1) then
begin
if firstRemovedWasAlloc then
begin
hp := tai_regalloc.Alloc(reg,nil);
insertLLItem(start.previous,start,hp);
end;
if lastRemovedWasDealloc then
begin
hp := tai_regalloc.DeAlloc(reg,nil);
insertLLItem(p1.previous,p1,hp);
end;
end;
end;
function TX86AsmOptimizer.RegLoadedWithNewValue(reg: tregister; hp: tai): boolean;
var
p: taicpu;