* fixed a serious bug in the CSE which (I think) only showed with

-dnewoptimizations when using multi-dimensional arrays with
    elements of a size different from 1, 2 or 4 (especially strings).
  * made the DFA/CSE more robust (much less dependent on specifics of the
    code generator)
This commit is contained in:
Jonas Maebe 2000-04-10 12:45:56 +00:00
parent 55988e6f55
commit e4ceb46242
2 changed files with 297 additions and 178 deletions

View File

@ -172,6 +172,7 @@ Begin {CheckSequence}
{ be used anymore after the sequence, are still used nevertheless (when } { be used anymore after the sequence, are still used nevertheless (when }
{ range checking is on for instance, because this is not "normal" generated } { range checking is on for instance, because this is not "normal" generated }
{ code, but more or less manually inserted) } { code, but more or less manually inserted) }
(*
{$ifndef fpc} {$ifndef fpc}
If TmpResult Then If TmpResult Then
{$else fpc} {$else fpc}
@ -210,6 +211,7 @@ Begin {CheckSequence}
Exclude(RegInfo.RegsLoadedForRef,RegCounter); Exclude(RegInfo.RegsLoadedForRef,RegCounter);
End; End;
End; End;
*)
{$ifndef fpc} {$ifndef fpc}
CheckSequence := TmpResult; CheckSequence := TmpResult;
{$endif fpc} {$endif fpc}
@ -543,69 +545,6 @@ begin
end; end;
end; end;
function RegReadByInstruction(reg: TRegister; hp: pai): boolean;
{ assumes hp doesn't modify registers implicitely (like div) }
{ and that reg is a 32bit register }
var p: paicpu;
opCount: byte;
begin
RegReadByInstruction := false;
p := paicpu(hp);
if hp^.typ <> ait_instruction then
exit;
case p^.opcode of
A_IMUL:
case p^.ops of
1: regReadByInstruction := (reg = R_EAX) or reginOp(reg,p^.oper[0]);
2,3:
regReadByInstruction := regInOp(reg,p^.oper[0]) or
regInOp(reg,p^.oper[1]);
end;
{ A_IDIV,A_DIV,A_IMUL:
begin
regReadByInstruction :=
regInOp(reg,p^.oper[0]) or
(((p^.opcode = A_IDIV) or
(p^.opcode = A_DIV)) and
(reg = R_EAX));
end;}
else
begin
for opCount := 0 to 2 do
if (p^.oper[opCount].typ = top_ref) and
RegInRef(reg,p^.oper[opCount].ref^) then
begin
RegReadByInstruction := true;
exit
end;
for opCount := 1 to MaxCh do
case InsProp[p^.opcode].Ch[opCount] of
Ch_RWOp1,Ch_ROp1{$ifdef arithopt},Ch_MOp1{$endif}:
if (p^.oper[0].typ = top_reg) and
(reg32(p^.oper[0].reg) = reg) then
begin
RegReadByInstruction := true;
exit
end;
Ch_RWOp2,Ch_ROp2{$ifdef arithopt},Ch_MOp2{$endif}:
if (p^.oper[1].typ = top_reg) and
(reg32(p^.oper[1].reg) = reg) then
begin
RegReadByInstruction := true;
exit
end;
Ch_RWOp3,Ch_ROp3{$ifdef arithopt},Ch_MOp3{$endif}:
if (p^.oper[2].typ = top_reg) and
(reg32(p^.oper[2].reg) = reg) then
begin
RegReadByInstruction := true;
exit
end;
end;
end;
end;
end;
procedure DoReplaceReadReg(orgReg,newReg: tregister; p: paicpu); procedure DoReplaceReadReg(orgReg,newReg: tregister; p: paicpu);
var opCount: byte; var opCount: byte;
begin begin
@ -653,7 +592,7 @@ function ReplaceReg(asmL: PaasmOutput; orgReg, newReg: TRegister; p: pai;
{ false otherwise. If successful, the contents of newReg are set to c, } { false otherwise. If successful, the contents of newReg are set to c, }
{ which should hold the contents of newReg before the current sequence } { which should hold the contents of newReg before the current sequence }
{ started } { started }
{ if the functino returns true, returnEndP holds the lat instruction } { if the function returns true, returnEndP holds the last instruction }
{ where newReg was replaced by orgReg } { where newReg was replaced by orgReg }
var endP, hp: Pai; var endP, hp: Pai;
removeLast, sequenceEnd, tmpResult, newRegModified, orgRegRead: Boolean; removeLast, sequenceEnd, tmpResult, newRegModified, orgRegRead: Boolean;
@ -878,7 +817,7 @@ Procedure DoCSE(AsmL: PAasmOutput; First, Last: Pai);
{marks the instructions that can be removed by RemoveInstructs. They're not {marks the instructions that can be removed by RemoveInstructs. They're not
removed immediately because sometimes an instruction needs to be checked in removed immediately because sometimes an instruction needs to be checked in
two different sequences} two different sequences}
Var Cnt, Cnt2: Longint; Var Cnt, Cnt2, Cnt3: Longint;
p, hp1, hp2: Pai; p, hp1, hp2: Pai;
hp3, hp4: pai; hp3, hp4: pai;
{$ifdef replacereg} {$ifdef replacereg}
@ -916,9 +855,14 @@ Begin
Begin Begin
If (p = StartMod) And If (p = StartMod) And
GetLastInstruction (p, hp1) And GetLastInstruction (p, hp1) And
(hp1^.typ <> ait_marker) (hp1^.typ <> ait_marker) Then
Then
{so we don't try to check a sequence when p is the first instruction of the block} {so we don't try to check a sequence when p is the first instruction of the block}
begin
{$ifdef csdebug}
hp5 := new(pai_asm_comment,init(strpnew(
'cse checking '+att_reg2str[Reg32(Paicpu(p)^.oper[1].reg)])));
insertLLItem(asml,p,p^.next,hp5);
{$endif csdebug}
If CheckSequence(p, Paicpu(p)^.oper[1].reg, Cnt, RegInfo) And If CheckSequence(p, Paicpu(p)^.oper[1].reg, Cnt, RegInfo) And
(Cnt > 0) Then (Cnt > 0) Then
Begin Begin
@ -943,16 +887,31 @@ Begin
While Cnt2 <= Cnt Do While Cnt2 <= Cnt Do
Begin Begin
If (hp1 = nil) And If (hp1 = nil) And
Not(RegInInstruction(Paicpu(hp2)^.oper[1].reg, p) Or Not(RegInInstruction(Paicpu(hp2)^.oper[1].reg, p)) And
RegInInstruction(Reg32(Paicpu(hp2)^.oper[1].reg), p)) And ((p^.typ = ait_instruction) And
Not((p^.typ = ait_instruction) And ((paicpu(p)^.OpCode = A_MOV) or
(paicpu(p)^.OpCode = A_MOV) And (paicpu(p)^.opcode = A_MOVZX) or
(paicpu(p)^.Oper[0].typ = top_ref) And (paicpu(p)^.opcode = A_MOVSX)) And
(PPaiProp(p^.OptInfo)^.Regs[Reg32(paicpu(p)^.Oper[1].reg)].NrOfMods (paicpu(p)^.Oper[0].typ = top_ref)) Then
<= (Cnt - Cnt2 + 1))) if (PPaiProp(p^.OptInfo)^.Regs[Reg32(paicpu(p)^.Oper[1].reg)].NrOfMods
Then hp1 := p; <= (Cnt - Cnt2 + 1)) and
(Reg32(paicpu(p)^.Oper[1].reg) in regInfo.regsLoadedForRef) then
begin
hp3 := p;
for Cnt3 := PPaiProp(p^.OptInfo)^.Regs[Reg32(paicpu(p)^.Oper[1].reg)].NrOfMods
downto 1 do
begin
{$ifndef noremove} {$ifndef noremove}
PPaiProp(p^.OptInfo)^.CanBeRemoved := True; if regInInstruction(paicpu(p)^.Oper[1].reg,hp3) then
PPaiProp(hp3^.OptInfo)^.CanBeRemoved := True;
{$endif noremove}
getNextInstruction(hp3,hp3);
end
end
else hp1 := p;
{$ifndef noremove}
if regInInstruction(Paicpu(hp2)^.oper[1].reg,p) then
PPaiProp(p^.OptInfo)^.CanBeRemoved := True;
{$endif noremove} {$endif noremove}
Inc(Cnt2); Inc(Cnt2);
GetNextInstruction(p, p); GetNextInstruction(p, p);
@ -1072,7 +1031,8 @@ Begin
End; End;
hp3 := New(Pai_Marker,Init(NoPropInfoEnd)); hp3 := New(Pai_Marker,Init(NoPropInfoEnd));
InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3); InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3);
If hp1 <> nil Then p := hp1; If hp1 <> nil Then
p := hp1;
Continue; Continue;
End End
Else Else
@ -1085,14 +1045,14 @@ Begin
Cnt2 := 1; Cnt2 := 1;
While Cnt2 <= Cnt Do While Cnt2 <= Cnt Do
Begin Begin
If RegInInstruction(Paicpu(hp2)^.oper[1].reg, p) Or If RegInInstruction(Paicpu(hp2)^.oper[1].reg, p) Then
RegInInstruction(Reg32(Paicpu(hp2)^.oper[1].reg), p) Then
PPaiProp(p^.OptInfo)^.CanBeRemoved := False; PPaiProp(p^.OptInfo)^.CanBeRemoved := False;
Inc(Cnt2); Inc(Cnt2);
GetNextInstruction(p, p); GetNextInstruction(p, p);
End; End;
Continue; Continue;
End; End;
End;
End; End;
End; End;
{$ifdef replacereg} {$ifdef replacereg}
@ -1216,7 +1176,14 @@ End.
{ {
$Log$ $Log$
Revision 1.56 2000-03-25 19:05:47 jonas Revision 1.57 2000-04-10 12:45:57 jonas
* fixed a serious bug in the CSE which (I think) only showed with
-dnewoptimizations when using multi-dimensional arrays with
elements of a size different from 1, 2 or 4 (especially strings).
* made the DFA/CSE more robust (much less dependent on specifics of the
code generator)
Revision 1.56 2000/03/25 19:05:47 jonas
* fixed some things for -Or. Make cycle now works with -OG2p3r if * fixed some things for -Or. Make cycle now works with -OG2p3r if
you use -Aas. There still a bug in popt386.pas that causes a you use -Aas. There still a bug in popt386.pas that causes a
problem with the binary writer, but I haven't found it yet problem with the binary writer, but I haven't found it yet
@ -1352,4 +1319,4 @@ End.
Revision 1.24 1999/08/25 11:59:58 jonas Revision 1.24 1999/08/25 11:59:58 jonas
* changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu) * changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
} }

