* several fixes to allocregbetween()

This commit is contained in:
Jonas Maebe 2004-10-10 15:01:19 +00:00
parent 28e0869e6f
commit cf085fb9d0
4 changed files with 120 additions and 80 deletions

View File

@ -1352,7 +1352,7 @@ begin
ClearRegContentsFrom(orgsupreg,p,hp);
if removeLast then
ptaiprop(endp.optinfo)^.canBeRemoved := true;
allocRegBetween(asml,newreg(R_INTREGISTER,orgsupreg,R_SUBWHOLE),p,endP);
allocRegBetween(asml,newreg(R_INTREGISTER,orgsupreg,R_SUBWHOLE),p,endP,ptaiprop(p.optinfo)^.usedregs);
end
{$ifdef replaceregdebug}
@ -1560,8 +1560,14 @@ begin
if (reginfo.new2oldreg[regcounter] <> RS_INVALID) Then
begin
include(regsloaded,regcounter);
AllocRegBetween(asml,newreg(R_INTREGISTER,reginfo.new2oldreg[regcounter],R_SUBWHOLE),
ptaiprop(prevseqstart.optinfo)^.Regs[reginfo.new2oldreg[regcounter]].StartMod,curseqstart);
if assigned(ptaiprop(prevseqstart.optinfo)^.Regs[reginfo.new2oldreg[regcounter]].StartMod) then
AllocRegBetween(asml,newreg(R_INTREGISTER,reginfo.new2oldreg[regcounter],R_SUBWHOLE),
ptaiprop(prevseqstart.optinfo)^.Regs[reginfo.new2oldreg[regcounter]].StartMod,curseqstart,
ptaiprop(ptaiprop(prevseqstart.optinfo)^.Regs[reginfo.new2oldreg[regcounter]].StartMod.optinfo)^.usedregs)
else
AllocRegBetween(asml,newreg(R_INTREGISTER,reginfo.new2oldreg[regcounter],R_SUBWHOLE),
prevseqstart,curseqstart,ptaiprop(prevseqstart.optinfo)^.usedregs);
if curprev <> prevseqstart then
begin
if assigned(reginfo.lastReload[regCounter]) then
@ -1572,7 +1578,8 @@ begin
hp := curprev;
clearRegContentsFrom(regCounter,prevSeq_next,hp);
getnextInstruction(hp,hp);
allocRegBetween(asml,newreg(R_INTREGISTER,regCounter,R_SUBWHOLE),prevseqstart,hp);
allocRegBetween(asml,newreg(R_INTREGISTER,regCounter,R_SUBWHOLE),prevseqstart,hp,
ptaiprop(prevseqstart.optinfo)^.usedregs);
end;
if not(regcounter in reginfo.RegsLoadedforRef) and
{old reg new reg}
@ -1815,8 +1822,12 @@ begin
ptaiprop(hp4.optinfo)^.regs[getsupreg(taicpu(p).oper[1]^.reg)],false,hp1) then
begin
ptaiprop(p.optinfo)^.canBeRemoved := true;
{ this is just a regular move that was here, so the source register should be }
{ allocated already at this point -> only allocate from here onwards }
if not(getsupreg(taicpu(p).oper[0]^.reg) in pTaiProp(p.optinfo)^.usedregs) then
internalerror(2004101011);
allocRegBetween(asml,taicpu(p).oper[0]^.reg,
pTaiProp(p.optinfo)^.regs[getsupreg(taicpu(p).oper[0]^.reg)].startMod,hp1);
p,hp1,pTaiProp(p.optinfo)^.usedregs)
end
else
begin
@ -1836,12 +1847,12 @@ begin
(taicpu(p).oper[1]^.reg = memreg) then
begin
pTaiProp(p.optinfo)^.canberemoved := true;
allocregbetween(asml,memreg,hp5,p);
allocregbetween(asml,memreg,hp5,p,ptaiprop(hp5.optinfo)^.usedregs);
end
else
begin
replaceoperandwithreg(asml,p,0,memreg);
allocregbetween(asml,memreg,hp5,p);
allocregbetween(asml,memreg,hp5,p,ptaiprop(hp5.optinfo)^.usedregs);
regcounter := getsupreg(memreg);
incstate(pTaiProp(p.optinfo)^.regs[regcounter].rstate,1);
updatestate(regcounter,p);
@ -1871,7 +1882,8 @@ begin
opsequal(taicpu(StartMod).oper[0]^,taicpu(p).oper[0]^) then
begin
ptaiprop(p.optinfo)^.CanBeRemoved := True;
allocRegBetween(asml,taicpu(p).oper[1]^.reg,startMod,p);
allocRegBetween(asml,taicpu(p).oper[1]^.reg,startmod,p,
ptaiprop(startmod.optinfo)^.usedregs);
end
else
removePrevNotUsedLoad(p,getsupreg(taicpu(p).oper[1]^.reg),false);
@ -1884,7 +1896,8 @@ begin
begin
taicpu(p).loadreg(0,memreg);
allocRegBetween(asml,memreg,
ptaiprop(hp1.optinfo)^.regs[getsupreg(memreg)].startMod,p);
ptaiprop(hp1.optinfo)^.regs[getsupreg(memreg)].startMod,p,
ptaiprop(ptaiprop(hp1.optinfo)^.regs[getsupreg(memreg)].startMod.optinfo)^.usedregs);
end;
end;
end;
@ -1919,7 +1932,7 @@ begin
if memreg <> NR_NO then
begin
replaceoperandwithreg(asml,p,0,memreg);
allocregbetween(asml,memreg,hp5,p);
allocregbetween(asml,memreg,hp5,p,ptaiprop(hp5.optinfo)^.usedregs);
regcounter := getsupreg(memreg);
incstate(pTaiProp(p.optinfo)^.regs[regcounter].rstate,1);
updatestate(regcounter,p);
@ -1951,7 +1964,7 @@ begin
insertllitem(asml,p,p.next,hp1);
replaceoperandwithreg(asml,p,0,memreg);
allocregbetween(asml,memreg,hp5,
tai(p.next.next));
tai(p.next.next),ptaiprop(hp5.optinfo)^.usedregs);
ClearRegContentsFrom(regcounter,hp5,p);
end;
end;
@ -1966,7 +1979,7 @@ begin
if memreg <> NR_NO then
begin
replaceoperandwithreg(asml,p,1,memreg);
allocregbetween(asml,memreg,hp5,p);
allocregbetween(asml,memreg,hp5,p,ptaiprop(hp5.optinfo)^.usedregs);
regcounter := getsupreg(memreg);
incstate(pTaiProp(p.optinfo)^.regs[regcounter].rstate,1);
updatestate(regcounter,p);
@ -2004,7 +2017,7 @@ begin
insertllitem(asml,p,p.next,hp1);
replaceoperandwithreg(asml,p,1,memreg);
allocregbetween(asml,memreg,hp5,
tai(p.next.next));
tai(p.next.next),ptaiprop(hp5.optinfo)^.usedregs);
ClearRegContentsFrom(regcounter,hp5,p);
end;
end;
@ -2109,7 +2122,10 @@ end.
{
$Log$
Revision 1.67 2004-10-06 19:24:38 jonas
Revision 1.68 2004-10-10 15:01:19 jonas
* several fixes to allocregbetween()
Revision 1.67 2004/10/06 19:24:38 jonas
* take into account the size of a write to determine whether a write to
one reference influences the contents of another reference

View File

@ -197,7 +197,7 @@ procedure RemoveLastDeallocForFuncRes(asmL: TAAsmOutput; p: tai);
function regLoadedWithNewValue(supreg: tsuperregister; canDependOnPrevValue: boolean;
hp: tai): boolean;
procedure UpdateUsedRegs(var UsedRegs: TRegSet; p: tai);
procedure AllocRegBetween(asml: taasmoutput; reg: tregister; p1, p2: tai);
procedure AllocRegBetween(asml: taasmoutput; reg: tregister; p1, p2: tai; const initialusedregs: tregset);
function FindRegDealloc(supreg: tsuperregister; p: tai): boolean;
//function RegsEquivalent(OldReg, NewReg: tregister; var RegInfo: toptreginfo; OpAct: TopAction): Boolean;
@ -736,6 +736,8 @@ begin
exit;
p := taicpu(hp);
case p.opcode of
A_CALL:
regreadbyinstruction := true;
A_IMUL:
case p.ops of
1:
@ -808,6 +810,8 @@ begin
exit;
p := taicpu(p1);
case p.opcode of
A_CALL:
regininstruction := true;
A_IMUL:
case p.ops of
1:
@ -1141,14 +1145,21 @@ begin
end;
procedure AllocRegBetween(asml: taasmoutput; reg: tregister; p1, p2: tai);
procedure AllocRegBetween(asml: taasmoutput; reg: tregister; p1, p2: tai; const initialusedregs: tregset);
{ 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) }
var
hp, start: tai;
lastRemovedWasDealloc, firstRemovedWasAlloc, first: boolean;
hp: tai;
lastRemovedWasDealloc: boolean;
supreg: tsuperregister;
begin
{$ifdef EXTDEBUG}
if assigned(p1.optinfo) and
(ptaiprop(p1.optinfo)^.usedregs <> initialusedregs) then
internalerror(2004101010);
{$endif EXTDEBUG}
supreg := getsupreg(reg);
{ if not(supreg in rg.usableregsint+[RS_EDI,RS_ESI]) or
not(assigned(p1)) then}
@ -1158,11 +1169,8 @@ begin
{ current block (e.g. esi with self) }
exit;
{ make sure we allocate it for this instruction }
if p1 = p2 then
getnextinstruction(p2,p2);
getnextinstruction(p2,p2);
lastRemovedWasDealloc := false;
firstRemovedWasAlloc := false;
first := true;
{$ifdef allocregdebug}
hp := tai_comment.Create(strpnew('allocating '+std_reg2str[supreg]+
' from here...')));
@ -1171,51 +1179,44 @@ begin
' till here...')));
insertllitem(asml,p2,p1.next,hp);
{$endif allocregdebug}
start := p1;
repeat
if assigned(p1.OptInfo) then
include(ptaiprop(p1.OptInfo)^.UsedRegs,supreg);
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
if (getsupreg(tai_regalloc(p1).reg) = supreg) then
begin
if first then
begin
firstRemovedWasAlloc := (tai_regalloc(p1).ratype=ra_alloc);
first := false;
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);
until not(assigned(p1)) or
not(p1.typ in SkipInstr);
until not(assigned(p1)) or
(p1 = p2);
if assigned(p1) then
if not(supreg in initialusedregs) then
begin
hp := tai_regalloc.alloc(reg,nil);
insertllItem(asmL,p1.previous,p1,hp);
end;
while assigned(p1) and
(p1 <> p2) do
begin
if assigned(p1.optinfo) then
include(ptaiprop(p1.OptInfo)^.UsedRegs,supreg);
include(ptaiprop(p1.optinfo)^.usedregs,supreg);
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
if (getsupreg(tai_regalloc(p1).reg) = supreg) then
begin
lastRemovedWasDealloc := (tai_regalloc(p1).ratype=ra_dealloc);
hp := tai(p1.Next);
asml.Remove(p1);
p1.free;
p1 := hp;
end
else p1 := tai(p1.next);
until not(assigned(p1)) or
not(p1.typ in SkipInstr);
end;
if assigned(p1) then
begin
if lastRemovedWasDealloc then
begin
hp := tai_regalloc.DeAlloc(reg,nil);
insertLLItem(asmL,p1,p1.next,hp);
insertLLItem(asmL,p1.previous,p1,hp);
end;
end;
if firstRemovedWasAlloc then
begin
hp := tai_regalloc.Alloc(reg,nil);
insertLLItem(asmL,start.previous,start,hp);
end;
end;
@ -2068,7 +2069,13 @@ begin
if not(supreg in usedregs) then
include(usedregs, supreg)
else
addregdeallocfor(list, tai_regalloc(p).reg, p);
begin
//addregdeallocfor(list, tai_regalloc(p).reg, p);
hp1 := tai(p.previous);
list.remove(p);
p.free;
p := hp1;
end;
end;
ra_dealloc :
begin
@ -2085,6 +2092,17 @@ begin
list.remove(p);
insertllitem(list, hp2, tai(hp2.next), p);
p := hp1;
end
else if findregalloc(tai_regalloc(p).reg, tai(p.next),ra_alloc)
and getnextinstruction(p,hp1) and
(hp1.typ = ait_instruction) and
(taicpu(hp1).opcode = A_CALL) then
begin
hp1 := tai(p.previous);
list.remove(p);
p.free;
p := hp1;
include(usedregs,supreg);
end;
end;
end;
@ -2765,7 +2783,10 @@ end.
{
$Log$
Revision 1.72 2004-10-06 19:24:38 jonas
Revision 1.73 2004-10-10 15:01:19 jonas
* several fixes to allocregbetween()
Revision 1.72 2004/10/06 19:24:38 jonas
* take into account the size of a write to determine whether a write to
one reference influences the contents of another reference

View File

@ -939,7 +939,7 @@ begin
TmpUsedRegs := UsedRegs;
{ reg1 will be used after the first instruction, }
{ so update the allocation info }
allocRegBetween(asmL,taicpu(p).oper[0]^.reg,p,hp1);
allocRegBetween(asmL,taicpu(p).oper[0]^.reg,p,hp1,usedregs);
if GetNextInstruction(hp1, hp2) and
(hp2.typ = ait_instruction) and
taicpu(hp2).is_jmp and
@ -999,7 +999,7 @@ begin
{change "mov reg1, mem1; cmp x, mem1" to "mov reg, mem1; cmp x, reg1"}
begin
taicpu(hp1).loadreg(1,taicpu(p).oper[0]^.reg);
allocRegBetween(asmL,taicpu(p).oper[0]^.reg,p,hp1);
allocRegBetween(asmL,taicpu(p).oper[0]^.reg,p,hp1,usedregs);
end;
{ Next instruction is also a MOV ? }
if GetNextInstruction(p, hp1) and
@ -1022,7 +1022,7 @@ begin
mov mem1/reg2, reg1 }
begin
if (taicpu(p).oper[0]^.typ = top_reg) then
AllocRegBetween(asmL,taicpu(p).oper[0]^.reg,p,hp1);
AllocRegBetween(asmL,taicpu(p).oper[0]^.reg,p,hp1,usedregs);
asml.remove(hp1);
hp1.free;
end
@ -1080,7 +1080,7 @@ begin
mov mem1, reg2
mov reg2, mem2}
begin
AllocRegBetween(asmL,taicpu(hp2).oper[1]^.reg,p,hp2);
AllocRegBetween(asmL,taicpu(hp2).oper[1]^.reg,p,hp2,usedregs);
taicpu(p).Loadoper(1,taicpu(hp2).oper[1]^);
taicpu(hp1).loadoper(0,taicpu(hp2).oper[1]^);
asml.remove(hp2);
@ -1110,19 +1110,19 @@ begin
taicpu(hp1).LoadReg(1,taicpu(hp2).oper[1]^.reg);
taicpu(hp2).LoadRef(1,taicpu(hp2).oper[0]^.ref^);
taicpu(hp2).LoadReg(0,taicpu(p).oper[1]^.reg);
allocRegBetween(asmL,taicpu(p).oper[1]^.reg,p,hp2);
allocRegBetween(asmL,taicpu(p).oper[1]^.reg,p,hp2,usedregs);
if (taicpu(p).oper[0]^.ref^.base <> NR_NO) and
(getsupreg(taicpu(p).oper[0]^.ref^.base) in [RS_EAX,RS_EBX,RS_ECX,RS_EDX,RS_ESI,RS_EDI]) then
allocRegBetween(asmL,taicpu(p).oper[0]^.ref^.base,p,hp2);
allocRegBetween(asmL,taicpu(p).oper[0]^.ref^.base,p,hp2,usedregs);
if (taicpu(p).oper[0]^.ref^.index <> NR_NO) and
(getsupreg(taicpu(p).oper[0]^.ref^.index) in [RS_EAX,RS_EBX,RS_ECX,RS_EDX,RS_ESI,RS_EDI]) then
allocRegBetween(asmL,taicpu(p).oper[0]^.ref^.index,p,hp2);
allocRegBetween(asmL,taicpu(p).oper[0]^.ref^.index,p,hp2,usedregs);
end
else
if (taicpu(hp1).Oper[0]^.reg <> taicpu(hp2).Oper[1]^.reg) then
begin
taicpu(hp2).LoadReg(0,taicpu(hp1).Oper[0]^.reg);
allocRegBetween(asmL,taicpu(p).oper[1]^.reg,p,hp2);
allocRegBetween(asmL,taicpu(p).oper[1]^.reg,p,hp2,usedregs);
end
else
begin
@ -1159,12 +1159,7 @@ begin
(taicpu(p).opsize = taicpu(hp1).opsize) and
RefsEqual(taicpu(hp1).oper[0]^.ref^,taicpu(p).oper[1]^.ref^) then
begin
allocregbetween(asml,taicpu(hp1).oper[1]^.reg,p,hp1);
{ allocregbetween doesn't insert this because at }
{ this time, no regalloc info is available in }
{ the optinfo field, so do it manually (JM) }
hp2 := tai_regalloc.Alloc(taicpu(hp1).oper[1]^.reg,nil);
insertllitem(asml,p.previous,p,hp2);
allocregbetween(asml,taicpu(hp1).oper[1]^.reg,p,hp1,usedregs);
taicpu(hp1).LoadReg(0,taicpu(hp1).oper[1]^.reg);
taicpu(hp1).LoadRef(1,taicpu(p).oper[1]^.ref^);
taicpu(p).LoadReg(1,taicpu(hp1).oper[0]^.reg);
@ -2004,7 +1999,10 @@ end.
{
$Log$
Revision 1.63 2004-10-05 20:41:02 peter
Revision 1.64 2004-10-10 15:01:19 jonas
* several fixes to allocregbetween()
Revision 1.63 2004/10/05 20:41:02 peter
* more spilling rewrites
Revision 1.62 2004/10/05 17:31:41 peter

View File

@ -320,8 +320,10 @@ begin
end
else
getLastInstruction(hp,hp);
allocRegBetween(asmL,newreg(R_INTREGISTER,reg1,R_SUBWHOLE),start,lastreg1);
allocRegBetween(asmL,newreg(R_INTREGISTER,reg2,R_SUBWHOLE),start,lastreg2);
allocRegBetween(asmL,newreg(R_INTREGISTER,reg1,R_SUBWHOLE),start,lastreg1,
ptaiprop(start.optinfo)^.usedregs);
allocRegBetween(asmL,newreg(R_INTREGISTER,reg2,R_SUBWHOLE),start,lastreg2,
ptaiprop(start.optinfo)^.usedregs);
end;
end;
@ -364,7 +366,10 @@ End.
{
$Log$
Revision 1.28 2004-08-17 16:34:58 jonas
Revision 1.29 2004-10-10 15:01:19 jonas
* several fixes to allocregbetween()
Revision 1.28 2004/08/17 16:34:58 jonas
* do not rename registers across conditional jumps
Revision 1.27 2004/06/20 08:55:31 florian