diff options
-rw-r--r-- | compiler/optdfa.pas | 47 | ||||
-rw-r--r-- | compiler/optutils.pas | 34 |
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; |