mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 03:25:57 +02:00
* do not unroll loops if the counter variable is accessed outside the current scope
git-svn-id: trunk@39163 -
This commit is contained in:
parent
3b3e33d863
commit
21d785e41b
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -11991,6 +11991,7 @@ tests/test/cg/tdivz1.pp svneol=native#text/plain
|
|||||||
tests/test/cg/tdivz2.pp svneol=native#text/plain
|
tests/test/cg/tdivz2.pp svneol=native#text/plain
|
||||||
tests/test/cg/texit.pp svneol=native#text/plain
|
tests/test/cg/texit.pp svneol=native#text/plain
|
||||||
tests/test/cg/tfor.pp svneol=native#text/plain
|
tests/test/cg/tfor.pp svneol=native#text/plain
|
||||||
|
tests/test/cg/tfor2.pp svneol=native#text/pascal
|
||||||
tests/test/cg/tformfnc.pp svneol=native#text/plain
|
tests/test/cg/tformfnc.pp svneol=native#text/plain
|
||||||
tests/test/cg/tfuncret.pp svneol=native#text/plain
|
tests/test/cg/tfuncret.pp svneol=native#text/plain
|
||||||
tests/test/cg/tin.pp svneol=native#text/plain
|
tests/test/cg/tin.pp svneol=native#text/plain
|
||||||
|
@ -1050,6 +1050,8 @@ implementation
|
|||||||
begin
|
begin
|
||||||
if (ra_addr_taken in how) then
|
if (ra_addr_taken in how) then
|
||||||
tabstractvarsym(tloadnode(p).symtableentry).addr_taken:=true;
|
tabstractvarsym(tloadnode(p).symtableentry).addr_taken:=true;
|
||||||
|
if (ra_different_scope in how) then
|
||||||
|
tabstractvarsym(tloadnode(p).symtableentry).different_scope:=true;
|
||||||
if (tabstractvarsym(tloadnode(p).symtableentry).varregable <> vr_none) and
|
if (tabstractvarsym(tloadnode(p).symtableentry).varregable <> vr_none) and
|
||||||
((not records_only) or
|
((not records_only) or
|
||||||
(tabstractvarsym(tloadnode(p).symtableentry).vardef.typ = recorddef)) then
|
(tabstractvarsym(tloadnode(p).symtableentry).vardef.typ = recorddef)) then
|
||||||
|
@ -118,7 +118,8 @@ unit optloop;
|
|||||||
{ the address of the counter variable might be taken if it is passed by constref to a
|
{ the address of the counter variable might be taken if it is passed by constref to a
|
||||||
subroutine, so really check if it is not taken }
|
subroutine, so really check if it is not taken }
|
||||||
((tfornode(node).left.nodetype=loadn) and (tloadnode(tfornode(node).left).symtableentry is tabstractvarsym) and
|
((tfornode(node).left.nodetype=loadn) and (tloadnode(tfornode(node).left).symtableentry is tabstractvarsym) and
|
||||||
not(tabstractvarsym(tloadnode(tfornode(node).left).symtableentry).addr_taken))
|
not(tabstractvarsym(tloadnode(tfornode(node).left).symtableentry).addr_taken) and
|
||||||
|
not(tabstractvarsym(tloadnode(tfornode(node).left).symtableentry).different_scope))
|
||||||
) then
|
) then
|
||||||
begin
|
begin
|
||||||
{ number of executions known? }
|
{ number of executions known? }
|
||||||
|
@ -43,7 +43,7 @@ type
|
|||||||
{$endif Test_Double_checksum}
|
{$endif Test_Double_checksum}
|
||||||
|
|
||||||
const
|
const
|
||||||
CurrentPPUVersion = 200;
|
CurrentPPUVersion = 201;
|
||||||
|
|
||||||
{ unit flags }
|
{ unit flags }
|
||||||
uf_init = $000001; { unit has initialization section }
|
uf_init = $000001; { unit has initialization section }
|
||||||
|
@ -172,11 +172,13 @@ interface
|
|||||||
varspez : tvarspez; { sets the type of access }
|
varspez : tvarspez; { sets the type of access }
|
||||||
varregable : tvarregable;
|
varregable : tvarregable;
|
||||||
varstate : tvarstate;
|
varstate : tvarstate;
|
||||||
{ Has the address of this variable potentially escaped the }
|
{ Has the address of this variable potentially escaped the
|
||||||
{ block in which is was declared? }
|
block in which is was declared?
|
||||||
{ could also be part of tabstractnormalvarsym, but there's }
|
could also be part of tabstractnormalvarsym, but there's
|
||||||
{ one byte left here till the next 4 byte alignment }
|
one byte left here till the next 4 byte alignment }
|
||||||
addr_taken : boolean;
|
addr_taken : boolean;
|
||||||
|
{ true if the variable is accessed in a different scope }
|
||||||
|
different_scope : boolean;
|
||||||
constructor create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions;doregister:boolean);
|
constructor create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions;doregister:boolean);
|
||||||
constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
|
constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
|
||||||
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
||||||
@ -1601,6 +1603,7 @@ implementation
|
|||||||
varspez:=tvarspez(ppufile.getbyte);
|
varspez:=tvarspez(ppufile.getbyte);
|
||||||
varregable:=tvarregable(ppufile.getbyte);
|
varregable:=tvarregable(ppufile.getbyte);
|
||||||
addr_taken:=ppufile.getboolean;
|
addr_taken:=ppufile.getboolean;
|
||||||
|
different_scope:=ppufile.getboolean;
|
||||||
ppufile.getderef(vardefderef);
|
ppufile.getderef(vardefderef);
|
||||||
ppufile.getsmallset(varoptions);
|
ppufile.getsmallset(varoptions);
|
||||||
end;
|
end;
|
||||||
@ -1633,6 +1636,7 @@ implementation
|
|||||||
ppufile.do_crc:=false;
|
ppufile.do_crc:=false;
|
||||||
ppufile.putbyte(byte(varregable));
|
ppufile.putbyte(byte(varregable));
|
||||||
ppufile.putboolean(addr_taken);
|
ppufile.putboolean(addr_taken);
|
||||||
|
ppufile.putboolean(different_scope);
|
||||||
ppufile.do_crc:=oldintfcrc;
|
ppufile.do_crc:=oldintfcrc;
|
||||||
ppufile.putderef(vardefderef);
|
ppufile.putderef(vardefderef);
|
||||||
ppufile.putsmallset(varoptions);
|
ppufile.putsmallset(varoptions);
|
||||||
|
@ -2117,6 +2117,7 @@ begin
|
|||||||
writeln([space,' Spez : ',Varspez2Str(i)]);
|
writeln([space,' Spez : ',Varspez2Str(i)]);
|
||||||
writeln([space,' Regable : ',Varregable2Str(ppufile.getbyte)]);
|
writeln([space,' Regable : ',Varregable2Str(ppufile.getbyte)]);
|
||||||
writeln([space,' Addr Taken : ',(ppufile.getbyte<>0)]);
|
writeln([space,' Addr Taken : ',(ppufile.getbyte<>0)]);
|
||||||
|
writeln([space,'Escaped Scope : ',(ppufile.getbyte<>0)]);
|
||||||
write ([space,' Var Type : ']);
|
write ([space,' Var Type : ']);
|
||||||
if VarDef <> nil then
|
if VarDef <> nil then
|
||||||
readderef('',VarDef.VarType)
|
readderef('',VarDef.VarType)
|
||||||
|
22
tests/test/cg/tfor2.pp
Normal file
22
tests/test/cg/tfor2.pp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{ %OPT=-O3 }
|
||||||
|
program LoopUnrollTest;
|
||||||
|
procedure Test;
|
||||||
|
var
|
||||||
|
I: Integer;
|
||||||
|
procedure Test2;
|
||||||
|
begin
|
||||||
|
if I<>1 then
|
||||||
|
halt(1)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
writeln('ok');
|
||||||
|
halt(0);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
begin
|
||||||
|
for I := 1 to 10 do
|
||||||
|
Test2;
|
||||||
|
end;
|
||||||
|
begin
|
||||||
|
Test;
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user