mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-18 23:09:18 +02:00
+ life dfa for if, label and goto
git-svn-id: trunk@7297 -
This commit is contained in:
parent
85406e8a15
commit
62d54389c8
@ -20,7 +20,7 @@
|
|||||||
****************************************************************************
|
****************************************************************************
|
||||||
}
|
}
|
||||||
|
|
||||||
{ $define DEBUG_DFA}
|
{$define DEBUG_DFA}
|
||||||
|
|
||||||
{ this unit implements routines to perform dfa }
|
{ this unit implements routines to perform dfa }
|
||||||
unit optdfa;
|
unit optdfa;
|
||||||
@ -154,7 +154,6 @@ unit optdfa;
|
|||||||
var
|
var
|
||||||
l : TDFASet;
|
l : TDFASet;
|
||||||
begin
|
begin
|
||||||
n.allocoptinfo;
|
|
||||||
if assigned(n.successor) then
|
if assigned(n.successor) then
|
||||||
begin
|
begin
|
||||||
{
|
{
|
||||||
@ -187,6 +186,9 @@ unit optdfa;
|
|||||||
if node=nil then
|
if node=nil then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
|
{ ensure we've already optinfo set }
|
||||||
|
node.allocoptinfo;
|
||||||
|
|
||||||
if nf_processing in node.flags then
|
if nf_processing in node.flags then
|
||||||
exit;
|
exit;
|
||||||
include(node.flags,nf_processing);
|
include(node.flags,nf_processing);
|
||||||
@ -202,7 +204,6 @@ unit optdfa;
|
|||||||
calclife(node);
|
calclife(node);
|
||||||
if lnf_testatbegin in twhilerepeatnode(node).loopflags then
|
if lnf_testatbegin in twhilerepeatnode(node).loopflags then
|
||||||
begin
|
begin
|
||||||
{ first, do things as usual, get life information from the successor }
|
|
||||||
node.allocoptinfo;
|
node.allocoptinfo;
|
||||||
if not(assigned(node.optinfo^.def)) and
|
if not(assigned(node.optinfo^.def)) and
|
||||||
not(assigned(node.optinfo^.use)) then
|
not(assigned(node.optinfo^.use)) then
|
||||||
@ -228,40 +229,71 @@ unit optdfa;
|
|||||||
CreateInfo(twhilerepeatnode(node).right);
|
CreateInfo(twhilerepeatnode(node).right);
|
||||||
end;
|
end;
|
||||||
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:
|
statementn:
|
||||||
begin
|
begin
|
||||||
{ actually an expression doing something? }
|
{ nested statement }
|
||||||
case tstatementnode(node).statement.nodetype of
|
CreateInfo(tstatementnode(node).statement);
|
||||||
assignn:
|
{ inherit info }
|
||||||
begin
|
node.optinfo^.life:=tstatementnode(node).statement.optinfo^.life;
|
||||||
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;
|
|
||||||
end;
|
end;
|
||||||
blockn:
|
blockn:
|
||||||
begin
|
begin
|
||||||
CreateInfo(tblocknode(node).statements);
|
CreateInfo(tblocknode(node).statements);
|
||||||
node.allocoptinfo;
|
|
||||||
if assigned(tblocknode(node).statements) then
|
if assigned(tblocknode(node).statements) then
|
||||||
node.optinfo^.life:=tblocknode(node).statements.optinfo^.life;
|
node.optinfo^.life:=tblocknode(node).statements.optinfo^.life;
|
||||||
end;
|
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
|
else
|
||||||
internalerror(2007050502);
|
internalerror(2007050502);
|
||||||
end;
|
end;
|
||||||
|
@ -210,6 +210,36 @@ unit optutils;
|
|||||||
Breakstack.Delete(Breakstack.Count-1);
|
Breakstack.Delete(Breakstack.Count-1);
|
||||||
Continuestack.Delete(Continuestack.Count-1);
|
Continuestack.Delete(Continuestack.Count-1);
|
||||||
end;
|
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
|
{ exit is actually a jump to some final. code
|
||||||
exitn:
|
exitn:
|
||||||
begin
|
begin
|
||||||
@ -217,12 +247,11 @@ unit optutils;
|
|||||||
p.successor:=nil;
|
p.successor:=nil;
|
||||||
end;
|
end;
|
||||||
}
|
}
|
||||||
ifn,
|
inlinen,
|
||||||
|
calln,
|
||||||
exitn,
|
exitn,
|
||||||
withn,
|
withn,
|
||||||
casen,
|
casen,
|
||||||
labeln,
|
|
||||||
goton,
|
|
||||||
tryexceptn,
|
tryexceptn,
|
||||||
raisen,
|
raisen,
|
||||||
tryfinallyn,
|
tryfinallyn,
|
||||||
|
Loading…
Reference in New Issue
Block a user