* AllocRegBetween always extends the processed register to the whole super register and takes care of this while removing (de)/allocs

git-svn-id: trunk@34718 -
This commit is contained in:
florian 2016-10-15 15:03:23 +00:00
parent 41c9543ddf
commit 4109f88e08

View File

@ -23,7 +23,7 @@ unit aoptx86;
{$i fpcdefs.inc} {$i fpcdefs.inc}
{ $define DEBUG_AOPTCPU} {$define DEBUG_AOPTCPU}
interface interface
@ -241,6 +241,16 @@ unit aoptx86;
' till here...')); ' till here...'));
insertllitem(asml,p2,p2.next,hp); insertllitem(asml,p2,p2.next,hp);
{$endif allocregdebug} {$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 if not(RegInUsedRegs(reg,initialusedregs)) then
begin begin
hp := tai_regalloc.alloc(reg,nil); hp := tai_regalloc.alloc(reg,nil);
@ -261,20 +271,31 @@ unit aoptx86;
{ remove all allocation/deallocation info about the register in between } { remove all allocation/deallocation info about the register in between }
if assigned(p1) and if assigned(p1) and
(p1.typ = ait_regalloc) then (p1.typ = ait_regalloc) then
if tai_regalloc(p1).reg=reg then begin
begin if (getregtype(reg)=getregtype(tai_regalloc(p1).reg)) and
if not removedSomething then (getsupreg(tai_regalloc(p1).reg)=getsupreg(reg)) and (tai_regalloc(p1).reg<>reg) then
begin begin
firstRemovedWasAlloc := tai_regalloc(p1).ratype=ra_alloc; if (getsubreg(tai_regalloc(p1).reg)>getsubreg(reg)) or (getsubreg(reg)=R_SUBH) then
removedSomething := true; internalerror(2016101501);
end; tai_regalloc(p1).reg:=reg;
lastRemovedWasDealloc := (tai_regalloc(p1).ratype=ra_dealloc); end;
hp := tai(p1.Next);
asml.Remove(p1); if tai_regalloc(p1).reg=reg then
p1.free; begin
p1 := hp; if not removedSomething then
end begin
else p1 := tai(p1.next); 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 until not(assigned(p1)) or
not(p1.typ in SkipInstr); not(p1.typ in SkipInstr);
end; end;
@ -748,7 +769,7 @@ unit aoptx86;
mov reg1, mem1/reg2 mov reg1, mem1/reg2
mov mem1/reg2, reg1 } mov mem1/reg2, reg1 }
begin begin
if (taicpu(p).oper[0]^.typ = top_reg) then if taicpu(p).oper[0]^.typ=top_reg then
AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,usedregs); AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,usedregs);
DebugMsg('PeepHole Optimization,MovMov2Mov 1',p); DebugMsg('PeepHole Optimization,MovMov2Mov 1',p);
asml.remove(hp1); asml.remove(hp1);
@ -902,7 +923,7 @@ unit aoptx86;
RefsEqual(taicpu(hp1).oper[0]^.ref^,taicpu(p).oper[1]^.ref^) and RefsEqual(taicpu(hp1).oper[0]^.ref^,taicpu(p).oper[1]^.ref^) and
not(RegInRef(taicpu(hp1).oper[1]^.reg,taicpu(hp1).oper[0]^.ref^)) then not(RegInRef(taicpu(hp1).oper[1]^.reg,taicpu(hp1).oper[0]^.ref^)) then
begin begin
allocregbetween(taicpu(hp1).oper[1]^.reg,p,hp1,usedregs); AllocRegBetween(taicpu(hp1).oper[1]^.reg,p,hp1,usedregs);
taicpu(hp1).loadReg(0,taicpu(hp1).oper[1]^.reg); taicpu(hp1).loadReg(0,taicpu(hp1).oper[1]^.reg);
taicpu(hp1).loadRef(1,taicpu(p).oper[1]^.ref^); taicpu(hp1).loadRef(1,taicpu(p).oper[1]^.ref^);
taicpu(p).loadReg(1,taicpu(hp1).oper[0]^.reg); taicpu(p).loadReg(1,taicpu(hp1).oper[0]^.reg);