mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-03 12:00:30 +02:00
* 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:
parent
5be6c35518
commit
767ecef9bb
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user