* fixed bug in arrayRefsEq

* object/class fields are now handled the same as local/global vars and
    parameters (ie. a write to a local var can now never destroy a class
    field)
This commit is contained in:
Jonas Maebe 2000-11-03 18:06:26 +00:00
parent 5be6c35518
commit 767ecef9bb

View File

@ -728,7 +728,7 @@ Begin
AddReg2RegInfo(OldReg, NewReg, RegInfo);
RegsEquivalent := True
End
Else RegsEquivalent := False
Else RegsEquivalent := False
Else RegsEquivalent := False
Else RegsEquivalent := OldReg = NewReg
End;
@ -1593,10 +1593,65 @@ Begin
ArrayRefsEq := (R1.Offset+R1.OffsetFixup = R2.Offset+R2.OffsetFixup) And
(R1.Segment = R2.Segment) And
(R1.Symbol=R2.Symbol) And
((Assigned(R1.Symbol)) Or
(R1.Base = R2.Base))
(R1.Base = R2.Base)
End;
function isSimpleRef(const ref: treference): boolean;
{ returns true if ref is reference to a local or global variable, to a }
{ parameter or to an object field (this includes arrays). Returns false }
{ otherwise. }
begin
isSimpleRef :=
assigned(ref.symbol) or
(ref.base = procinfo^.framepointer) or
(assigned(procinfo^._class) and
(ref.base = R_ESI));
end;
function containsPointerRef(p: pai): boolean;
{ checks if an instruction contains a reference which is a pointer location }
var
hp: paicpu;
count: longint;
begin
containsPointerRef := false;
if p^.typ <> ait_instruction then
exit;
hp := paicpu(p);
for count := 0 to high(hp^.ops) do
begin
case hp^.oper[count].typ of
top_ref:
if not isSimpleRef(hp^.oper[count].ref^) then
begin
containsPointerRef := true;
exit;
end;
top_none:
exit;
end;
end;
end;
function containsPointerLoad(c: tcontent): boolean;
{ checks whether the contents of a register contain a pointer reference }
var
p: pai;
count: longint;
begin
containsPointerLoad := false;
p := c.startmod;
for count := c.nrOfMods downto 1 do
begin
if containsPointerRef(p) then
begin
containsPointerLoad := true;
exit;
end;
getnextinstruction(p,p);
end;
end;
function writeToMemDestroysContents(regWritten: tregister; const ref: treference;
reg: tregister; const c: tcontent): boolean;
@ -1612,8 +1667,7 @@ begin
end;
reg := reg32(reg);
regWritten := reg32(regWritten);
if (ref.base = procinfo^.framePointer) or
assigned(ref.symbol) Then
if isSimpleRef(ref) then
begin
if (ref.index <> R_NO) or
(assigned(ref.symbol) and
@ -1630,14 +1684,14 @@ begin
{ "mov?? (Ref), %reg". WhichReg (this is the register whose contents }
{ are being written to memory) is not destroyed if it's StartMod is }
{ of that form and NrOfMods = 1 (so if it holds ref, but is not a }
{ pointer based on Ref) }
{ expression based on Ref) }
{ * with uncertain optimizations off: }
{ - also destroy registers that contain any pointer }
with c do
writeToMemDestroysContents :=
(typ in [con_ref,con_noRemoveRef]) and
((not(cs_uncertainOpts in aktglobalswitches) and
(nrOfMods <> 1)
containsPointerLoad(c)
) or
(refInSequence(ref,c,refsEq) and
((reg <> regWritten) or
@ -1662,15 +1716,10 @@ begin
(typ in [con_ref,con_noRemoveRef]) and
(not(cs_UncertainOpts in aktglobalswitches) or
{ for movsl }
((ref.base = R_EDI) and (ref.index = R_EDI)) or
((ref.base = R_EDI) and (ref.index = R_EDI)) or
{ don't destroy if reg contains a parameter, local or global variable }
not((nrOfMods = 1) and
(paicpu(startMod)^.oper[0].typ = top_ref) and
((paicpu(startMod)^.oper[0].ref^.base = procinfo^.framePointer) or
assigned(paicpu(startMod)^.oper[0].ref^.symbol)
)
)
)
containsPointerLoad(c)
)
end;
function writeToRegDestroysContents(destReg: tregister; reg: tregister;
@ -2387,7 +2436,13 @@ End.
{
$Log$
Revision 1.3 2000-10-24 10:40:53 jonas
Revision 1.4 2000-11-03 18:06:26 jonas
* fixed bug in arrayRefsEq
* object/class fields are now handled the same as local/global vars and
parameters (ie. a write to a local var can now never destroy a class
field)
Revision 1.3 2000/10/24 10:40:53 jonas
+ register renaming ("fixes" bug1088)
* changed command line options meanings for optimizer:
O2 now means peepholopts, CSE and register renaming in 1 pass