+ 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 -
This commit is contained in:
florian 2013-04-21 16:53:25 +00:00
parent 57777945a8
commit 709ba5e053
5 changed files with 54 additions and 162 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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