+ life dfa for if, label and goto

git-svn-id: trunk@7297 -
This commit is contained in:
florian 2007-05-07 19:14:21 +00:00
parent 85406e8a15
commit 62d54389c8
2 changed files with 92 additions and 31 deletions

View File

@ -20,7 +20,7 @@
****************************************************************************
}
{ $define DEBUG_DFA}
{$define DEBUG_DFA}
{ this unit implements routines to perform dfa }
unit optdfa;
@ -154,7 +154,6 @@ unit optdfa;
var
l : TDFASet;
begin
n.allocoptinfo;
if assigned(n.successor) then
begin
{
@ -187,6 +186,9 @@ unit optdfa;
if node=nil then
exit;
{ ensure we've already optinfo set }
node.allocoptinfo;
if nf_processing in node.flags then
exit;
include(node.flags,nf_processing);
@ -202,7 +204,6 @@ unit optdfa;
calclife(node);
if lnf_testatbegin in twhilerepeatnode(node).loopflags then
begin
{ first, do things as usual, get life information from the successor }
node.allocoptinfo;
if not(assigned(node.optinfo^.def)) and
not(assigned(node.optinfo^.use)) then
@ -228,40 +229,71 @@ unit optdfa;
CreateInfo(twhilerepeatnode(node).right);
end;
end;
assignn:
begin
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,node,@AddDefUse,@dfainfo);
end;
calclife(node);
end;
statementn:
begin
{ actually an expression doing something? }
case tstatementnode(node).statement.nodetype of
assignn:
begin
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,tstatementnode(node).left,@AddDefUse,@dfainfo);
end;
calclife(node);
end;
else
begin
{ nested statement }
CreateInfo(tstatementnode(node).statement);
{ inherit info }
node.allocoptinfo;
node.optinfo^.life:=tstatementnode(node).statement.optinfo^.life;
end;
end;
{ nested statement }
CreateInfo(tstatementnode(node).statement);
{ inherit info }
node.optinfo^.life:=tstatementnode(node).statement.optinfo^.life;
end;
blockn:
begin
CreateInfo(tblocknode(node).statements);
node.allocoptinfo;
if assigned(tblocknode(node).statements) then
node.optinfo^.life:=tblocknode(node).statements.optinfo^.life;
end;
ifn:
begin
{ get information from cond. expression }
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,tifnode(node).left,@AddDefUse,@dfainfo);
end;
{ create life info for left and right node }
CreateInfo(tifnode(node).right);
CreateInfo(tifnode(node).t1);
{ ensure that we don't remove life info }
l:=node.optinfo^.life;
{ get life info from then branch }
if assigned(tifnode(node).right) then
DFASetIncludeSet(l,tifnode(node).right.optinfo^.life);
{ get life info from else branch }
if assigned(tifnode(node).t1) then
DFASetIncludeSet(l,tifnode(node).t1.optinfo^.life)
else
if assigned(node.successor) then
DFASetIncludeSet(l,node.successor.optinfo^.life);
{ add use info from cond. expression }
DFASetIncludeSet(l,tifnode(node).optinfo^.use);
{ finally, update the life info of the node }
UpdateLifeInfo(node,l);
end;
goton:
begin
calclife(node);
end;
labeln:
begin
calclife(node);
end;
else
internalerror(2007050502);
end;

View File

@ -210,6 +210,36 @@ unit optutils;
Breakstack.Delete(Breakstack.Count-1);
Continuestack.Delete(Continuestack.Count-1);
end;
ifn:
begin
result:=p;
DoSet(tifnode(p).right,succ);
DoSet(tifnode(p).t1,succ);
p.successor:=succ;
end;
labeln:
begin
result:=p;
if assigned(tlabelnode(p).left) then
begin
DoSet(tlabelnode(p).left,succ);
p.successor:=tlabelnode(p).left;
end
else
p.successor:=succ;
end;
assignn:
begin
result:=p;
p.successor:=succ;
end;
goton:
begin
result:=p;
if not(assigned(tgotonode(p).labelnode)) then
internalerror(2007050701);
p.successor:=tgotonode(p).labelnode;
end;
{ exit is actually a jump to some final. code
exitn:
begin
@ -217,12 +247,11 @@ unit optutils;
p.successor:=nil;
end;
}
ifn,
inlinen,
calln,
exitn,
withn,
casen,
labeln,
goton,
tryexceptn,
raisen,
tryfinallyn,