mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-28 07:31:23 +02:00
+ 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:
parent
57777945a8
commit
709ba5e053
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user