View File

@ -64,11 +64,10 @@ Function RefsEquivalent(Const R1, R2: TReference; Var RegInfo: TRegInfo; OpAct:
Function RefsEqual(Const R1, R2: TReference): Boolean; Function RefsEqual(Const R1, R2: TReference): Boolean;
Function IsGP32Reg(Reg: TRegister): Boolean; Function IsGP32Reg(Reg: TRegister): Boolean;
Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean; Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
Function RegInInstruction(Reg: TRegister; p1: Pai): Boolean; function RegReadByInstruction(reg: TRegister; hp: pai): boolean;
{$ifdef newOptimizations} function RegModifiedByInstruction(Reg: TRegister; p1: Pai): Boolean;
Function RegInOp(Reg: TRegister; const o:toper): Boolean; function RegInInstruction(Reg: TRegister; p1: Pai): Boolean;
{$endif newOptimizations} function RegInOp(Reg: TRegister; const o:toper): Boolean;
Function RegModifiedByInstruction(Reg: TRegister; p1: Pai): Boolean;
Function GetNextInstruction(Current: Pai; Var Next: Pai): Boolean; Function GetNextInstruction(Current: Pai; Var Next: Pai): Boolean;
Function GetLastInstruction(Current: Pai; Var Last: Pai): Boolean; Function GetLastInstruction(Current: Pai; Var Last: Pai): Boolean;
@ -771,52 +770,138 @@ Begin {checks whether Ref contains a reference to Reg}
RegInRef := (Ref.Base = Reg) Or (Ref.Index = Reg) RegInRef := (Ref.Base = Reg) Or (Ref.Index = Reg)
End; End;
Function RegInInstruction(Reg: TRegister; p1: Pai): Boolean; function RegReadByInstruction(reg: TRegister; hp: pai): boolean;
{checks if Reg is used by the instruction p1} var p: paicpu;
Var Counter: Longint; opCount: byte;
TmpResult: Boolean; begin
Begin RegReadByInstruction := false;
TmpResult := False; reg := reg32(reg);
If (Pai(p1)^.typ = ait_instruction) Then p := paicpu(hp);
Begin if hp^.typ <> ait_instruction then
Reg := Reg32(Reg); exit;
Counter := 0; case p^.opcode of
Repeat A_IMUL:
Case Paicpu(p1)^.oper[Counter].typ Of case p^.ops of
Top_Reg: TmpResult := Reg = Reg32(Paicpu(p1)^.oper[Counter].reg); 1: regReadByInstruction := (reg = R_EAX) or reginOp(reg,p^.oper[0]);
Top_Ref: TmpResult := RegInRef(Reg, Paicpu(p1)^.oper[Counter].ref^); 2,3:
End; regReadByInstruction := regInOp(reg,p^.oper[0]) or
Inc(Counter) regInOp(reg,p^.oper[1]);
Until (Counter = 3) or TmpResult; end;
End; A_IDIV,A_DIV,A_MUL:
RegInInstruction := TmpResult begin
End; regReadByInstruction :=
regInOp(reg,p^.oper[0]) or (reg = R_EAX);
end;
else
begin
for opCount := 0 to 2 do
if (p^.oper[opCount].typ = top_ref) and
RegInRef(reg,p^.oper[opCount].ref^) then
begin
RegReadByInstruction := true;
exit
end;
for opCount := 1 to MaxCh do
case InsProp[p^.opcode].Ch[opCount] of
Ch_REAX..CH_REDI,CH_RWEAX..Ch_MEDI:
if reg = TCh2Reg(InsProp[p^.opcode].Ch[opCount]) then
begin
RegReadByInstruction := true;
exit
end;
Ch_RWOp1,Ch_ROp1{$ifdef arithopt},Ch_MOp1{$endif}:
if (p^.oper[0].typ = top_reg) and
(reg32(p^.oper[0].reg) = reg) then
begin
RegReadByInstruction := true;
exit
end;
Ch_RWOp2,Ch_ROp2{$ifdef arithopt},Ch_MOp2{$endif}:
if (p^.oper[1].typ = top_reg) and
(reg32(p^.oper[1].reg) = reg) then
begin
RegReadByInstruction := true;
exit
end;
Ch_RWOp3,Ch_ROp3{$ifdef arithopt},Ch_MOp3{$endif}:
if (p^.oper[2].typ = top_reg) and
(reg32(p^.oper[2].reg) = reg) then
begin
RegReadByInstruction := true;
exit
end;
end;
end;
end;
end;
function regInInstruction(Reg: TRegister; p1: Pai): Boolean;
{ Checks if Reg is used by the instruction p1 }
{ Difference with "regReadBysinstruction() or regModifiedByInstruction()": }
{ this one ignores CH_ALL opcodes, while regModifiedByInstruction doesn't }
var p: paicpu;
opCount: byte;
begin
reg := reg32(reg);
regInInstruction := false;
p := paicpu(p1);
if p1^.typ <> ait_instruction then
exit;
case p^.opcode of
A_IMUL:
case p^.ops of
1: regInInstruction := (reg = R_EAX) or reginOp(reg,p^.oper[0]);
2,3:
regInInstruction := regInOp(reg,p^.oper[0]) or
regInOp(reg,p^.oper[1]) or regInOp(reg,p^.oper[2]);
end;
A_IDIV,A_DIV,A_MUL:
regInInstruction :=
regInOp(reg,p^.oper[0]) or
(reg = R_EAX) or (reg = R_EDX)
else
begin
for opCount := 1 to MaxCh do
case InsProp[p^.opcode].Ch[opCount] of
CH_REAX..CH_MEDI:
if tch2reg(InsProp[p^.opcode].Ch[opCount]) = reg then
begin
regInInstruction := true;
exit;
end;
Ch_ROp1..Ch_MOp1:
if regInOp(reg,p^.oper[0]) then
begin
regInInstruction := true;
exit
end;
Ch_ROp2..Ch_MOp2:
if regInOp(reg,p^.oper[1]) then
begin
regInInstruction := true;
exit
end;
Ch_ROp3..Ch_MOp3:
if regInOp(reg,p^.oper[2]) then
begin
regInInstruction := true;
exit
end;
end;
end;
end;
end;
{$ifdef newOptimizations}
Function RegInOp(Reg: TRegister; const o:toper): Boolean; Function RegInOp(Reg: TRegister; const o:toper): Boolean;
Begin Begin
RegInOp := False; RegInOp := False;
reg := reg32(reg);
Case o.typ Of Case o.typ Of
top_reg: RegInOp := Reg = o.reg; top_reg: RegInOp := Reg = reg32(o.reg);
top_ref: RegInOp := (Reg = o.ref^.Base) Or top_ref: RegInOp := (Reg = o.ref^.Base) Or
(Reg = o.ref^.Index); (Reg = o.ref^.Index);
End; End;
End; End;
{$endif newOptimizations}
(*
Function RegModifiedByInstruction(Reg: TRegister; p1: Pai): Boolean;
{returns true if Reg is modified by the instruction p1. P1 is assumed to be
of the type ait_instruction}
Var hp: Pai;
Begin
If GetLastInstruction(p1, hp)
Then
RegModifiedByInstruction :=
PPAiProp(p1^.OptInfo)^.Regs[Reg].WState <>
PPAiProp(hp^.OptInfo)^.Regs[Reg].WState
Else RegModifiedByInstruction := True;
End;
*)
Function RegModifiedByInstruction(Reg: TRegister; p1: Pai): Boolean; Function RegModifiedByInstruction(Reg: TRegister; p1: Pai): Boolean;
Var InstrProp: TInsProp; Var InstrProp: TInsProp;
@ -830,7 +915,7 @@ Begin
A_IMUL: A_IMUL:
With paicpu(p1)^ Do With paicpu(p1)^ Do
TmpResult := TmpResult :=
((ops = 1) and (reg = R_EAX)) or ((ops = 1) and (reg in [R_EAX,R_EDX])) or
((ops = 2) and (Reg32(oper[1].reg) = reg)) or ((ops = 2) and (Reg32(oper[1].reg) = reg)) or
((ops = 3) and (Reg32(oper[2].reg) = reg)); ((ops = 3) and (Reg32(oper[2].reg) = reg));
A_DIV, A_IDIV, A_MUL: A_DIV, A_IDIV, A_MUL:
@ -1098,10 +1183,11 @@ Begin
Else s := 0 Else s := 0
End; End;
Function RegInSequence(Reg: TRegister; Const Content: TContent): Boolean; Function sequenceDependsonReg(Const Content: TContent; seqReg, Reg: TRegister): Boolean;
{checks the whole sequence of Content (so StartMod and and the next NrOfMods { Content is the sequence of instructions that describes the contents of }
Pai objects) to see whether Reg is used somewhere, without it being loaded { seqReg. Reg is being overwritten by the current instruction. If the }
with something else first} { content of seqReg depends on reg (ie. because of a }
{ "movl (seqreg,reg), seqReg" instruction), this function returns true }
Var p: Pai; Var p: Pai;
Counter: Byte; Counter: Byte;
TmpResult: Boolean; TmpResult: Boolean;
@ -1117,35 +1203,30 @@ Begin
If (p^.typ = ait_instruction) and If (p^.typ = ait_instruction) and
((Paicpu(p)^.opcode = A_MOV) or ((Paicpu(p)^.opcode = A_MOV) or
(Paicpu(p)^.opcode = A_MOVZX) or (Paicpu(p)^.opcode = A_MOVZX) or
(Paicpu(p)^.opcode = A_MOVSX)) (Paicpu(p)^.opcode = A_MOVSX) or
Then (paicpu(p)^.opcode = A_LEA)) and
Begin (Paicpu(p)^.oper[0].typ = top_ref) Then
If (Paicpu(p)^.oper[0].typ = top_ref) Then With Paicpu(p)^.oper[0].ref^ Do
With Paicpu(p)^.oper[0].ref^ Do If ((Base = procinfo^.FramePointer) or
If (Base = procinfo^.FramePointer) And (assigned(symbol) and (base = R_NO))) And
(Index = R_NO) (Index = R_NO) Then
Then Begin
Begin RegsChecked := RegsChecked + [Reg32(Paicpu(p)^.oper[1].reg)];
RegsChecked := RegsChecked + [Reg32(Paicpu(p)^.oper[1].reg)]; If Reg = Reg32(Paicpu(p)^.oper[1].reg) Then
If Reg = Reg32(Paicpu(p)^.oper[1].reg) Then Break;
Break; End
End Else
Else tmpResult :=
Begin regReadByInstruction(reg,p) and
If (Base = Reg) And regModifiedByInstruction(seqReg,p)
Not(Base In RegsChecked) Else
Then TmpResult := True; tmpResult :=
If Not(TmpResult) And regReadByInstruction(reg,p) and
(Index = Reg) And regModifiedByInstruction(seqReg,p);
Not(Index In RegsChecked)
Then TmpResult := True;
End
End
Else TmpResult := RegInInstruction(Reg, p);
Inc(Counter); Inc(Counter);
GetNextInstruction(p,p) GetNextInstruction(p,p)
End; End;
RegInSequence := TmpResult sequenceDependsonReg := TmpResult
End; End;
Procedure DestroyReg(p1: PPaiProp; Reg: TRegister; doIncState:Boolean); Procedure DestroyReg(p1: PPaiProp; Reg: TRegister; doIncState:Boolean);
@ -1173,20 +1254,19 @@ Begin
WState := TmpWState; WState := TmpWState;
RState := TmpRState; RState := TmpRState;
End; End;
For Counter := R_EAX to R_EDI Do For counter := R_EAX to R_EDI Do
With p1^.Regs[Counter] Do With p1^.Regs[counter] Do
If (Typ = Con_Ref) And If (Typ = Con_Ref) And
RegInSequence(Reg, p1^.Regs[Counter]) sequenceDependsOnReg(p1^.Regs[counter],counter,reg) Then
Then Begin
Begin if doIncState then
if doIncState then IncState(WState);
IncState(WState); TmpWState := WState;
TmpWState := WState; TmpRState := RState;
TmpRState := RState; FillChar(p1^.Regs[Counter], SizeOf(TContent), 0);
FillChar(p1^.Regs[Counter], SizeOf(TContent), 0); WState := TmpWState;
WState := TmpWState; RState := TmpRState;
RState := TmpRState; End;
End;
End; End;
End; End;
@ -1561,9 +1641,24 @@ Begin {initializes/desrtoys all registers}
End; End;
Procedure DestroyOp(PaiObj: Pai; const o:Toper); Procedure DestroyOp(PaiObj: Pai; const o:Toper);
{$ifdef statedebug}
var hp: pai;
{$endif statedebug}
Begin Begin
Case o.typ Of Case o.typ Of
top_reg: DestroyReg(PPaiProp(PaiObj^.OptInfo), o.reg, true); top_reg:
begin
{$ifdef statedebug}
hp := new(pai_asm_comment,init(strpnew('destroying '+att_reg2str[o.reg])));
hp^.next := paiobj^.next;
hp^.previous := paiobj;
paiobj^.next := hp;
if assigned(hp^.next) then
hp^.next^.previous := hp;
{$endif statedebug}
DestroyReg(PPaiProp(PaiObj^.OptInfo), o.reg, true);
end;
top_ref: top_ref:
Begin Begin
ReadRef(PPaiProp(PaiObj^.OptInfo), o.ref); ReadRef(PPaiProp(PaiObj^.OptInfo), o.ref);
@ -1610,6 +1705,10 @@ Begin
End End
Else Else
Begin Begin
{$ifdef statedebug}
hp := new(pai_asm_comment,init(strpnew('destroying '+att_reg2str[reg])));
insertllitem(asml,p,p^.next,hp);
{$endif statedebug}
DestroyReg(PPaiProp(p^.optinfo), Reg, true); DestroyReg(PPaiProp(p^.optinfo), Reg, true);
{$ifdef StateDebug} {$ifdef StateDebug}
hp := new(pai_asm_comment,init(strpnew(att_reg2str[reg]+': '+tostr(PPaiProp(p^.optinfo)^.Regs[reg].WState)))); hp := new(pai_asm_comment,init(strpnew(att_reg2str[reg]+': '+tostr(PPaiProp(p^.optinfo)^.Regs[reg].WState))));
@ -1890,6 +1989,11 @@ Begin
Case Paicpu(p)^.oper[1].typ Of Case Paicpu(p)^.oper[1].typ Of
Top_Reg: Top_Reg:
Begin Begin
{$ifdef statedebug}
hp := new(pai_asm_comment,init(strpnew('destroying '+
att_reg2str[Paicpu(p)^.oper[1].reg])));
insertllitem(asml,p,p^.next,hp);
{$endif statedebug}
DestroyReg(CurProp, Paicpu(p)^.oper[1].reg, true); DestroyReg(CurProp, Paicpu(p)^.oper[1].reg, true);
ReadReg(CurProp, Paicpu(p)^.oper[0].reg); ReadReg(CurProp, Paicpu(p)^.oper[0].reg);
{ CurProp^.Regs[Paicpu(p)^.oper[1].reg] := { CurProp^.Regs[Paicpu(p)^.oper[1].reg] :=
@ -1908,7 +2012,6 @@ Begin
Top_Ref: Top_Ref:
Begin {destination is always a register in this case} Begin {destination is always a register in this case}
ReadRef(CurProp, Paicpu(p)^.oper[0].ref); ReadRef(CurProp, Paicpu(p)^.oper[0].ref);
ReadReg(CurProp, Paicpu(p)^.oper[1].reg);
TmpReg := Reg32(Paicpu(p)^.oper[1].reg); TmpReg := Reg32(Paicpu(p)^.oper[1].reg);
If RegInRef(TmpReg, Paicpu(p)^.oper[0].ref^) And If RegInRef(TmpReg, Paicpu(p)^.oper[0].ref^) And
(CurProp^.Regs[TmpReg].Typ = Con_Ref) (CurProp^.Regs[TmpReg].Typ = Con_Ref)
@ -1927,6 +2030,10 @@ Begin
End End
Else Else
Begin Begin
{$ifdef statedebug}
hp := new(pai_asm_comment,init(strpnew('destroying & initing '+att_reg2str[tmpreg])));
insertllitem(asml,p,p^.next,hp);
{$endif statedebug}
DestroyReg(CurProp, TmpReg, true); DestroyReg(CurProp, TmpReg, true);
If Not(RegInRef(TmpReg, Paicpu(p)^.oper[0].ref^)) Then If Not(RegInRef(TmpReg, Paicpu(p)^.oper[0].ref^)) Then
With CurProp^.Regs[TmpReg] Do With CurProp^.Regs[TmpReg] Do
@ -1948,6 +2055,10 @@ Begin
Top_Reg: Top_Reg:
Begin Begin
TmpReg := Reg32(Paicpu(p)^.oper[1].reg); TmpReg := Reg32(Paicpu(p)^.oper[1].reg);
{$ifdef statedebug}
hp := new(pai_asm_comment,init(strpnew('destroying '+att_reg2str[tmpreg])));
insertllitem(asml,p,p^.next,hp);
{$endif statedebug}
With CurProp^.Regs[TmpReg] Do With CurProp^.Regs[TmpReg] Do
Begin Begin
DestroyReg(CurProp, TmpReg, true); DestroyReg(CurProp, TmpReg, true);
@ -1971,6 +2082,10 @@ Begin
If (Paicpu(p)^.OpCode = A_IDIV) or If (Paicpu(p)^.OpCode = A_IDIV) or
(Paicpu(p)^.OpCode = A_DIV) Then (Paicpu(p)^.OpCode = A_DIV) Then
ReadReg(CurProp,R_EDX); ReadReg(CurProp,R_EDX);
{$ifdef statedebug}
hp := new(pai_asm_comment,init(strpnew('destroying eax and edx')));
insertllitem(asml,p,p^.next,hp);
{$endif statedebug}
DestroyReg(CurProp, R_EAX, true); DestroyReg(CurProp, R_EAX, true);
DestroyReg(CurProp, R_EDX, true) DestroyReg(CurProp, R_EDX, true)
End; End;
@ -1982,18 +2097,25 @@ Begin
If (Paicpu(p)^.oper[1].typ = top_none) Then If (Paicpu(p)^.oper[1].typ = top_none) Then
Begin Begin
ReadReg(CurProp,R_EAX); ReadReg(CurProp,R_EAX);
{$ifdef statedebug}
hp := new(pai_asm_comment,init(strpnew('destroying eax and edx')));
insertllitem(asml,p,p^.next,hp);
{$endif statedebug}
DestroyReg(CurProp, R_EAX, true); DestroyReg(CurProp, R_EAX, true);
DestroyReg(CurProp, R_EDX, true) DestroyReg(CurProp, R_EDX, true)
End End
Else Else
{$ifdef arithopt} {$ifdef arithopt}
AddInstr2OpContents(Paicpu(p), Paicpu(p)^.oper[1]) AddInstr2OpContents(
{$ifdef statedebug}asml,{$endif}
Paicpu(p), Paicpu(p)^.oper[1])
{$else arithopt} {$else arithopt}
DestroyOp(p, Paicpu(p)^.oper[1]) DestroyOp(p, Paicpu(p)^.oper[1])
{$endif arithopt} {$endif arithopt}
Else Else
{$ifdef arithopt} {$ifdef arithopt}
AddInstr2OpContents(Paicpu(p), Paicpu(p)^.oper[2]); AddInstr2OpContents({$ifdef statedebug}asml,{$endif}
Paicpu(p), Paicpu(p)^.oper[2]);
{$else arithopt} {$else arithopt}
DestroyOp(p, Paicpu(p)^.oper[2]); DestroyOp(p, Paicpu(p)^.oper[2]);
{$endif arithopt} {$endif arithopt}
@ -2003,8 +2125,17 @@ Begin
begin begin
readop(curprop,paicpu(p)^.oper[0]); readop(curprop,paicpu(p)^.oper[0]);
if reginref(paicpu(p)^.oper[1].reg,paicpu(p)^.oper[0].ref^) then if reginref(paicpu(p)^.oper[1].reg,paicpu(p)^.oper[0].ref^) then
AddInstr2RegContents(paicpu(p), paicpu(p)^.oper[1].reg) AddInstr2RegContents({$ifdef statedebug}asml,{$endif}
else destroyreg(curprop,paicpu(p)^.oper[1].reg,true); paicpu(p), paicpu(p)^.oper[1].reg)
else
begin
{$ifdef statedebug}
hp := new(pai_asm_comment,init(strpnew('destroying '+
att_reg2str[paicpu(p)^.oper[1].reg])));
insertllitem(asml,p,p^.next,hp);
{$endif statedebug}
destroyreg(curprop,paicpu(p)^.oper[1].reg,true);
end;
end; end;
{$endif arithopt} {$endif arithopt}
Else Else
@ -2019,13 +2150,17 @@ Begin
Begin Begin
If (InstrProp.Ch[Cnt] >= Ch_RWEAX) Then If (InstrProp.Ch[Cnt] >= Ch_RWEAX) Then
ReadReg(CurProp, TCh2Reg(InstrProp.Ch[Cnt])); ReadReg(CurProp, TCh2Reg(InstrProp.Ch[Cnt]));
{$ifdef statedebug}
hp := new(pai_asm_comment,init(strpnew('destroying '+
att_reg2str[TCh2Reg(InstrProp.Ch[Cnt])])));
insertllitem(asml,p,p^.next,hp);
{$endif statedebug}
DestroyReg(CurProp, TCh2Reg(InstrProp.Ch[Cnt]), true); DestroyReg(CurProp, TCh2Reg(InstrProp.Ch[Cnt]), true);
End; End;
{$ifdef arithopt} {$ifdef arithopt}
Ch_MEAX..Ch_MEDI: Ch_MEAX..Ch_MEDI:
AddInstr2RegContents({$ifdef statedebug} asml, {$endif} AddInstr2RegContents({$ifdef statedebug} asml,{$endif}
Paicpu(p), Paicpu(p),TCh2Reg(InstrProp.Ch[Cnt]));
TCh2Reg(InstrProp.Ch[Cnt]));
{$endif arithopt} {$endif arithopt}
Ch_CDirFlag: CurProp^.DirFlag := F_NotSet; Ch_CDirFlag: CurProp^.DirFlag := F_NotSet;
Ch_SDirFlag: CurProp^.DirFlag := F_Set; Ch_SDirFlag: CurProp^.DirFlag := F_Set;
@ -2075,6 +2210,11 @@ Begin
Ch_RFlags, Ch_WFlags, Ch_RWFlags, Ch_FPU: Ch_RFlags, Ch_WFlags, Ch_RWFlags, Ch_FPU:
Else Else
Begin Begin
{$ifdef statedebug}
hp := new(pai_asm_comment,init(strpnew(
'destroying all regs for prev instruction')));
insertllitem(asml,p, p^.next,hp);
{$endif statedebug}
DestroyAllRegs(CurProp); DestroyAllRegs(CurProp);
End; End;
End; End;
@ -2086,6 +2226,11 @@ Begin
End End
Else Else
Begin Begin
{$ifdef statedebug}
hp := new(pai_asm_comment,init(strpnew(
'destroying all regs: unknown pai: '+tostr(ord(p^.typ)))));
insertllitem(asml,p, p^.next,hp);
{$endif statedebug}
DestroyAllRegs(CurProp); DestroyAllRegs(CurProp);
End; End;
End; End;
@ -2190,7 +2335,14 @@ End.
{ {
$Log$ $Log$
Revision 1.85 2000-03-25 18:58:00 jonas Revision 1.86 2000-04-10 12:45:56 jonas
* fixed a serious bug in the CSE which (I think) only showed with
-dnewoptimizations when using multi-dimensional arrays with
elements of a size different from 1, 2 or 4 (especially strings).
* made the DFA/CSE more robust (much less dependent on specifics of the
code generator)
Revision 1.85 2000/03/25 18:58:00 jonas
* moved AllocRegBetween() from csopt386 to this unit because it's now * moved AllocRegBetween() from csopt386 to this unit because it's now
also used by popt386 also used by popt386
@ -2278,4 +2430,4 @@ End.
Revision 1.62 1999/10/07 16:07:35 jonas Revision 1.62 1999/10/07 16:07:35 jonas
* small bugfix in ArrayRefsEq * small bugfix in ArrayRefsEq
} }