mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 18:47:52 +02:00
* moved conversion of for into while loops in a separate pass, so node optimizations on the node tree can be
carried out without losing information from for loops git-svn-id: trunk@43910 -
This commit is contained in:
parent
3b39ec84e4
commit
2f2b378c03
@ -110,6 +110,7 @@ interface
|
||||
constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;reintroduce;
|
||||
function pass_typecheck:tnode;override;
|
||||
function pass_1 : tnode;override;
|
||||
function makewhileloop : tnode;
|
||||
function simplify(forinline : boolean) : tnode;override;
|
||||
end;
|
||||
tfornodeclass = class of tfornode;
|
||||
@ -280,6 +281,10 @@ interface
|
||||
enumerator_get, enumerator_move: tprocdef; enumerator_current: tpropertysym): tnode;
|
||||
function create_for_in_loop(hloopvar, hloopbody, expr: tnode): tnode;
|
||||
|
||||
{ converts all for nodes in the tree into while nodes,
|
||||
returns true if something was converted }
|
||||
function ConvertForLoops(var n : tnode) : Boolean;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -993,6 +998,28 @@ implementation
|
||||
current_filepos:=storefilepos;
|
||||
end;
|
||||
|
||||
|
||||
function _ConvertForLoops(var n: tnode; arg: pointer): foreachnoderesult;
|
||||
var
|
||||
hp : tnode;
|
||||
begin
|
||||
Result:=fen_false;
|
||||
if n.nodetype=forn then
|
||||
begin
|
||||
Result:=fen_true;
|
||||
hp:=n;
|
||||
n:=tfornode(n).makewhileloop;
|
||||
do_firstpass(n);
|
||||
hp.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function ConvertForLoops(var n : tnode) : boolean;
|
||||
begin
|
||||
result:=foreachnodestatic(pm_postprocess,n,@_ConvertForLoops,nil);
|
||||
end;
|
||||
|
||||
{****************************************************************************
|
||||
TLOOPNODE
|
||||
*****************************************************************************}
|
||||
@ -1702,6 +1729,20 @@ implementation
|
||||
|
||||
|
||||
function tfornode.pass_1 : tnode;
|
||||
begin
|
||||
result:=nil;
|
||||
expectloc:=LOC_VOID;
|
||||
|
||||
firstpass(left);
|
||||
firstpass(right);
|
||||
firstpass(t1);
|
||||
|
||||
if assigned(t2) then
|
||||
firstpass(t2);
|
||||
end;
|
||||
|
||||
|
||||
function tfornode.makewhileloop : tnode;
|
||||
var
|
||||
ifblock,loopblock : tblocknode;
|
||||
ifstatements,statements,loopstatements : tstatementnode;
|
||||
@ -1716,6 +1757,7 @@ implementation
|
||||
usetotemp : boolean;
|
||||
{ if the lower bound is not constant, it must be store in a temp before calculating the upper bound }
|
||||
usefromtemp : boolean;
|
||||
storefilepos: tfileposinfo;
|
||||
|
||||
procedure iterate_counter(var s : tstatementnode;fw : boolean);
|
||||
begin
|
||||
@ -1737,21 +1779,10 @@ implementation
|
||||
|
||||
begin
|
||||
result:=nil;
|
||||
expectloc:=LOC_VOID;
|
||||
fromtemp:=nil;
|
||||
totemp:=nil;
|
||||
|
||||
firstpass(left);
|
||||
firstpass(right);
|
||||
firstpass(t1);
|
||||
|
||||
if assigned(t2) then
|
||||
begin
|
||||
firstpass(t2);
|
||||
if codegenerror then
|
||||
exit;
|
||||
end;
|
||||
|
||||
fromtemp:=nil;
|
||||
storefilepos:=current_filepos;
|
||||
current_filepos:=fileinfo;
|
||||
do_loopvar_at_end:=(lnf_dont_mind_loopvar_on_exit in loopflags)
|
||||
{ if the loop is unrolled and there is a jump into the loop,
|
||||
then we can't do the trick with incrementing the loop var only at the
|
||||
@ -1890,6 +1921,7 @@ implementation
|
||||
addstatement(ifstatements,cwhilerepeatnode.create(caddnode.create_internal(cond,left.getcopy,t1.getcopy),loopblock,false,true));
|
||||
addstatement(statements,ifblock);
|
||||
end;
|
||||
current_filepos:=storefilepos;
|
||||
end;
|
||||
|
||||
|
||||
|
@ -602,6 +602,10 @@ unit optdfa;
|
||||
if the tree has been changed without updating dfa }
|
||||
procedure TDFABuilder.resetdfainfo(node : tnode);
|
||||
begin
|
||||
nodemap.Free;
|
||||
nodemap:=nil;
|
||||
resultnode.Free;
|
||||
resultnode:=nil;
|
||||
foreachnodestatic(pm_postprocess,node,@ResetDFA,nil);
|
||||
end;
|
||||
|
||||
|
@ -1139,6 +1139,7 @@ implementation
|
||||
procedure tcgprocinfo.OptimizeNodeTree;
|
||||
var
|
||||
i : integer;
|
||||
RedoDFA: Boolean;
|
||||
{RedoDFA : boolean;}
|
||||
begin
|
||||
{ do this before adding the entry code else the tail recursion recognition won't work,
|
||||
@ -1158,6 +1159,24 @@ implementation
|
||||
dfabuilder:=TDFABuilder.Create;
|
||||
dfabuilder.createdfainfo(code);
|
||||
include(flags,pi_dfaavailable);
|
||||
RedoDFA:=false;
|
||||
|
||||
if (cs_opt_loopstrength in current_settings.optimizerswitches)
|
||||
{ our induction variable strength reduction doesn't like
|
||||
for loops with more than one entry }
|
||||
and not(pi_has_label in flags) then
|
||||
begin
|
||||
RedoDFA:=OptimizeInductionVariables(code);
|
||||
end;
|
||||
|
||||
RedoDFA:=ConvertForLoops(code) or RedoDFA;
|
||||
|
||||
if RedoDFA then
|
||||
begin
|
||||
dfabuilder.resetdfainfo(code);
|
||||
dfabuilder.createdfainfo(code);
|
||||
include(flags,pi_dfaavailable);
|
||||
end;
|
||||
|
||||
{ when life info is available, we can give more sophisticated warning about uninitialized
|
||||
variables ...
|
||||
@ -1186,19 +1205,15 @@ implementation
|
||||
tabstractnormalvarsym(tloadnode(dfabuilder.nodemap[i]).symtableentry).noregvarinitneeded:=true
|
||||
end;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ConvertForLoops(code);
|
||||
end;
|
||||
|
||||
if (pi_dfaavailable in flags) and (cs_opt_dead_store_eliminate in current_settings.optimizerswitches) then
|
||||
do_optdeadstoreelim(code);
|
||||
|
||||
if (cs_opt_loopstrength in current_settings.optimizerswitches)
|
||||
{ our induction variable strength reduction doesn't like
|
||||
for loops with more than one entry }
|
||||
and not(pi_has_label in flags) then
|
||||
begin
|
||||
{RedoDFA:=}OptimizeInductionVariables(code);
|
||||
end;
|
||||
|
||||
if (cs_opt_remove_emtpy_proc in current_settings.optimizerswitches) and
|
||||
(procdef.proctypeoption in [potype_operator,potype_procedure,potype_function]) and
|
||||
(code.nodetype=blockn) and (tblocknode(code).statements=nil) then
|
||||
|
Loading…
Reference in New Issue
Block a user