* fixed some more optimizer bugs, make cycle now works with -O2p3,

-O2p3u, -O3p3 and -O3p3u
This commit is contained in:
Jonas Maebe 2003-12-20 22:53:33 +00:00
parent 9fd5217032
commit bade472032
2 changed files with 122 additions and 76 deletions

View File

@ -68,7 +68,7 @@ end;
} }
function modifiesConflictingMemLocation(p1: tai; supreg: tsuperregister; c: tregContent; function modifiesConflictingMemLocation(p1: tai; supreg: tsuperregister; c: tregContent;
var regsStillValid: tregset; onlymem: boolean): boolean; var regsStillValid: tregset; onlymem: boolean; var invalsmemwrite: boolean): boolean;
var var
p, hp: taicpu; p, hp: taicpu;
tmpRef: treference; tmpRef: treference;
@ -77,6 +77,7 @@ var
dummy: boolean; dummy: boolean;
begin begin
modifiesConflictingMemLocation := false; modifiesConflictingMemLocation := false;
invalsmemwrite := false;
if p1.typ <> ait_instruction then if p1.typ <> ait_instruction then
exit; exit;
p := taicpu(p1); p := taicpu(p1);
@ -93,13 +94,15 @@ begin
exclude(regsStillValid,regCounter); exclude(regsStillValid,regCounter);
modifiesConflictingMemLocation := not(supreg in regsStillValid); modifiesConflictingMemLocation := not(supreg in regsStillValid);
end; end;
if (regcounter = supreg) then
invalsmemwrite := invalsmemwrite or dummy;
end end
else else
{ if is_reg_var[getsupreg(p.oper[1]^.reg)] then } { if is_reg_var[getsupreg(p.oper[1]^.reg)] then }
if not onlymem then if not onlymem then
for regCounter := RS_EAX to RS_EDI do for regCounter := RS_EAX to RS_EDI do
begin begin
if writeDestroysContents(p.oper[1]^,regCounter,c[regCounter]) then if writeDestroysContents(p.oper[1]^,regCounter,c[regCounter],dummy) then
begin begin
exclude(regsStillValid,regCounter); exclude(regsStillValid,regCounter);
modifiesConflictingMemLocation := not(supreg in regsStillValid); modifiesConflictingMemLocation := not(supreg in regsStillValid);
@ -129,7 +132,7 @@ begin
{ last operand is always destination } { last operand is always destination }
for regCounter := RS_EAX to RS_EDI do for regCounter := RS_EAX to RS_EDI do
begin begin
if writeDestroysContents(p.oper[p.ops-1]^,regCounter,c[regCounter]) then if writeDestroysContents(p.oper[p.ops-1]^,regCounter,c[regCounter],dummy) then
begin begin
exclude(regsStillValid,regCounter); exclude(regsStillValid,regCounter);
modifiesConflictingMemLocation := not(supreg in regsStillValid); modifiesConflictingMemLocation := not(supreg in regsStillValid);
@ -144,33 +147,45 @@ begin
(p.oper[0]^.typ = top_ref) then (p.oper[0]^.typ = top_ref) then
{ or ((p.oper[0]^.typ = top_reg) and } { or ((p.oper[0]^.typ = top_reg) and }
{ is_reg_var[getsupreg(p.oper[0]^.reg)]) then } { is_reg_var[getsupreg(p.oper[0]^.reg)]) then }
for regCounter := RS_EAX to RS_EDI do for regCounter := RS_EAX to RS_EDI do
if writeDestroysContents(p.oper[0]^,regCounter,c[regCounter]) then
begin begin
exclude(regsStillValid,regCounter); if writeDestroysContents(p.oper[0]^,regCounter,c[regCounter],dummy) then
modifiesConflictingMemLocation := not(supreg in regsStillValid); begin
exclude(regsStillValid,regCounter);
modifiesConflictingMemLocation := not(supreg in regsStillValid);
end;
if (regcounter = supreg) then
invalsmemwrite := invalsmemwrite or dummy;
end; end;
Ch_MOp2,CH_WOp2,CH_RWOp2: Ch_MOp2,CH_WOp2,CH_RWOp2:
if not(onlymem) or if not(onlymem) or
(p.oper[1]^.typ = top_ref) then (p.oper[1]^.typ = top_ref) then
{ or ((p.oper[1]^.typ = top_reg) and } { or ((p.oper[1]^.typ = top_reg) and }
{ is_reg_var[getsupreg(p.oper[1]^.reg)]) then } { is_reg_var[getsupreg(p.oper[1]^.reg)]) then }
for regCounter := RS_EAX to RS_EDI do for regCounter := RS_EAX to RS_EDI do
if writeDestroysContents(p.oper[1]^,regCounter,c[regCounter]) then
begin begin
exclude(regsStillValid,regCounter); if writeDestroysContents(p.oper[1]^,regCounter,c[regCounter],dummy) then
modifiesConflictingMemLocation := not(supreg in regsStillValid); begin
exclude(regsStillValid,regCounter);
modifiesConflictingMemLocation := not(supreg in regsStillValid);
end;
if (regcounter = supreg) then
invalsmemwrite := invalsmemwrite or dummy;
end; end;
Ch_MOp3,CH_WOp3,CH_RWOp3: Ch_MOp3,CH_WOp3,CH_RWOp3:
if not(onlymem) or if not(onlymem) or
(p.oper[2]^.typ = top_ref) then (p.oper[2]^.typ = top_ref) then
{ or ((p.oper[2]^.typ = top_reg) and } { or ((p.oper[2]^.typ = top_reg) and }
{ is_reg_var[getsupreg(p.oper[2]^.reg)]) then } { is_reg_var[getsupreg(p.oper[2]^.reg)]) then }
for regCounter := RS_EAX to RS_EDI do for regCounter := RS_EAX to RS_EDI do
if writeDestroysContents(p.oper[2]^,regCounter,c[regCounter]) then
begin begin
exclude(regsStillValid,regCounter); if writeDestroysContents(p.oper[2]^,regCounter,c[regCounter],dummy) then
modifiesConflictingMemLocation := not(supreg in regsStillValid); begin
exclude(regsStillValid,regCounter);
modifiesConflictingMemLocation := not(supreg in regsStillValid);
end;
if (regcounter = supreg) then
invalsmemwrite := invalsmemwrite or dummy;
end; end;
Ch_WMemEDI: Ch_WMemEDI:
begin begin
@ -183,6 +198,8 @@ begin
exclude(regsStillValid,regCounter); exclude(regsStillValid,regCounter);
modifiesConflictingMemLocation := not(supreg in regsStillValid); modifiesConflictingMemLocation := not(supreg in regsStillValid);
end; end;
if (regcounter = supreg) then
invalsmemwrite := invalsmemwrite or dummy;
end; end;
end; end;
end; end;
@ -213,7 +230,8 @@ var
regsNotRead, regsStillValid : tregset; regsNotRead, regsStillValid : tregset;
checkingPrevSequences, checkingPrevSequences,
passedFlagsModifyingInstr, passedFlagsModifyingInstr,
passedJump : boolean; passedJump,
invalsmemwrite : boolean;
function getPrevSequence(p: tai; supreg: tsuperregister; currentPrev: tai; var newPrev: tai): tsuperregister; function getPrevSequence(p: tai; supreg: tsuperregister; currentPrev: tai; var newPrev: tai): tsuperregister;
@ -267,6 +285,7 @@ var
var var
hp, prevFound: tai; hp, prevFound: tai;
tmpResult, regCounter: tsuperregister; tmpResult, regCounter: tsuperregister;
invalsmemwrite: boolean;
begin begin
if (current_reg <> RS_EDI) and if (current_reg <> RS_EDI) and
(current_reg <> RS_INVALID) then (current_reg <> RS_INVALID) then
@ -296,7 +315,7 @@ var
stillValid(hp) and stillValid(hp) and
(ptaiprop(prevFound.optinfo)^.canBeRemoved or (ptaiprop(prevFound.optinfo)^.canBeRemoved or
not(modifiesConflictingMemLocation(prevFound,supreg, not(modifiesConflictingMemLocation(prevFound,supreg,
ptaiprop(p.optinfo)^.regs,regsStillValid,false))) do ptaiprop(p.optinfo)^.regs,regsStillValid,false, invalsmemwrite))) do
begin begin
{ only update the regsread for the instructions we already passed } { only update the regsread for the instructions we already passed }
if not(ptaiprop(prevFound.optinfo)^.canBeRemoved) then if not(ptaiprop(prevFound.optinfo)^.canBeRemoved) then
@ -363,6 +382,7 @@ var
var var
orgdiffregs,diffregs: tregset; orgdiffregs,diffregs: tregset;
runner: tai; runner: tai;
invalsmemwrite: boolean;
begin begin
diffregs := newreginfo.newregsencountered - oldreginfo.newregsencountered; diffregs := newreginfo.newregsencountered - oldreginfo.newregsencountered;
orgdiffregs := diffregs; orgdiffregs := diffregs;
@ -370,7 +390,7 @@ var
begin begin
runner := startp; runner := startp;
repeat repeat
modifiesConflictingMemLocation(runner,RS_EAX { dummy },ptaiprop(current.optinfo)^.regs,diffregs,true); modifiesConflictingMemLocation(runner,RS_EAX { dummy },ptaiprop(current.optinfo)^.regs,diffregs,true,invalsmemwrite);
if orgdiffregs <> diffregs then if orgdiffregs <> diffregs then
begin begin
changedreginvalidatedbetween := true; changedreginvalidatedbetween := true;
@ -463,9 +483,11 @@ begin {CheckSequence}
((taicpu(hp3).oper[0]^.ref^.index = NR_NO) or ((taicpu(hp3).oper[0]^.ref^.index = NR_NO) or
regModified[index]) and regModified[index]) and
not(regInRef(tmpReg,taicpu(hp3).oper[0]^.ref^)) then not(regInRef(tmpReg,taicpu(hp3).oper[0]^.ref^)) then
with ptaiprop(hp3.optinfo)^.regs[tmpreg] do begin
if nrofMods > (oldNrofMods - found) then with ptaiprop(hp3.optinfo)^.regs[tmpreg] do
oldNrofMods := found + nrofMods; if nrofMods > (oldNrofMods - found) then
oldNrofMods := found + nrofMods;
end;
end; end;
top_reg: top_reg:
if regModified[getsupreg(taicpu(hp3).oper[0]^.reg)] then if regModified[getsupreg(taicpu(hp3).oper[0]^.reg)] then
@ -637,7 +659,7 @@ begin
exclude(regsUsable,regCounter); exclude(regsUsable,regCounter);
{$ifdef alignregdebug} {$ifdef alignregdebug}
temp := tai_comment.Create(strpnew( temp := tai_comment.Create(strpnew(
std_reg2str[regCounter]+' removed'))); std_regname(newreg(R_INTREGISTER,regCounter,R_SUBWHOLE))+' removed')));
temp.next := prev.next; temp.next := prev.next;
temp.previous := prev; temp.previous := prev;
prev.next := temp; prev.next := temp;
@ -687,7 +709,7 @@ begin
exclude(regsUsable,regCounter); exclude(regsUsable,regCounter);
{$ifdef alignregdebug} {$ifdef alignregdebug}
temp := tai_comment.Create(strpnew( temp := tai_comment.Create(strpnew(
std_reg2str[regCounter]+' removed'))); std_regname(newreg(R_INTREGISTER,regCounter,R_SUBWHOLE))+' removed')));
temp.next := next.next; temp.next := next.next;
temp.previous := next; temp.previous := next;
next.next := temp; next.next := temp;
@ -730,7 +752,7 @@ begin
break break
end; end;
{$ifdef alignregdebug} {$ifdef alignregdebug}
next := tai_comment.Create(strpnew(std_reg2str[lastRemoved]+ next := tai_comment.Create(strpnew(std_regname(newreg(R_INTREGISTER,lastremoved,R_SUBWHOLE))+
' chosen as alignment register'))); ' chosen as alignment register')));
next.next := p.next; next.next := p.next;
next.previous := p; next.previous := p;
@ -768,12 +790,12 @@ begin
{$ifdef replaceregdebug} {$ifdef replaceregdebug}
l := random(1000); l := random(1000);
hp := tai_comment.Create(strpnew( hp := tai_comment.Create(strpnew(
'cleared '+std_reg2str[reg]+' from here... '+tostr(l)))); 'cleared '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+' from here... '+tostr(l)));
hp.next := p; hp.next := p;
hp.previous := p.previous; hp.previous := p.previous;
p.previous := hp; p.previous := hp;
if assigned(hp.previous) then if assigned(hp.previous) then
hp.previous^.next := hp; hp.previous.next := hp;
{$endif replaceregdebug} {$endif replaceregdebug}
ptaiprop(p.optinfo)^.Regs[supreg].typ := con_unknown; ptaiprop(p.optinfo)^.Regs[supreg].typ := con_unknown;
while (p <> endP) do while (p <> endP) do
@ -803,12 +825,12 @@ begin
if assigned(p) then if assigned(p) then
begin begin
hp := tai_comment.Create(strpnew( hp := tai_comment.Create(strpnew(
'cleared '+std_reg2str[reg]+' till here... '+tostr(l)))); 'cleared '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+' till here... '+tostr(l)));
hp.next := p; hp.next := p;
hp.previous := p.previous; hp.previous := p.previous;
p.previous := hp; p.previous := hp;
if assigned(hp.previous) then if assigned(hp.previous) then
hp.previous^.next := hp; hp.previous.next := hp;
end; end;
{$endif replaceregdebug} {$endif replaceregdebug}
end; end;
@ -819,18 +841,21 @@ var
hp: tai; hp: tai;
l: longint; l: longint;
{$endif replaceregdebug} {$endif replaceregdebug}
dummyregs: tregset;
tmpState: byte; tmpState: byte;
prevcontenttyp: byte; prevcontenttyp: byte;
memconflict: boolean;
invalsmemwrite: boolean;
begin begin
{$ifdef replaceregdebug} {$ifdef replaceregdebug}
l := random(1000); l := random(1000);
hp := tai_comment.Create(strpnew( hp := tai_comment.Create(strpnew(
'restored '+std_reg2str[supreg]+' with data from here... '+tostr(l)))); 'restored '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+' with data from here... '+tostr(l)));
hp.next := p; hp.next := p;
hp.previous := p.previous; hp.previous := p.previous;
p.previous := hp; p.previous := hp;
if assigned(hp.previous) then if assigned(hp.previous) then
hp.previous^.next := hp; hp.previous.next := hp;
{$endif replaceregdebug} {$endif replaceregdebug}
{ ptaiprop(p.optinfo)^.Regs[reg] := c;} { ptaiprop(p.optinfo)^.Regs[reg] := c;}
while (p <> endP) do while (p <> endP) do
@ -839,27 +864,35 @@ begin
getNextInstruction(p,p); getNextInstruction(p,p);
end; end;
tmpState := ptaiprop(p.optinfo)^.Regs[supreg].wState; tmpState := ptaiprop(p.optinfo)^.Regs[supreg].wState;
repeat dummyregs := [supreg];
repeat
prevcontenttyp := ptaiprop(p.optinfo)^.Regs[supreg].typ; prevcontenttyp := ptaiprop(p.optinfo)^.Regs[supreg].typ;
ptaiprop(p.optinfo)^.Regs[supreg] := c; // is this a write to memory that destroys the contents we are restoring?
until not getNextInstruction(p,p) or memconflict := modifiesConflictingMemLocation(p,supreg,ptaiprop(p.optinfo)^.regs,dummyregs,true,invalsmemwrite);
if not memconflict and not invalsmemwrite then
ptaiprop(p.optinfo)^.Regs[supreg] := c;
until invalsmemwrite or
memconflict or
not getNextInstruction(p,p) or
(ptaiprop(p.optinfo)^.Regs[supreg].wState <> tmpState) or (ptaiprop(p.optinfo)^.Regs[supreg].wState <> tmpState) or
(p.typ = ait_label) or (p.typ = ait_label) or
((prevcontenttyp <> con_invalid) and ((prevcontenttyp <> con_invalid) and
(ptaiprop(p.optinfo)^.Regs[supreg].typ = con_invalid)); (ptaiprop(p.optinfo)^.Regs[supreg].typ = con_invalid));
if assigned(p) and if assigned(p) and
(p.typ = ait_label) then ((p.typ = ait_label) or
memconflict or
invalsmemwrite) then
clearRegContentsFrom(supreg,p,p); clearRegContentsFrom(supreg,p,p);
{$ifdef replaceregdebug} {$ifdef replaceregdebug}
if assigned(p) then if assigned(p) then
begin begin
hp := tai_comment.Create(strpnew( hp := tai_comment.Create(strpnew(
'restored '+std_reg2str[reg]+' till here... '+tostr(l)))); 'restored '+std_regname(newreg(R_INTREGISTER,supreg,R_SUBWHOLE))+' till here... '+tostr(l)));
hp.next := p; hp.next := p;
hp.previous := p.previous; hp.previous := p.previous;
p.previous := hp; p.previous := hp;
if assigned(hp.previous) then if assigned(hp.previous) then
hp.previous^.next := hp; hp.previous.next := hp;
end; end;
{$endif replaceregdebug} {$endif replaceregdebug}
end; end;
@ -1159,9 +1192,9 @@ begin
end; end;
function ReplaceReg(asml: TAAsmOutput; orgsupreg, newsupreg: tsuperregister; p: tai; function ReplaceReg(asml: TAAsmOutput; orgsupreg, newsupreg: tsuperregister; p,
const c: TContent; orgRegCanBeModified: Boolean; seqstart: tai; const c: TContent; orgRegCanBeModified: Boolean;
var returnEndP: tai): Boolean; var returnEndP: tai): Boolean;
{ Tries to replace orgsupreg with newsupreg in all instructions coming after p } { Tries to replace orgsupreg with newsupreg in all instructions coming after p }
{ until orgsupreg gets loaded with a new value. Returns true if successful, } { until orgsupreg gets loaded with a new value. Returns true if successful, }
{ false otherwise. if successful, the contents of newsupreg are set to c, } { false otherwise. if successful, the contents of newsupreg are set to c, }
@ -1196,7 +1229,7 @@ begin
hp.previous := endp.previous; hp.previous := endp.previous;
endp.previous := hp; endp.previous := hp;
if assigned(hp.previous) then if assigned(hp.previous) then
hp.previous^.next := hp;} hp.previous.next := hp;}
exit; exit;
end; end;
if tmpResult and if tmpResult and
@ -1268,17 +1301,17 @@ begin
begin begin
{$ifdef replaceregdebug} {$ifdef replaceregdebug}
hp := tai_comment.Create(strpnew( hp := tai_comment.Create(strpnew(
'replacing '+std_reg2str[newsupreg]+' with '+std_reg2str[orgsupreg]+ 'replacing '+std_regname(newreg(R_INTREGISTER,newsupreg,R_SUBWHOLE))+' with '+std_regname(newreg(R_INTREGISTER,orgsupreg,R_SUBWHOLE))+
' from here...'))); ' from here...'));
hp.next := p; hp.next := p;
hp.previous := p.previous; hp.previous := p.previous;
p.previous := hp; p.previous := hp;
if assigned(hp.previous) then if assigned(hp.previous) then
hp.previous^.next := hp; hp.previous.next := hp;
hp := tai_comment.Create(strpnew( hp := tai_comment.Create(strpnew(
'replaced '+std_reg2str[newsupreg]+' with '+std_reg2str[orgsupreg]+ 'replaced '+std_regname(newreg(R_INTREGISTER,newsupreg,R_SUBWHOLE))+' with '+std_regname(newreg(R_INTREGISTER,orgsupreg,R_SUBWHOLE))+
' till here'))); ' till here'));
hp.next := endp.next; hp.next := endp.next;
hp.previous := endp; hp.previous := endp;
endp.next := hp; endp.next := hp;
@ -1309,26 +1342,18 @@ begin
if stateChanged or readStateChanged then if stateChanged or readStateChanged then
updateState(orgsupreg,endP); updateState(orgsupreg,endP);
{ the replacing stops either at the moment that } { We replaced newreg with oldreg between p and endp, so restore the contents }
{ a) the newsupreg gets loaded with a new value (one not depending on the } { of newreg there with its contents from before the sequence. }
{ current value of newsupreg) }
{ b) newsupreg is completely replaced in this sequence and it's current value }
{ isn't used anymore }
{ in case b, the newsupreg was completely replaced by oldreg, so it's contents }
{ are unchanged compared the start of this sequence, so restore them }
if removeLast or if removeLast or
RegLoadedWithNewValue(newsupreg,true,endP) then RegLoadedWithNewValue(newsupreg,true,endP) then
GetLastInstruction(endP,hp) GetLastInstruction(endP,hp)
else hp := endP; else hp := endP;
if removeLast or RestoreRegContentsTo(newsupreg,c,seqstart,hp);
(p <> endp) or
not RegLoadedWithNewValue(newsupreg,true,endP) then
RestoreRegContentsTo(newsupreg,c,p,hp);
{ in both case a and b, it is possible that the new register was modified } { Ot is possible that the new register was modified (e.g. an add/sub), so if }
{ (e.g. an add/sub), so if it was replaced by oldreg in that instruction, } { it was replaced by oldreg in that instruction, oldreg's contents have been }
{ oldreg's contents have been changed. To take this into account, we simply } { changed. To take this into account, we simply set the contents of orgsupreg }
{ set the contents of orgsupreg to "unknown" after this sequence } { to "unknown" after this sequence }
if newRegModified then if newRegModified then
ClearRegContentsFrom(orgsupreg,p,hp); ClearRegContentsFrom(orgsupreg,p,hp);
if removeLast then if removeLast then
@ -1340,17 +1365,17 @@ begin
else else
begin begin
hp := tai_comment.Create(strpnew( hp := tai_comment.Create(strpnew(
'replacing '+std_reg2str[newsupreg]+' with '+std_reg2str[orgsupreg]+ 'replacing '+std_regname(newreg(R_INTREGISTER,newsupreg,R_SUBWHOLE))+' with '+std_regname(newreg(R_INTREGISTER,orgsupreg,R_SUBWHOLE))+
' from here...'))); ' from here...'));
hp.previous := p.previous; hp.previous := p.previous;
hp.next := p; hp.next := p;
p.previous := hp; p.previous := hp;
if assigned(hp.previous) then if assigned(hp.previous) then
hp.previous^.next := hp; hp.previous.next := hp;
hp := tai_comment.Create(strpnew( hp := tai_comment.Create(strpnew(
'replacing '+std_reg2str[newsupreg]+' with '+std_reg2str[orgsupreg]+ 'replacing '+std_regname(newreg(R_INTREGISTER,newsupreg,R_SUBWHOLE))+' with '+std_regname(newreg(R_INTREGISTER,orgsupreg,R_SUBWHOLE))+
' failed here'))); ' failed here'));
hp.next := endp.next; hp.next := endp.next;
hp.previous := endp; hp.previous := endp;
endp.next := hp; endp.next := hp;
@ -1376,12 +1401,12 @@ begin
if (ptaiprop(p.optinfo)^.regs[counter].typ in [con_const,con_noRemoveConst]) then if (ptaiprop(p.optinfo)^.regs[counter].typ in [con_const,con_noRemoveConst]) then
begin begin
hp := tai_comment.Create(strpnew( hp := tai_comment.Create(strpnew(
'checking const load of '+tostr(l)+' here...'))); 'checking const load of '+tostr(l)+' here...'));
hp.next := ptaiprop(p.optinfo)^.Regs[Counter].StartMod; hp.next := ptaiprop(p.optinfo)^.Regs[Counter].StartMod;
hp.previous := ptaiprop(p.optinfo)^.Regs[Counter].StartMod^.previous; hp.previous := ptaiprop(p.optinfo)^.Regs[Counter].StartMod^.previous;
ptaiprop(p.optinfo)^.Regs[Counter].StartMod^.previous := hp; ptaiprop(p.optinfo)^.Regs[Counter].StartMod^.previous := hp;
if assigned(hp.previous) then if assigned(hp.previous) then
hp.previous^.next := hp; hp.previous.next := hp;
end; end;
{$endif testing} {$endif testing}
if (ptaiprop(p.optinfo)^.regs[counter].typ in [con_const,con_noRemoveConst]) and if (ptaiprop(p.optinfo)^.regs[counter].typ in [con_const,con_noRemoveConst]) and
@ -1564,7 +1589,7 @@ begin
{not(regCounter in rg.usableregsint + [RS_EDI,RS_ESI]) or} {not(regCounter in rg.usableregsint + [RS_EDI,RS_ESI]) or}
not(regCounter in [RS_EAX,RS_EBX,RS_ECX,RS_EDX,RS_EDI,RS_ESI]) or not(regCounter in [RS_EAX,RS_EBX,RS_ECX,RS_EDX,RS_EDI,RS_ESI]) or
not ReplaceReg(asml,reginfo.new2oldreg[regcounter], not ReplaceReg(asml,reginfo.new2oldreg[regcounter],
regCounter,hp, regCounter,hp,curseqstart,
ptaiprop(prevseqstart.optinfo)^.Regs[regCounter],true,hp2) then ptaiprop(prevseqstart.optinfo)^.Regs[regCounter],true,hp2) then
begin begin
if not(reginfo.new2oldreg[regcounter] in regsloaded) or if not(reginfo.new2oldreg[regcounter] in regsloaded) or
@ -1598,6 +1623,20 @@ begin
updateState(reginfo.new2oldreg[regcounter],hp2); updateState(reginfo.new2oldreg[regcounter],hp2);
updateState(regcounter,hp2); updateState(regcounter,hp2);
end end
else
begin
// replace the new register with the old register in the
// sequence itself as well so later comparisons get the
// correct knowledge about which registers are used
hp2 := curseqstart;
// curseqend = instruction following last instruction of this
// sequence
while hp2 <> curseqend do
begin
doreplacereg(taicpu(hp2),regcounter,reginfo.new2oldreg[regcounter]);
getnextinstruction(hp2,hp2);
end;
end;
end end
else else
{ imagine the following code: } { imagine the following code: }
@ -1778,7 +1817,7 @@ begin
{ we only have to start replacing from the instruction after the mov, } { we only have to start replacing from the instruction after the mov, }
{ but replacereg only starts with getnextinstruction(p,p) } { but replacereg only starts with getnextinstruction(p,p) }
replaceReg(asml,getsupreg(taicpu(p).oper[0]^.reg), replaceReg(asml,getsupreg(taicpu(p).oper[0]^.reg),
getsupreg(taicpu(p).oper[1]^.reg),p, getsupreg(taicpu(p).oper[1]^.reg),p,p,
ptaiprop(hp4.optinfo)^.regs[getsupreg(taicpu(p).oper[1]^.reg)],false,hp1) then ptaiprop(hp4.optinfo)^.regs[getsupreg(taicpu(p).oper[1]^.reg)],false,hp1) then
begin begin
ptaiprop(p.optinfo)^.canBeRemoved := true; ptaiprop(p.optinfo)^.canBeRemoved := true;
@ -2074,7 +2113,11 @@ end.
{ {
$Log$ $Log$
Revision 1.58 2003-12-15 21:25:49 peter Revision 1.59 2003-12-20 22:53:33 jonas
* fixed some more optimizer bugs, make cycle now works with -O2p3,
-O2p3u, -O3p3 and -O3p3u
Revision 1.58 2003/12/15 21:25:49 peter
* reg allocations for imaginary register are now inserted just * reg allocations for imaginary register are now inserted just
before reg allocation before reg allocation
* tregister changed to enum to allow compile time check * tregister changed to enum to allow compile time check

View File

@ -175,7 +175,7 @@ function writeToMemDestroysContents(regWritten: tsuperregister; const ref: trefe
function writeToRegDestroysContents(destReg, supreg: tsuperregister; function writeToRegDestroysContents(destReg, supreg: tsuperregister;
const c: tcontent): boolean; const c: tcontent): boolean;
function writeDestroysContents(const op: toper; supreg: tsuperregister; function writeDestroysContents(const op: toper; supreg: tsuperregister;
const c: tcontent): boolean; const c: tcontent; var memwritedestroyed: boolean): boolean;
function GetNextInstruction(Current: tai; var Next: tai): Boolean; function GetNextInstruction(Current: tai; var Next: tai): Boolean;
@ -1805,19 +1805,18 @@ end;
function writeDestroysContents(const op: toper; supreg: tsuperregister; function writeDestroysContents(const op: toper; supreg: tsuperregister;
const c: tcontent): boolean; const c: tcontent; var memwritedestroyed: boolean): boolean;
{ returns whether the contents c of reg are invalid after regWritten is } { returns whether the contents c of reg are invalid after regWritten is }
{ is written to op } { is written to op }
var
dummy: boolean;
begin begin
memwritedestroyed := false;
case op.typ of case op.typ of
top_reg: top_reg:
writeDestroysContents := writeDestroysContents :=
writeToRegDestroysContents(getsupreg(op.reg),supreg,c); writeToRegDestroysContents(getsupreg(op.reg),supreg,c);
top_ref: top_ref:
writeDestroysContents := writeDestroysContents :=
writeToMemDestroysContents(RS_INVALID,op.ref^,supreg,c,dummy); writeToMemDestroysContents(RS_INVALID,op.ref^,supreg,c,memwritedestroyed);
else else
writeDestroysContents := false; writeDestroysContents := false;
end; end;
@ -2714,7 +2713,11 @@ end.
{ {
$Log$ $Log$
Revision 1.61 2003-12-15 21:25:49 peter Revision 1.62 2003-12-20 22:53:33 jonas
* fixed some more optimizer bugs, make cycle now works with -O2p3,
-O2p3u, -O3p3 and -O3p3u
Revision 1.61 2003/12/15 21:25:49 peter
* reg allocations for imaginary register are now inserted just * reg allocations for imaginary register are now inserted just
before reg allocation before reg allocation
* tregister changed to enum to allow compile time check * tregister changed to enum to allow compile time check