* life info generation works for the whole compiler if exception catching blocks are ignored

git-svn-id: trunk@7561 -
This commit is contained in:
florian 2007-06-03 16:37:59 +00:00
parent 496d73dc9d
commit 2761b9e096
3 changed files with 104 additions and 9 deletions

View File

@ -20,7 +20,8 @@
****************************************************************************
}
{$define DEBUG_DFA}
{ $define DEBUG_DFA}
{ $define EXTDEBUG_DFA}
{ this unit implements routines to perform dfa }
unit optdfa;
@ -44,7 +45,7 @@ unit optdfa;
globtype,globals,
verbose,
cpuinfo,
symdef,
symconst,symdef,
defutil,
procinfo,
nutils,
@ -123,6 +124,13 @@ unit optdfa;
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);
var
@ -149,6 +157,11 @@ unit optdfa;
writeln;
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;
node.optinfo^.life:=l;
end;
@ -177,7 +190,10 @@ unit optdfa;
DFASetIncludeSet(l,n.optinfo^.life);
end
else
l:=n.optinfo^.use;
begin
l:=n.optinfo^.use;
DFASetIncludeSet(l,n.optinfo^.life);
end;
updatelifeinfo(n,l);
end;
@ -200,12 +216,16 @@ unit optdfa;
if assigned(node.successor) then
CreateInfo(node.successor);
{$ifdef EXTDEBUG_DFA}
writeln('Handling: ',nodetype2str[node.nodetype],'(',node.fileinfo.line,',',node.fileinfo.column,')');
{$endif EXTDEBUG_DFA}
{ life:=succesorlive-definition+use }
case node.nodetype of
whilerepeatn:
begin
calclife(node);
{ take care of repeat until! }
if lnf_testatbegin in twhilerepeatnode(node).loopflags then
begin
node.allocoptinfo;
@ -233,6 +253,43 @@ unit optdfa;
CreateInfo(twhilerepeatnode(node).right);
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:
begin
if not(assigned(node.optinfo^.def)) and
@ -332,15 +389,39 @@ unit optdfa;
{ finally, update the life info of the node }
UpdateLifeInfo(node,l);
end;
exitn:
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
{ get info from faked resultnode }
node.optinfo^.use:=resultnode.optinfo^.use;
node.optinfo^.life:=node.optinfo^.use;
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,
continuen,
goton,
@ -350,10 +431,13 @@ unit optdfa;
calclife(node);
end;
else
internalerror(2007050502);
begin
writeln(nodetype2str[node.nodetype]);
internalerror(2007050502);
end;
end;
exclude(node.flags,nf_processing);
// exclude(node.flags,nf_processing);
end;
var
@ -361,7 +445,8 @@ unit optdfa;
dfarec : tdfainfo;
begin
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
{ create a fake node using the result }
resultnode:=load_result_node;
@ -378,6 +463,7 @@ unit optdfa;
inc(runs);
changed:=false;
CreateInfo(node);
foreachnodestatic(pm_postprocess,node,@ResetProcessing,nil);
{$ifdef DEBUG_DFA}
PrintIndexedNodeSet(output,map);
PrintDFAInfo(output,node);

View File

@ -271,9 +271,14 @@ unit optutils;
result:=p;
p.successor:=succ;
end;
raisen:
begin
result:=p;
{ raise never returns }
p.successor:=nil;
end;
withn,
tryexceptn,
raisen,
tryfinallyn,
onn:
internalerror(2007050501);

View File

@ -756,7 +756,11 @@ implementation
(pi_is_recursive in flags) then
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
createdfainfo(code);
end;