* fixed several regvar related bugs, cycle with -OZp3r doesn't work

yet though
This commit is contained in:
Jonas Maebe 2004-12-28 18:01:40 +00:00
parent 080ed4548f
commit 53c04512cc
2 changed files with 43 additions and 30 deletions

View File

@ -542,6 +542,7 @@ begin {CheckSequence}
else if assigned(hp3) then else if assigned(hp3) then
for regcounter2 := RS_EAX to RS_EDI do for regcounter2 := RS_EAX to RS_EDI do
if (regcounter2 in reginfo.regsLoadedforRef) and if (regcounter2 in reginfo.regsLoadedforRef) and
regModified[regcounter2] and
(regcounter2 in ptaiprop(hp3.optinfo)^.usedRegs) and (regcounter2 in ptaiprop(hp3.optinfo)^.usedRegs) and
not regLoadedWithNewValue(regcounter2,false,hp3) then not regLoadedWithNewValue(regcounter2,false,hp3) then
begin begin
@ -1607,14 +1608,16 @@ end;
procedure loadcseregs(asml: taasmoutput; const reginfo: toptreginfo; curseqend, prevseqstart, curseqstart, curprev: tai; cnt: longint); procedure loadcseregs(asml: taasmoutput; const reginfo: toptreginfo; curseqend, prevseqstart, curseqstart, curprev: tai; cnt: longint);
var var
regsloaded: tregset; regsloaded: tregset;
regloads: array[RS_EAX..RS_EDI] of tai; regloads, reguses: array[RS_EAX..RS_EDI] of tai;
regcounter: tsuperregister; regcounter, substreg: tsuperregister;
hp, hp2: tai; hp, hp2: tai;
insertpos, prevseq_next: tai; insertpos, prevseq_next: tai;
i: longint; i: longint;
opc: tasmop;
begin begin
regsloaded := []; regsloaded := [];
fillchar(regloads,sizeof(regloads),0); fillchar(regloads,sizeof(regloads),0);
fillchar(reguses,sizeof(reguses),0);
getnextinstruction(prevseqstart,prevseq_next); getnextinstruction(prevseqstart,prevseq_next);
for regcounter := RS_EAX To RS_EDI do for regcounter := RS_EAX To RS_EDI do
if (reginfo.new2oldreg[regcounter] <> RS_INVALID) Then if (reginfo.new2oldreg[regcounter] <> RS_INVALID) Then
@ -1653,22 +1656,23 @@ begin
regCounter,hp,curseqstart, 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 opc := A_MOV;
{ happens if the register has been replaced } insertpos := prevseq_next;
not(assigned(regloads[reginfo.new2oldreg[regcounter]])) then if assigned(reguses[regcounter]) then
insertpos := prevseq_next if assigned(regloads[reginfo.new2oldreg[regcounter]]) then
opc := A_XCHG
else else
begin insertpos := tai(reguses[regcounter].next)
{$warning add cycle detection for register loads and use xchg if necessary} else
if assigned(regloads[reginfo.new2oldreg[regcounter]]) then
insertpos := regloads[reginfo.new2oldreg[regcounter]]; insertpos := regloads[reginfo.new2oldreg[regcounter]];
end;
hp := Tai_Marker.Create(NoPropInfoStart); hp := Tai_Marker.Create(NoPropInfoStart);
InsertLLItem(asml, insertpos.previous,insertpos, hp); InsertLLItem(asml, insertpos.previous,insertpos, hp);
hp2 := taicpu.Op_Reg_Reg(A_MOV, S_L, hp2 := taicpu.Op_Reg_Reg(opc, S_L,
{old reg new reg} {old reg new reg}
newreg(R_INTREGISTER,reginfo.new2oldreg[regcounter],R_SUBWHOLE), newreg(R_INTREGISTER,regcounter,R_SUBWHOLE)); newreg(R_INTREGISTER,reginfo.new2oldreg[regcounter],R_SUBWHOLE), newreg(R_INTREGISTER,regcounter,R_SUBWHOLE));
regloads[regcounter] := hp2; regloads[regcounter] := hp2;
reguses[reginfo.new2oldreg[regcounter]] := hp2;
new(ptaiprop(hp2.optinfo)); new(ptaiprop(hp2.optinfo));
ptaiprop(hp2.optinfo)^ := ptaiprop(insertpos.optinfo)^; ptaiprop(hp2.optinfo)^ := ptaiprop(insertpos.optinfo)^;
ptaiprop(hp2.optinfo)^.canBeRemoved := false; ptaiprop(hp2.optinfo)^.canBeRemoved := false;
@ -2182,7 +2186,11 @@ end.
{ {
$Log$ $Log$
Revision 1.71 2004-12-27 15:20:03 jonas Revision 1.72 2004-12-28 18:01:40 jonas
* fixed several regvar related bugs, cycle with -OZp3r doesn't work
yet though
Revision 1.71 2004/12/27 15:20:03 jonas
* fixed internalerror when cycling with -O3p3u * fixed internalerror when cycling with -O3p3u
Revision 1.70 2004/12/18 15:16:10 jonas Revision 1.70 2004/12/18 15:16:10 jonas

View File

@ -170,7 +170,6 @@ type
procedure InsertLLItem(AsmL: TAAsmOutput; prev, foll, new_one: TLinkedListItem); procedure InsertLLItem(AsmL: TAAsmOutput; prev, foll, new_one: TLinkedListItem);
function RefsEquivalent(const R1, R2: TReference; var RegInfo: toptreginfo; OpAct: TOpAction): Boolean;
function RefsEqual(const R1, R2: TReference): Boolean; function RefsEqual(const R1, R2: TReference): Boolean;
function isgp32reg(supreg: tsuperregister): Boolean; function isgp32reg(supreg: tsuperregister): Boolean;
function reginref(supreg: tsuperregister; const ref: treference): boolean; function reginref(supreg: tsuperregister; const ref: treference): boolean;
@ -201,7 +200,6 @@ procedure UpdateUsedRegs(var UsedRegs: TRegSet; p: tai);
procedure AllocRegBetween(asml: taasmoutput; reg: tregister; p1, p2: tai; const initialusedregs: tregset); procedure AllocRegBetween(asml: taasmoutput; reg: tregister; p1, p2: tai; const initialusedregs: tregset);
function FindRegDealloc(supreg: tsuperregister; p: tai): boolean; function FindRegDealloc(supreg: tsuperregister; p: tai): boolean;
//function RegsEquivalent(OldReg, NewReg: tregister; var RegInfo: toptreginfo; OpAct: TopAction): Boolean;
function InstructionsEquivalent(p1, p2: tai; var RegInfo: toptreginfo): Boolean; function InstructionsEquivalent(p1, p2: tai; var RegInfo: toptreginfo): Boolean;
function sizescompatible(loadsize,newsize: topsize): boolean; function sizescompatible(loadsize,newsize: topsize): boolean;
function OpsEqual(const o1,o2:toper): Boolean; function OpsEqual(const o1,o2:toper): Boolean;
@ -618,7 +616,7 @@ begin
end; end;
function RegsEquivalent(oldreg, newreg: tregister; var reginfo: toptreginfo; opact: topaction): Boolean; function RegsEquivalent(oldreg, newreg: tregister; const oldinst, newinst: taicpu; var reginfo: toptreginfo; opact: topaction): Boolean;
begin begin
if not((oldreg = NR_NO) or (newreg = NR_NO)) then if not((oldreg = NR_NO) or (newreg = NR_NO)) then
if RegsSameSize(oldreg, newreg) then if RegsSameSize(oldreg, newreg) then
@ -652,7 +650,10 @@ begin
else else
if not(getsupreg(newreg) in NewRegsEncountered) and if not(getsupreg(newreg) in NewRegsEncountered) and
((opact = opact_write) or ((opact = opact_write) or
(newreg = oldreg)) then ((newreg = oldreg) and
(ptaiprop(oldinst.optinfo)^.regs[getsupreg(oldreg)].wstate =
ptaiprop(newinst.optinfo)^.regs[getsupreg(oldreg)].wstate) and
not(regmodifiedbyinstruction(getsupreg(oldreg),oldinst)))) then
begin begin
AddReg2RegInfo(oldreg, newreg, reginfo); AddReg2RegInfo(oldreg, newreg, reginfo);
RegsEquivalent := true RegsEquivalent := true
@ -666,12 +667,12 @@ begin
end; end;
function RefsEquivalent(const r1, r2: treference; var regInfo: toptreginfo; opact: topaction): boolean; function RefsEquivalent(const r1, r2: treference; const oldinst, newinst: taicpu; var regInfo: toptreginfo): boolean;
begin begin
RefsEquivalent := RefsEquivalent :=
(r1.offset = r2.offset) and (r1.offset = r2.offset) and
RegsEquivalent(r1.base, r2.base, reginfo, opact) and RegsEquivalent(r1.base, r2.base, oldinst, newinst, reginfo, OpAct_Read) and
RegsEquivalent(r1.index, r2.index, reginfo, opact) and RegsEquivalent(r1.index, r2.index, oldinst, newinst, reginfo, OpAct_Read) and
(r1.segment = r2.segment) and (r1.scalefactor = r2.scalefactor) and (r1.segment = r2.segment) and (r1.scalefactor = r2.scalefactor) and
(r1.symbol = r2.symbol) and (r1.refaddr = r2.refaddr) and (r1.symbol = r2.symbol) and (r1.refaddr = r2.refaddr) and
(r1.relsymbol = r2.relsymbol); (r1.relsymbol = r2.relsymbol);
@ -1407,15 +1408,15 @@ begin
end; end;
end;} end;}
function OpsEquivalent(const o1, o2: toper; var RegInfo: toptreginfo; OpAct: TopAction): Boolean; function OpsEquivalent(const o1, o2: toper; const oldinst, newinst: taicpu; var RegInfo: toptreginfo; OpAct: TopAction): Boolean;
begin {checks whether the two ops are equivalent} begin {checks whether the two ops are equivalent}
OpsEquivalent := False; OpsEquivalent := False;
if o1.typ=o2.typ then if o1.typ=o2.typ then
case o1.typ Of case o1.typ Of
top_reg: top_reg:
OpsEquivalent :=RegsEquivalent(o1.reg,o2.reg, RegInfo, OpAct); OpsEquivalent :=RegsEquivalent(o1.reg,o2.reg, oldinst, newinst, RegInfo, OpAct);
top_ref: top_ref:
OpsEquivalent := RefsEquivalent(o1.ref^, o2.ref^, RegInfo, OpAct); OpsEquivalent := RefsEquivalent(o1.ref^, o2.ref^, oldinst, newinst, RegInfo);
Top_Const: Top_Const:
OpsEquivalent := o1.val = o2.val; OpsEquivalent := o1.val = o2.val;
Top_None: Top_None:
@ -1497,7 +1498,7 @@ begin {checks whether two taicpu instructions are equal}
{the "old" instruction is a load of a register with a new value, not with {the "old" instruction is a load of a register with a new value, not with
a value based on the contents of this register (so no "mov (reg), reg")} a value based on the contents of this register (so no "mov (reg), reg")}
if not(RegInRef(getsupreg(taicpu(p2).oper[1]^.reg), taicpu(p2).oper[0]^.ref^)) and if not(RegInRef(getsupreg(taicpu(p2).oper[1]^.reg), taicpu(p2).oper[0]^.ref^)) and
RefsEqual(taicpu(p1).oper[0]^.ref^, taicpu(p2).oper[0]^.ref^) then RefsEquivalent(taicpu(p1).oper[0]^.ref^, taicpu(p2).oper[0]^.ref^,taicpu(p1), taicpu(p2), reginfo) then
{the "new" instruction is also a load of a register with a new value, and {the "new" instruction is also a load of a register with a new value, and
this value is fetched from the same memory location} this value is fetched from the same memory location}
begin begin
@ -1517,7 +1518,7 @@ begin {checks whether two taicpu instructions are equal}
{the registers from .oper[1]^ have to be equivalent, but not necessarily equal} {the registers from .oper[1]^ have to be equivalent, but not necessarily equal}
InstructionsEquivalent := InstructionsEquivalent :=
RegsEquivalent(taicpu(p1).oper[1]^.reg, RegsEquivalent(taicpu(p1).oper[1]^.reg,
taicpu(p2).oper[1]^.reg, RegInfo, OpAct_Write); taicpu(p2).oper[1]^.reg, taicpu(p1), taicpu(p2), RegInfo, OpAct_Write);
end end
{the registers are loaded with values from different memory locations. if {the registers are loaded with values from different memory locations. if
this was allowed, the instructions "mov -4(esi),eax" and "mov -4(ebp),eax" this was allowed, the instructions "mov -4(esi),eax" and "mov -4(ebp),eax"
@ -1560,8 +1561,8 @@ begin {checks whether two taicpu instructions are equal}
{$endif csdebug} {$endif csdebug}
end; end;
InstructionsEquivalent := InstructionsEquivalent :=
OpsEquivalent(taicpu(p1).oper[0]^, taicpu(p2).oper[0]^, RegInfo, OpAct_Read) and OpsEquivalent(taicpu(p1).oper[0]^, taicpu(p2).oper[0]^, taicpu(p1), taicpu(p2), RegInfo, OpAct_Read) and
OpsEquivalent(taicpu(p1).oper[1]^, taicpu(p2).oper[1]^, RegInfo, OpAct_Write) OpsEquivalent(taicpu(p1).oper[1]^, taicpu(p2).oper[1]^, taicpu(p1), taicpu(p2), RegInfo, OpAct_Write)
end end
else else
{an instruction <> mov, movzx, movsx} {an instruction <> mov, movzx, movsx}
@ -1575,11 +1576,11 @@ begin {checks whether two taicpu instructions are equal}
{$endif csdebug} {$endif csdebug}
InstructionsEquivalent := InstructionsEquivalent :=
(not(assigned(taicpu(p1).oper[0])) or (not(assigned(taicpu(p1).oper[0])) or
OpsEquivalent(taicpu(p1).oper[0]^, taicpu(p2).oper[0]^, RegInfo, OpAct_Unknown)) and OpsEquivalent(taicpu(p1).oper[0]^, taicpu(p2).oper[0]^, taicpu(p1), taicpu(p2), RegInfo, OpAct_Unknown)) and
(not(assigned(taicpu(p1).oper[1])) or (not(assigned(taicpu(p1).oper[1])) or
OpsEquivalent(taicpu(p1).oper[1]^, taicpu(p2).oper[1]^, RegInfo, OpAct_Unknown)) and OpsEquivalent(taicpu(p1).oper[1]^, taicpu(p2).oper[1]^, taicpu(p1), taicpu(p2), RegInfo, OpAct_Unknown)) and
(not(assigned(taicpu(p1).oper[2])) or (not(assigned(taicpu(p1).oper[2])) or
OpsEquivalent(taicpu(p1).oper[2]^, taicpu(p2).oper[2]^, RegInfo, OpAct_Unknown)) OpsEquivalent(taicpu(p1).oper[2]^, taicpu(p2).oper[2]^, taicpu(p1), taicpu(p2), RegInfo, OpAct_Unknown))
end end
{the instructions haven't even got the same structure, so they're certainly {the instructions haven't even got the same structure, so they're certainly
not equivalent} not equivalent}
@ -2792,7 +2793,11 @@ end.
{ {
$Log$ $Log$
Revision 1.77 2004-12-18 15:16:10 jonas Revision 1.78 2004-12-28 18:01:41 jonas
* fixed several regvar related bugs, cycle with -OZp3r doesn't work
yet though
Revision 1.77 2004/12/18 15:16:10 jonas
* fixed tracking of usage of flags register * fixed tracking of usage of flags register
* fixed destroying of "memwrite"'s * fixed destroying of "memwrite"'s
* fixed checking of entire sequences in all cases (previously this was * fixed checking of entire sequences in all cases (previously this was