mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 10:39:18 +02:00
* check for more controll flow statements before doing loop unrolling
git-svn-id: trunk@39083 -
This commit is contained in:
parent
308e439d5d
commit
8f472d5212
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -13755,6 +13755,7 @@ tests/test/tunit1.pp svneol=native#text/plain
|
|||||||
tests/test/tunit2.pp svneol=native#text/plain
|
tests/test/tunit2.pp svneol=native#text/plain
|
||||||
tests/test/tunit3.pp svneol=native#text/plain
|
tests/test/tunit3.pp svneol=native#text/plain
|
||||||
tests/test/tunroll1.pp svneol=native#text/plain
|
tests/test/tunroll1.pp svneol=native#text/plain
|
||||||
|
tests/test/tunroll2.pp svneol=native#text/pascal
|
||||||
tests/test/tutf81.pp svneol=native#text/plain
|
tests/test/tutf81.pp svneol=native#text/plain
|
||||||
tests/test/tutf82.pp svneol=native#text/plain
|
tests/test/tutf82.pp svneol=native#text/plain
|
||||||
tests/test/tutf8cpl.pp svneol=native#text/plain
|
tests/test/tutf8cpl.pp svneol=native#text/plain
|
||||||
|
@ -74,9 +74,9 @@ unit optloop;
|
|||||||
end;
|
end;
|
||||||
preplaceinfo = ^treplaceinfo;
|
preplaceinfo = ^treplaceinfo;
|
||||||
|
|
||||||
function checkbreakcontinue(var n:tnode; arg: pointer): foreachnoderesult;
|
function checkcontrollflowstatements(var n:tnode; arg: pointer): foreachnoderesult;
|
||||||
begin
|
begin
|
||||||
if n.nodetype in [breakn,continuen] then
|
if n.nodetype in [breakn,continuen,goton,labeln,exitn,raisen] then
|
||||||
result:=fen_norecurse_true
|
result:=fen_norecurse_true
|
||||||
else
|
else
|
||||||
result:=fen_false;
|
result:=fen_false;
|
||||||
@ -105,7 +105,7 @@ unit optloop;
|
|||||||
unrollblock : tblocknode;
|
unrollblock : tblocknode;
|
||||||
getridoffor : boolean;
|
getridoffor : boolean;
|
||||||
replaceinfo : treplaceinfo;
|
replaceinfo : treplaceinfo;
|
||||||
usesbreakcontinue : boolean;
|
hascontrollflowstatements : boolean;
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
if (cs_opt_size in current_settings.optimizerswitches) then
|
if (cs_opt_size in current_settings.optimizerswitches) then
|
||||||
@ -129,7 +129,7 @@ unit optloop;
|
|||||||
else
|
else
|
||||||
counts:=tordconstnode(tfornode(node).t1).value-tordconstnode(tfornode(node).right).value+1;
|
counts:=tordconstnode(tfornode(node).t1).value-tordconstnode(tfornode(node).right).value+1;
|
||||||
|
|
||||||
usesbreakcontinue:=foreachnodestatic(tfornode(node).t2,@checkbreakcontinue,nil);
|
hascontrollflowstatements:=foreachnodestatic(tfornode(node).t2,@checkcontrollflowstatements,nil);
|
||||||
|
|
||||||
{ don't unroll more than we need,
|
{ don't unroll more than we need,
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ unit optloop;
|
|||||||
unrollblock:=internalstatements(unrollstatement);
|
unrollblock:=internalstatements(unrollstatement);
|
||||||
|
|
||||||
{ can we get rid completly of the for ? }
|
{ can we get rid completly of the for ? }
|
||||||
getridoffor:=(unrolls=counts) and not(usesbreakcontinue) and
|
getridoffor:=(unrolls=counts) and not(hascontrollflowstatements) and
|
||||||
{ TP/Macpas allows assignments to the for-variables, so we cannot get rid of the for }
|
{ TP/Macpas allows assignments to the for-variables, so we cannot get rid of the for }
|
||||||
([m_tp7,m_mac]*current_settings.modeswitches=[]);
|
([m_tp7,m_mac]*current_settings.modeswitches=[]);
|
||||||
|
|
||||||
|
59
tests/test/tunroll2.pp
Normal file
59
tests/test/tunroll2.pp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
{ %OPT=-Ooloopunroll -Sg }
|
||||||
|
{$mode objfpc}
|
||||||
|
|
||||||
|
uses
|
||||||
|
sysutils;
|
||||||
|
|
||||||
|
var
|
||||||
|
c,i : Integer;
|
||||||
|
|
||||||
|
|
||||||
|
function f1 : Integer;
|
||||||
|
begin
|
||||||
|
for Result:=1 to 2 do
|
||||||
|
if (i=1234) and (Result=2) then
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function f2 : Integer;
|
||||||
|
begin
|
||||||
|
for Result:=1 to 2 do
|
||||||
|
if (i=1234) and (Result=2) then
|
||||||
|
Break;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function f3 : Integer;
|
||||||
|
label
|
||||||
|
Stop;
|
||||||
|
begin
|
||||||
|
for Result:=1 to 2 do
|
||||||
|
if (i=1234) and (Result=2) then
|
||||||
|
Goto Stop;
|
||||||
|
Stop:
|
||||||
|
end;
|
||||||
|
|
||||||
|
function f4 : Integer;
|
||||||
|
begin
|
||||||
|
Result:=-1;
|
||||||
|
for c:=1 to 2 do
|
||||||
|
if (i=1234) and (Result=2) then
|
||||||
|
Raise Exception.Create('Test');
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
i:=1234;
|
||||||
|
if f1<>2 then
|
||||||
|
halt(1);
|
||||||
|
if f2<>2 then
|
||||||
|
halt(1);
|
||||||
|
if f3<>2 then
|
||||||
|
halt(1);
|
||||||
|
try
|
||||||
|
f4;
|
||||||
|
except
|
||||||
|
if c<>2 then
|
||||||
|
halt(1);
|
||||||
|
end;
|
||||||
|
writeln('ok');
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user