mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 10:49:09 +02:00
* life info generation works for the whole compiler if exception catching blocks are ignored
git-svn-id: trunk@7561 -
This commit is contained in:
parent
496d73dc9d
commit
2761b9e096
@ -20,7 +20,8 @@
|
|||||||
****************************************************************************
|
****************************************************************************
|
||||||
}
|
}
|
||||||
|
|
||||||
{$define DEBUG_DFA}
|
{ $define DEBUG_DFA}
|
||||||
|
{ $define EXTDEBUG_DFA}
|
||||||
|
|
||||||
{ this unit implements routines to perform dfa }
|
{ this unit implements routines to perform dfa }
|
||||||
unit optdfa;
|
unit optdfa;
|
||||||
@ -44,7 +45,7 @@ unit optdfa;
|
|||||||
globtype,globals,
|
globtype,globals,
|
||||||
verbose,
|
verbose,
|
||||||
cpuinfo,
|
cpuinfo,
|
||||||
symdef,
|
symconst,symdef,
|
||||||
defutil,
|
defutil,
|
||||||
procinfo,
|
procinfo,
|
||||||
nutils,
|
nutils,
|
||||||
@ -123,6 +124,13 @@ unit optdfa;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function ResetProcessing(var n: tnode; arg: pointer): foreachnoderesult;
|
||||||
|
begin
|
||||||
|
exclude(n.flags,nf_processing);
|
||||||
|
result:=fen_false;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure CreateLifeInfo(node : tnode;map : TIndexedNodeSet);
|
procedure CreateLifeInfo(node : tnode;map : TIndexedNodeSet);
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -149,6 +157,11 @@ unit optdfa;
|
|||||||
writeln;
|
writeln;
|
||||||
end;
|
end;
|
||||||
}
|
}
|
||||||
|
{$ifdef DEBUG_DFA}
|
||||||
|
if not(changed) and b then
|
||||||
|
writeln('Another DFA pass caused by: ',nodetype2str[n.nodetype],'(',n.fileinfo.line,',',n.fileinfo.column,')');
|
||||||
|
{$endif DEBUG_DFA}
|
||||||
|
|
||||||
changed:=changed or b;
|
changed:=changed or b;
|
||||||
node.optinfo^.life:=l;
|
node.optinfo^.life:=l;
|
||||||
end;
|
end;
|
||||||
@ -177,7 +190,10 @@ unit optdfa;
|
|||||||
DFASetIncludeSet(l,n.optinfo^.life);
|
DFASetIncludeSet(l,n.optinfo^.life);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
l:=n.optinfo^.use;
|
begin
|
||||||
|
l:=n.optinfo^.use;
|
||||||
|
DFASetIncludeSet(l,n.optinfo^.life);
|
||||||
|
end;
|
||||||
updatelifeinfo(n,l);
|
updatelifeinfo(n,l);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -200,12 +216,16 @@ unit optdfa;
|
|||||||
if assigned(node.successor) then
|
if assigned(node.successor) then
|
||||||
CreateInfo(node.successor);
|
CreateInfo(node.successor);
|
||||||
|
|
||||||
|
{$ifdef EXTDEBUG_DFA}
|
||||||
|
writeln('Handling: ',nodetype2str[node.nodetype],'(',node.fileinfo.line,',',node.fileinfo.column,')');
|
||||||
|
{$endif EXTDEBUG_DFA}
|
||||||
{ life:=succesorlive-definition+use }
|
{ life:=succesorlive-definition+use }
|
||||||
|
|
||||||
case node.nodetype of
|
case node.nodetype of
|
||||||
whilerepeatn:
|
whilerepeatn:
|
||||||
begin
|
begin
|
||||||
calclife(node);
|
calclife(node);
|
||||||
|
{ take care of repeat until! }
|
||||||
if lnf_testatbegin in twhilerepeatnode(node).loopflags then
|
if lnf_testatbegin in twhilerepeatnode(node).loopflags then
|
||||||
begin
|
begin
|
||||||
node.allocoptinfo;
|
node.allocoptinfo;
|
||||||
@ -233,6 +253,43 @@ unit optdfa;
|
|||||||
CreateInfo(twhilerepeatnode(node).right);
|
CreateInfo(twhilerepeatnode(node).right);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
forn:
|
||||||
|
begin
|
||||||
|
{
|
||||||
|
left: loopvar
|
||||||
|
right: from
|
||||||
|
t1: to
|
||||||
|
t2: body
|
||||||
|
}
|
||||||
|
calclife(node);
|
||||||
|
node.allocoptinfo;
|
||||||
|
if not(assigned(node.optinfo^.def)) and
|
||||||
|
not(assigned(node.optinfo^.use)) then
|
||||||
|
begin
|
||||||
|
dfainfo.use:=@node.optinfo^.use;
|
||||||
|
dfainfo.def:=@node.optinfo^.def;
|
||||||
|
dfainfo.map:=map;
|
||||||
|
foreachnodestatic(pm_postprocess,tfornode(node).left,@AddDefUse,@dfainfo);
|
||||||
|
foreachnodestatic(pm_postprocess,tfornode(node).right,@AddDefUse,@dfainfo);
|
||||||
|
foreachnodestatic(pm_postprocess,tfornode(node).t1,@AddDefUse,@dfainfo);
|
||||||
|
end;
|
||||||
|
calclife(node);
|
||||||
|
|
||||||
|
{ create life the body }
|
||||||
|
CreateInfo(tfornode(node).t2);
|
||||||
|
|
||||||
|
{ update for node }
|
||||||
|
{ life:=life+use+body }
|
||||||
|
l:=node.optinfo^.life;
|
||||||
|
DFASetIncludeSet(l,node.optinfo^.use);
|
||||||
|
DFASetIncludeSet(l,tfornode(node).t2.optinfo^.life);
|
||||||
|
UpdateLifeInfo(node,l);
|
||||||
|
|
||||||
|
{ ... and a second iteration for fast convergence }
|
||||||
|
CreateInfo(tfornode(node).t2);
|
||||||
|
end;
|
||||||
|
|
||||||
assignn:
|
assignn:
|
||||||
begin
|
begin
|
||||||
if not(assigned(node.optinfo^.def)) and
|
if not(assigned(node.optinfo^.def)) and
|
||||||
@ -332,15 +389,39 @@ unit optdfa;
|
|||||||
{ finally, update the life info of the node }
|
{ finally, update the life info of the node }
|
||||||
UpdateLifeInfo(node,l);
|
UpdateLifeInfo(node,l);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
exitn:
|
exitn:
|
||||||
begin
|
begin
|
||||||
if not(is_void(current_procinfo.procdef.returndef)) then
|
if not(is_void(current_procinfo.procdef.returndef)) and
|
||||||
|
not(current_procinfo.procdef.proctypeoption=potype_constructor) then
|
||||||
begin
|
begin
|
||||||
{ get info from faked resultnode }
|
{ get info from faked resultnode }
|
||||||
node.optinfo^.use:=resultnode.optinfo^.use;
|
node.optinfo^.use:=resultnode.optinfo^.use;
|
||||||
node.optinfo^.life:=node.optinfo^.use;
|
node.optinfo^.life:=node.optinfo^.use;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
raisen:
|
||||||
|
begin
|
||||||
|
calclife(node);
|
||||||
|
node.allocoptinfo;
|
||||||
|
if not(assigned(node.optinfo^.def)) and
|
||||||
|
not(assigned(node.optinfo^.use)) then
|
||||||
|
begin
|
||||||
|
dfainfo.use:=@node.optinfo^.use;
|
||||||
|
dfainfo.def:=@node.optinfo^.def;
|
||||||
|
dfainfo.map:=map;
|
||||||
|
foreachnodestatic(pm_postprocess,traisenode(node).left,@AddDefUse,@dfainfo);
|
||||||
|
foreachnodestatic(pm_postprocess,traisenode(node).right,@AddDefUse,@dfainfo);
|
||||||
|
foreachnodestatic(pm_postprocess,traisenode(node).third,@AddDefUse,@dfainfo);
|
||||||
|
end;
|
||||||
|
calclife(node);
|
||||||
|
end;
|
||||||
|
|
||||||
|
tempcreaten,
|
||||||
|
tempdeleten,
|
||||||
|
inlinen,
|
||||||
|
calln,
|
||||||
nothingn,
|
nothingn,
|
||||||
continuen,
|
continuen,
|
||||||
goton,
|
goton,
|
||||||
@ -350,10 +431,13 @@ unit optdfa;
|
|||||||
calclife(node);
|
calclife(node);
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
internalerror(2007050502);
|
begin
|
||||||
|
writeln(nodetype2str[node.nodetype]);
|
||||||
|
internalerror(2007050502);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
exclude(node.flags,nf_processing);
|
// exclude(node.flags,nf_processing);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -361,7 +445,8 @@ unit optdfa;
|
|||||||
dfarec : tdfainfo;
|
dfarec : tdfainfo;
|
||||||
begin
|
begin
|
||||||
runs:=0;
|
runs:=0;
|
||||||
if not(is_void(current_procinfo.procdef.returndef)) then
|
if not(is_void(current_procinfo.procdef.returndef)) and
|
||||||
|
not(current_procinfo.procdef.proctypeoption=potype_constructor) then
|
||||||
begin
|
begin
|
||||||
{ create a fake node using the result }
|
{ create a fake node using the result }
|
||||||
resultnode:=load_result_node;
|
resultnode:=load_result_node;
|
||||||
@ -378,6 +463,7 @@ unit optdfa;
|
|||||||
inc(runs);
|
inc(runs);
|
||||||
changed:=false;
|
changed:=false;
|
||||||
CreateInfo(node);
|
CreateInfo(node);
|
||||||
|
foreachnodestatic(pm_postprocess,node,@ResetProcessing,nil);
|
||||||
{$ifdef DEBUG_DFA}
|
{$ifdef DEBUG_DFA}
|
||||||
PrintIndexedNodeSet(output,map);
|
PrintIndexedNodeSet(output,map);
|
||||||
PrintDFAInfo(output,node);
|
PrintDFAInfo(output,node);
|
||||||
|
@ -271,9 +271,14 @@ unit optutils;
|
|||||||
result:=p;
|
result:=p;
|
||||||
p.successor:=succ;
|
p.successor:=succ;
|
||||||
end;
|
end;
|
||||||
|
raisen:
|
||||||
|
begin
|
||||||
|
result:=p;
|
||||||
|
{ raise never returns }
|
||||||
|
p.successor:=nil;
|
||||||
|
end;
|
||||||
withn,
|
withn,
|
||||||
tryexceptn,
|
tryexceptn,
|
||||||
raisen,
|
|
||||||
tryfinallyn,
|
tryfinallyn,
|
||||||
onn:
|
onn:
|
||||||
internalerror(2007050501);
|
internalerror(2007050501);
|
||||||
|
@ -756,7 +756,11 @@ implementation
|
|||||||
(pi_is_recursive in flags) then
|
(pi_is_recursive in flags) then
|
||||||
do_opttail(code,procdef);
|
do_opttail(code,procdef);
|
||||||
|
|
||||||
if cs_opt_nodedfa in current_settings.optimizerswitches then
|
if (cs_opt_nodedfa in current_settings.optimizerswitches) and
|
||||||
|
{ creating dfa is not always possible }
|
||||||
|
((flags*[pi_has_assembler_block,pi_uses_exceptions,pi_is_assembler,
|
||||||
|
pi_needs_implicit_finally,pi_has_implicit_finally,pi_has_stackparameter,
|
||||||
|
pi_needs_stackframe])=[]) then
|
||||||
begin
|
begin
|
||||||
createdfainfo(code);
|
createdfainfo(code);
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user