* do not unroll loops if the counter variable is accessed outside the current scope

git-svn-id: trunk@39163 -
This commit is contained in:
florian 2018-06-03 15:12:48 +00:00
parent 3b3e33d863
commit 21d785e41b
7 changed files with 37 additions and 6 deletions

1
.gitattributes vendored
View File

@ -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/texit.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/tfuncret.pp svneol=native#text/plain
tests/test/cg/tin.pp svneol=native#text/plain

View File

@ -1050,6 +1050,8 @@ implementation
begin
if (ra_addr_taken in how) then
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
((not records_only) or
(tabstractvarsym(tloadnode(p).symtableentry).vardef.typ = recorddef)) then

View File

@ -118,7 +118,8 @@ unit optloop;
{ 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 }
((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
begin
{ number of executions known? }

View File

@ -43,7 +43,7 @@ type
{$endif Test_Double_checksum}
const
CurrentPPUVersion = 200;
CurrentPPUVersion = 201;
{ unit flags }
uf_init = $000001; { unit has initialization section }

View File

@ -172,11 +172,13 @@ interface
varspez : tvarspez; { sets the type of access }
varregable : tvarregable;
varstate : tvarstate;
{ Has the address of this variable potentially escaped the }
{ block in which is was declared? }
{ could also be part of tabstractnormalvarsym, but there's }
{ one byte left here till the next 4 byte alignment }
{ Has the address of this variable potentially escaped the
block in which is was declared?
could also be part of tabstractnormalvarsym, but there's
one byte left here till the next 4 byte alignment }
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 ppuload(st:tsymtyp;ppufile:tcompilerppufile);
procedure ppuwrite(ppufile:tcompilerppufile);override;
@ -1601,6 +1603,7 @@ implementation
varspez:=tvarspez(ppufile.getbyte);
varregable:=tvarregable(ppufile.getbyte);
addr_taken:=ppufile.getboolean;
different_scope:=ppufile.getboolean;
ppufile.getderef(vardefderef);
ppufile.getsmallset(varoptions);
end;
@ -1633,6 +1636,7 @@ implementation
ppufile.do_crc:=false;
ppufile.putbyte(byte(varregable));
ppufile.putboolean(addr_taken);
ppufile.putboolean(different_scope);
ppufile.do_crc:=oldintfcrc;
ppufile.putderef(vardefderef);
ppufile.putsmallset(varoptions);

View File

@ -2117,6 +2117,7 @@ begin
writeln([space,' Spez : ',Varspez2Str(i)]);
writeln([space,' Regable : ',Varregable2Str(ppufile.getbyte)]);
writeln([space,' Addr Taken : ',(ppufile.getbyte<>0)]);
writeln([space,'Escaped Scope : ',(ppufile.getbyte<>0)]);
write ([space,' Var Type : ']);
if VarDef <> nil then
readderef('',VarDef.VarType)

22
tests/test/cg/tfor2.pp Normal file
View 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.