summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optdfa.pas47
-rw-r--r--compiler/optutils.pas34
2 files changed, 73 insertions, 8 deletions
diff --git a/compiler/optdfa.pas b/compiler/optdfa.pas
index 29ffed1f11..ac0edb3694 100644
--- a/compiler/optdfa.pas
+++ b/compiler/optdfa.pas
@@ -48,7 +48,7 @@ unit optdfa;
defutil,
procinfo,
nutils,
- nbas,nflw,ncon,ninl,ncal,
+ nbas,nflw,ncon,ninl,ncal,nset,
optbase,optutils;
@@ -184,6 +184,7 @@ unit optdfa;
var
dfainfo : tdfainfo;
l : TDFASet;
+ i : longint;
begin
if node=nil then
@@ -244,6 +245,7 @@ unit optdfa;
end;
calclife(node);
end;
+
statementn:
begin
{ nested statement }
@@ -251,12 +253,14 @@ unit optdfa;
{ inherit info }
node.optinfo^.life:=tstatementnode(node).statement.optinfo^.life;
end;
+
blockn:
begin
CreateInfo(tblocknode(node).statements);
if assigned(tblocknode(node).statements) then
node.optinfo^.life:=tblocknode(node).statements.optinfo^.life;
end;
+
ifn:
begin
{ get information from cond. expression }
@@ -284,11 +288,50 @@ unit optdfa;
else
if assigned(node.successor) then
DFASetIncludeSet(l,node.successor.optinfo^.life);
- { add use info from cond. expression }
+ { add use info from the cond. expression }
DFASetIncludeSet(l,tifnode(node).optinfo^.use);
{ finally, update the life info of the node }
UpdateLifeInfo(node,l);
end;
+
+ casen:
+ begin
+ { get information from "case" 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,tcasenode(node).left,@AddDefUse,@dfainfo);
+ end;
+
+ { create life info for block and else nodes }
+ for i:=0 to tcasenode(node).blocks.count-1 do
+ CreateInfo(pcaseblock(tcasenode(node).blocks[i])^.statement);
+
+ CreateInfo(tcasenode(node).elseblock);
+
+ { ensure that we don't remove life info }
+ l:=node.optinfo^.life;
+
+ { get life info from case branches }
+ for i:=0 to tcasenode(node).blocks.count-1 do
+ DFASetIncludeSet(l,pcaseblock(tcasenode(node).blocks[i])^.statement.optinfo^.life);
+
+ { get life info from else branch or the succesor }
+ if assigned(tcasenode(node).elseblock) then
+ DFASetIncludeSet(l,tcasenode(node).elseblock.optinfo^.life)
+ else
+ if assigned(node.successor) then
+ DFASetIncludeSet(l,node.successor.optinfo^.life);
+
+ { add use info from the "case" expression }
+ DFASetIncludeSet(l,tcasenode(node).optinfo^.use);
+
+ { finally, update the life info of the node }
+ UpdateLifeInfo(node,l);
+ end;
exitn:
begin
if not(is_void(current_procinfo.procdef.returndef)) then
diff --git a/compiler/optutils.pas b/compiler/optutils.pas
index 4b2171426a..e0fb9dcd02 100644
--- a/compiler/optutils.pas
+++ b/compiler/optutils.pas
@@ -47,7 +47,7 @@ unit optutils;
uses
verbose,
optbase,
- nbas,nflw,nutils;
+ nbas,nflw,nutils,nset;
function TIndexedNodeSet.Add(node : tnode) : boolean;
var
@@ -142,6 +142,7 @@ unit optutils;
function DoSet(p : tnode;succ : tnode) : tnode;
var
hp1,hp2 : tnode;
+ i : longint;
begin
result:=nil;
if p=nil then
@@ -245,15 +246,36 @@ unit optutils;
result:=p;
p.successor:=nil;
end;
- inlinen,
- calln,
+ casen:
+ begin
+ result:=p;
+ DoSet(tcasenode(p).elseblock,succ);
+ for i:=0 to tcasenode(p).blocks.count-1 do
+ DoSet(pcaseblock(tcasenode(p).blocks[i])^.statement,succ);
+ p.successor:=succ;
+ end;
+ calln:
+ begin
+ { not sure if this is enough (FK) }
+ result:=p;
+ p.successor:=succ;
+ end;
+ inlinen:
+ begin
+ { not sure if this is enough (FK) }
+ result:=p;
+ p.successor:=succ;
+ end;
+ nothingn:
+ begin
+ result:=p;
+ p.successor:=succ;
+ end;
withn,
- casen,
tryexceptn,
raisen,
tryfinallyn,
- onn,
- nothingn:
+ onn:
internalerror(2007050501);
end;
end;