From 709ba5e053e87d060f28615844c79f5ba911a24e Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 21 Apr 2013 16:53:25 +0000 Subject: [PATCH] + introduce cnf_call_never_returns to signal the dfa if a call node never returns * get rid of tcgraisenode.pass_generate_code, it is replaced by compiler proc. call nodes generated in pass_1 git-svn-id: branches/i8086@24288 - --- compiler/ncal.pas | 3 +- compiler/ncgflw.pas | 122 ------------------------------------------ compiler/nflw.pas | 65 +++++++++++++++------- compiler/optdfa.pas | 21 +------- compiler/optutils.pas | 5 +- 5 files changed, 54 insertions(+), 162 deletions(-) diff --git a/compiler/ncal.pas b/compiler/ncal.pas index c5962e3b1a..adc98d07dd 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -51,7 +51,8 @@ interface cnf_create_failed, { exception thrown in constructor -> don't call beforedestruction } cnf_objc_processed, { the procedure name has been set to the appropriate objc_msgSend* variant -> don't process again } cnf_objc_id_call, { the procedure is a member call via id -> any ObjC method of any ObjC type in scope is fair game } - cnf_unit_specified { the unit in which the procedure has to be searched has been specified } + cnf_unit_specified, { the unit in which the procedure has to be searched has been specified } + cnf_call_never_returns { information for the dfa that a subroutine never returns } ); tcallnodeflags = set of tcallnodeflag; diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas index b0ba6e9922..2fd1a3a590 100644 --- a/compiler/ncgflw.pas +++ b/compiler/ncgflw.pas @@ -72,10 +72,6 @@ interface procedure pass_generate_code;override; end; - tcgraisenode = class(traisenode) - procedure pass_generate_code;override; - end; - tcgtryexceptnode = class(ttryexceptnode) procedure pass_generate_code;override; end; @@ -949,122 +945,6 @@ implementation end; -{***************************************************************************** - SecondRaise -*****************************************************************************} - - procedure tcgraisenode.pass_generate_code; - - var - a : tasmlabel; - href2: treference; - paraloc1,paraloc2,paraloc3 : tcgpara; - pd : tprocdef; - begin - location_reset(location,LOC_VOID,OS_NO); - - if assigned(left) then - begin - pd:=search_system_proc('fpc_raiseexception'); - paraloc1.init; - paraloc2.init; - paraloc3.init; - paramanager.getintparaloc(pd,1,paraloc1); - paramanager.getintparaloc(pd,2,paraloc2); - paramanager.getintparaloc(pd,3,paraloc3); - - { multiple parameters? } - if assigned(right) then - begin - { frame tree } - if assigned(third) then - secondpass(third); - secondpass(right); - end; - secondpass(left); - if codegenerror then - exit; - - { Push parameters } - { ugly code repetition follows for left to right and right to left calling conventions } - { TODO: refactor this somehow } - if pd.is_pushleftright then - begin - cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1); - if assigned(right) then - begin - { push address } - cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2); - { frame tree } - if assigned(third) then - cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,third.location,paraloc3) - else - cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc3); - end - else - begin - { get current address } - current_asmdata.getaddrlabel(a); - cg.a_label(current_asmdata.CurrAsmList,a); - reference_reset_symbol(href2,a,0,1); - { push current address } - if target_info.system <> system_powerpc_macos then - cg.a_loadaddr_ref_cgpara(current_asmdata.CurrAsmList,href2,paraloc2) - else - cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc2); - { push current frame } - cg.a_load_reg_cgpara(current_asmdata.CurrAsmList,OS_ADDR,NR_FRAME_POINTER_REG,paraloc3); - end; - end - else - begin - if assigned(right) then - begin - { frame tree } - if assigned(third) then - cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,third.location,paraloc3) - else - cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc3); - { push address } - cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,right.location,paraloc2); - end - else - begin - { get current address } - current_asmdata.getaddrlabel(a); - cg.a_label(current_asmdata.CurrAsmList,a); - reference_reset_symbol(href2,a,0,1); - { push current frame } - cg.a_load_reg_cgpara(current_asmdata.CurrAsmList,OS_ADDR,NR_FRAME_POINTER_REG,paraloc3); - { push current address } - if target_info.system <> system_powerpc_macos then - cg.a_loadaddr_ref_cgpara(current_asmdata.CurrAsmList,href2,paraloc2) - else - cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,paraloc2); - end; - cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,left.location,paraloc1); - end; - paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1); - paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc2); - paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc3); - cg.allocallcpuregisters(current_asmdata.CurrAsmList); - cg.a_call_name(current_asmdata.CurrAsmList,'FPC_RAISEEXCEPTION',false); - cg.deallocallcpuregisters(current_asmdata.CurrAsmList); - - paraloc1.done; - paraloc2.done; - paraloc3.done; - end - else - begin - cg.allocallcpuregisters(current_asmdata.CurrAsmList); - cg.a_call_name(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK',false); - cg.a_call_name(current_asmdata.CurrAsmList,'FPC_RERAISE',false); - cg.deallocallcpuregisters(current_asmdata.CurrAsmList); - end; - end; - - {***************************************************************************** SecondTryExcept *****************************************************************************} @@ -1072,7 +952,6 @@ implementation var endexceptlabel : tasmlabel; - { does the necessary things to clean up the object stack } { in the except block } procedure cleanupobjectstack; @@ -1693,7 +1572,6 @@ begin ccontinuenode:=tcgcontinuenode; cgotonode:=tcggotonode; clabelnode:=tcglabelnode; - craisenode:=tcgraisenode; ctryexceptnode:=tcgtryexceptnode; ctryfinallynode:=tcgtryfinallynode; connode:=tcgonnode; diff --git a/compiler/nflw.pas b/compiler/nflw.pas index 9992fc2a16..3e740bcc3a 100644 --- a/compiler/nflw.pas +++ b/compiler/nflw.pas @@ -1937,26 +1937,55 @@ implementation function traisenode.pass_1 : tnode; + var + statements : tstatementnode; + current_addr : tlabelnode; + raisenode : tcallnode; begin - result:=nil; - include(current_procinfo.flags,pi_do_call); - expectloc:=LOC_VOID; - if assigned(left) then - begin - { first para must be a _class_ } - firstpass(left); - { insert needed typeconvs for addr,frame } - if assigned(right) then - begin - { addr } - firstpass(right); - { frame } - if assigned(third) then - firstpass(third); - end; - end; - end; + result:=internalstatements(statements); + if assigned(left) then + begin + { first para must be a class } + firstpass(left); + { insert needed typeconvs for addr,frame } + if assigned(right) then + begin + { addr } + firstpass(right); + { frame } + if assigned(third) then + firstpass(third) + else + third:=cpointerconstnode.Create(0,voidpointertype); + end + else + begin + right:=cloadparentfpnode.create(current_procinfo.procdef); + current_addr:=clabelnode.create(cnothingnode.create,tlabelsym.create('$raiseaddr')); + addstatement(statements,current_addr); + third:=caddrnode.create(cloadnode.create(current_addr.labsym,current_addr.labsym.owner)); + end; + + raisenode:=ccallnode.createintern('fpc_raiseexception', + ccallparanode.create(third, + ccallparanode.create(right, + ccallparanode.create(left,nil))) + ); + include(raisenode.callnodeflags,cnf_call_never_returns); + addstatement(statements,raisenode); + end + else + begin + addstatement(statements,ccallnode.createintern('fpc_popaddrstack',nil)); + raisenode:=ccallnode.createintern('fpc_reraise',nil); + include(raisenode.callnodeflags,cnf_call_never_returns); + addstatement(statements,raisenode); + end; + left:=nil; + right:=nil; + third:=nil; + end; {***************************************************************************** TTRYEXCEPTNODE diff --git a/compiler/optdfa.pas b/compiler/optdfa.pas index 28f2f6fd46..e4734bca55 100644 --- a/compiler/optdfa.pas +++ b/compiler/optdfa.pas @@ -222,7 +222,8 @@ unit optdfa; begin { last node, not exit or raise node and function? } if assigned(resultnode) and - not(node.nodetype in [raisen,exitn]) then + not(node.nodetype=exitn) and + not((node.nodetype=calln) and (cnf_call_never_returns in tcallnode(node).callnodeflags)) then begin { if yes, result lifes } DFASetDiff(l,resultnode.optinfo^.life,n.optinfo^.def); @@ -499,24 +500,6 @@ unit optdfa; end; end; - raisen: - begin - if not(assigned(node.optinfo^.life)) 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); - { update node } - l:=node.optinfo^.life; - DFASetIncludeSet(l,node.optinfo^.use); - UpdateLifeInfo(node,l); - printdfainfo(output,node); - end; - end; - calln: begin if not(assigned(node.optinfo^.def)) and diff --git a/compiler/optutils.pas b/compiler/optutils.pas index 2cca995efc..a82286274a 100644 --- a/compiler/optutils.pas +++ b/compiler/optutils.pas @@ -52,7 +52,7 @@ unit optutils; uses verbose, optbase, - nbas,nflw,nutils,nset; + ncal,nbas,nflw,nutils,nset; function TIndexedNodeSet.Add(node : tnode) : boolean; var @@ -264,7 +264,8 @@ unit optutils; begin { not sure if this is enough (FK) } result:=p; - p.successor:=succ; + if not(cnf_call_never_returns in tcallnode(p).callnodeflags) then + p.successor:=succ; end; inlinen: begin