mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-26 14:50:32 +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;
|
constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;reintroduce;
|
||||||
function pass_typecheck:tnode;override;
|
function pass_typecheck:tnode;override;
|
||||||
function pass_1 : tnode;override;
|
function pass_1 : tnode;override;
|
||||||
|
function makewhileloop : tnode;
|
||||||
function simplify(forinline : boolean) : tnode;override;
|
function simplify(forinline : boolean) : tnode;override;
|
||||||
end;
|
end;
|
||||||
tfornodeclass = class of tfornode;
|
tfornodeclass = class of tfornode;
|
||||||
@ -280,6 +281,10 @@ interface
|
|||||||
enumerator_get, enumerator_move: tprocdef; enumerator_current: tpropertysym): tnode;
|
enumerator_get, enumerator_move: tprocdef; enumerator_current: tpropertysym): tnode;
|
||||||
function create_for_in_loop(hloopvar, hloopbody, expr: tnode): 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
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -993,6 +998,28 @@ implementation
|
|||||||
current_filepos:=storefilepos;
|
current_filepos:=storefilepos;
|
||||||
end;
|
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
|
TLOOPNODE
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -1702,6 +1729,20 @@ implementation
|
|||||||
|
|
||||||
|
|
||||||
function tfornode.pass_1 : tnode;
|
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
|
var
|
||||||
ifblock,loopblock : tblocknode;
|
ifblock,loopblock : tblocknode;
|
||||||
ifstatements,statements,loopstatements : tstatementnode;
|
ifstatements,statements,loopstatements : tstatementnode;
|
||||||
@ -1716,6 +1757,7 @@ implementation
|
|||||||
usetotemp : boolean;
|
usetotemp : boolean;
|
||||||
{ if the lower bound is not constant, it must be store in a temp before calculating the upper bound }
|
{ if the lower bound is not constant, it must be store in a temp before calculating the upper bound }
|
||||||
usefromtemp : boolean;
|
usefromtemp : boolean;
|
||||||
|
storefilepos: tfileposinfo;
|
||||||
|
|
||||||
procedure iterate_counter(var s : tstatementnode;fw : boolean);
|
procedure iterate_counter(var s : tstatementnode;fw : boolean);
|
||||||
begin
|
begin
|
||||||
@ -1737,21 +1779,10 @@ implementation
|
|||||||
|
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
expectloc:=LOC_VOID;
|
|
||||||
fromtemp:=nil;
|
|
||||||
totemp:=nil;
|
totemp:=nil;
|
||||||
|
fromtemp:=nil;
|
||||||
firstpass(left);
|
storefilepos:=current_filepos;
|
||||||
firstpass(right);
|
current_filepos:=fileinfo;
|
||||||
firstpass(t1);
|
|
||||||
|
|
||||||
if assigned(t2) then
|
|
||||||
begin
|
|
||||||
firstpass(t2);
|
|
||||||
if codegenerror then
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
do_loopvar_at_end:=(lnf_dont_mind_loopvar_on_exit in loopflags)
|
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,
|
{ 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
|
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(ifstatements,cwhilerepeatnode.create(caddnode.create_internal(cond,left.getcopy,t1.getcopy),loopblock,false,true));
|
||||||
addstatement(statements,ifblock);
|
addstatement(statements,ifblock);
|
||||||
end;
|
end;
|
||||||
|
current_filepos:=storefilepos;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
@ -602,6 +602,10 @@ unit optdfa;
|
|||||||
if the tree has been changed without updating dfa }
|
if the tree has been changed without updating dfa }
|
||||||
procedure TDFABuilder.resetdfainfo(node : tnode);
|
procedure TDFABuilder.resetdfainfo(node : tnode);
|
||||||
begin
|
begin
|
||||||
|
nodemap.Free;
|
||||||
|
nodemap:=nil;
|
||||||
|
resultnode.Free;
|
||||||
|
resultnode:=nil;
|
||||||
foreachnodestatic(pm_postprocess,node,@ResetDFA,nil);
|
foreachnodestatic(pm_postprocess,node,@ResetDFA,nil);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1139,6 +1139,7 @@ implementation
|
|||||||
procedure tcgprocinfo.OptimizeNodeTree;
|
procedure tcgprocinfo.OptimizeNodeTree;
|
||||||
var
|
var
|
||||||
i : integer;
|
i : integer;
|
||||||
|
RedoDFA: Boolean;
|
||||||
{RedoDFA : boolean;}
|
{RedoDFA : boolean;}
|
||||||
begin
|
begin
|
||||||
{ do this before adding the entry code else the tail recursion recognition won't work,
|
{ do this before adding the entry code else the tail recursion recognition won't work,
|
||||||
@ -1158,6 +1159,24 @@ implementation
|
|||||||
dfabuilder:=TDFABuilder.Create;
|
dfabuilder:=TDFABuilder.Create;
|
||||||
dfabuilder.createdfainfo(code);
|
dfabuilder.createdfainfo(code);
|
||||||
include(flags,pi_dfaavailable);
|
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
|
{ when life info is available, we can give more sophisticated warning about uninitialized
|
||||||
variables ...
|
variables ...
|
||||||
@ -1186,19 +1205,15 @@ implementation
|
|||||||
tabstractnormalvarsym(tloadnode(dfabuilder.nodemap[i]).symtableentry).noregvarinitneeded:=true
|
tabstractnormalvarsym(tloadnode(dfabuilder.nodemap[i]).symtableentry).noregvarinitneeded:=true
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
ConvertForLoops(code);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if (pi_dfaavailable in flags) and (cs_opt_dead_store_eliminate in current_settings.optimizerswitches) then
|
if (pi_dfaavailable in flags) and (cs_opt_dead_store_eliminate in current_settings.optimizerswitches) then
|
||||||
do_optdeadstoreelim(code);
|
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
|
if (cs_opt_remove_emtpy_proc in current_settings.optimizerswitches) and
|
||||||
(procdef.proctypeoption in [potype_operator,potype_procedure,potype_function]) and
|
(procdef.proctypeoption in [potype_operator,potype_procedure,potype_function]) and
|
||||||
(code.nodetype=blockn) and (tblocknode(code).statements=nil) then
|
(code.nodetype=blockn) and (tblocknode(code).statements=nil) then
|
||||||
|
Loading…
Reference in New Issue
Block a user