* moved finalization of code generator temps to a node, so it can be getcopy'd

(needed for LLVM, where we need two copies of the finally code: one in case
     an exception occurs, and one in case none is raised)
   o also first finalize parameters and only then code generator temps, since
     in theory the former could create more of the latter

git-svn-id: trunk@40345 -
This commit is contained in:
Jonas Maebe 2018-11-17 22:38:36 +00:00
parent d1361ca6ed
commit 3b9f5a5e96
9 changed files with 74 additions and 32 deletions

View File

@ -4567,13 +4567,14 @@ implementation
cleanup_regvars(list);
{$endif OLDREGVARS}
{ finalize temporary data }
finalizetempvariables(list);
{ finalize paras data }
if assigned(current_procinfo.procdef.parast) and
not(po_assembler in current_procinfo.procdef.procoptions) then
current_procinfo.procdef.parast.SymList.ForEachCall(@final_paras,list);
{ finalize temporary data }
finalizetempvariables(list);
current_procinfo:=old_current_procinfo;
end;

View File

@ -247,8 +247,6 @@ function ti386tryfinallynode.simplify(forinline: boolean): tnode;
if implicitframe then
begin
current_procinfo.finalize_procinfo:=finalizepi;
{ don't leave dangling pointer }
tcgprocinfo(current_procinfo).final_asmnode:=nil;
end;
end;
end;

View File

@ -59,6 +59,13 @@ interface
end;
tspecializenodeclass = class of tspecializenode;
tfinalizetempsnode = class(tnode)
constructor create;virtual;
function pass_1 : tnode;override;
function pass_typecheck:tnode;override;
end;
tfinalizetempsnodeclass = class of tfinalizetempsnode;
tasmnode = class(tnode)
p_asm : TAsmList;
currenttai : tai;
@ -289,6 +296,7 @@ interface
cnothingnode : tnothingnodeclass = tnothingnode;
cerrornode : terrornodeclass = terrornode;
cspecializenode : tspecializenodeclass = tspecializenode;
cfinalizetempsnode: tfinalizetempsnodeclass = tfinalizetempsnode;
casmnode : tasmnodeclass = tasmnode;
cstatementnode : tstatementnodeclass = tstatementnode;
cblocknode : tblocknodeclass = tblocknode;
@ -363,7 +371,6 @@ implementation
end;
{*****************************************************************************
TFIRSTNOTHING
*****************************************************************************}
@ -456,6 +463,28 @@ implementation
end;
{*****************************************************************************
TFINALIZETEMPSNODE
*****************************************************************************}
constructor tfinalizetempsnode.create;
begin
inherited create(finalizetempsn);
end;
function tfinalizetempsnode.pass_1: tnode;
begin
result:=nil;
expectloc:=LOC_VOID;
end;
function tfinalizetempsnode.pass_typecheck: tnode;
begin
resultdef:=voidtype;
result:=nil;
end;
{*****************************************************************************
TSTATEMENTNODE
*****************************************************************************}

View File

@ -68,6 +68,10 @@ interface
procedure pass_generate_code;override;
end;
tcgfinalizetempsnode = class(tfinalizetempsnode)
procedure pass_generate_code; override;
end;
implementation
uses
@ -714,6 +718,17 @@ interface
end;
{*****************************************************************************
TCGFINALIZETEMPSNODE
*****************************************************************************}
procedure tcgfinalizetempsnode.pass_generate_code;
begin
hlcg.gen_finalize_code(current_asmdata.CurrAsmList);
location.loc:=LOC_VOID;
end;
begin
cnothingnode:=tcgnothingnode;
casmnode:=tcgasmnode;
@ -722,4 +737,5 @@ begin
ctempcreatenode:=tcgtempcreatenode;
ctemprefnode:=tcgtemprefnode;
ctempdeletenode:=tcgtempdeletenode;
cfinalizetempsnode:=tcgfinalizetempsnode;
end.

View File

@ -110,7 +110,8 @@ interface
loadparentfpn, { Load the framepointer of the parent for nested procedures }
objcselectorn, { node for an Objective-C message selector }
objcprotocoln, { node for an Objective-C @protocol() expression (returns metaclass associated with protocol) }
specializen { parser-only node to handle Delphi-mode inline specializations }
specializen, { parser-only node to handle Delphi-mode inline specializations }
finalizetempsn { Internal node used to clean up code generator temps (warning: must NOT create additional tepms that may need to be finalised!) }
);
tnodetypeset = set of tnodetype;
@ -194,7 +195,8 @@ interface
'loadparentfpn',
'objcselectorn',
'objcprotocoln',
'specializen');
'specializen',
'finalizetempsn');
{ a set containing all const nodes }
nodetype_const = [niln,

View File

@ -963,6 +963,11 @@ implementation
end;
end;
finalizetempsn:
begin
result:=NODE_COMPLEXITY_INF;
exit;
end;
else
begin
result := NODE_COMPLEXITY_INF;

View File

@ -156,7 +156,8 @@ implementation
'loadparentfpn',
'objselectorn',
'objcprotocoln',
'specializen'
'specializen',
'finalizetemps'
);
var
p: pchar;

View File

@ -47,9 +47,8 @@ interface
loadpara_asmnode,
exitlabel_asmnode,
stackcheck_asmnode,
init_asmnode,
final_asmnode : tasmnode;
final_used : boolean;
init_asmnode : tasmnode;
temps_finalized : boolean;
dfabuilder : TDFABuilder;
destructor destroy;override;
@ -678,8 +677,6 @@ implementation
destructor tcgprocinfo.destroy;
begin
code.free;
if not final_used then
final_asmnode.free;
inherited destroy;
end;
@ -768,9 +765,9 @@ implementation
(cs_implicit_exceptions in current_settings.moduleswitches)) then
begin
include(tocode.flags,nf_block_with_exit);
addstatement(newstatement,final_asmnode);
addstatement(newstatement,cfinalizetempsnode.create);
cnodeutils.procdef_block_add_implicit_finalize_nodes(procdef,newstatement);
final_used:=true;
temps_finalized:=true;
end;
{ construction successful -> beforedestruction should be called
@ -880,8 +877,7 @@ implementation
{ Generate code/locations used at end of proc }
current_filepos:=exitpos;
exitlabel_asmnode:=casmnode.create_get_position;
final_asmnode:=casmnode.create_get_position;
final_used:=false;
temps_finalized:=false;
bodyexitcode:=generate_bodyexit_block;
{ Generate procedure by combining init+body+final,
@ -914,13 +910,13 @@ implementation
current_filepos:=exitpos;
{ Generate code that will be in the try...finally }
finalcode:=internalstatements(codestatement);
addstatement(codestatement,final_asmnode);
addstatement(codestatement,cfinalizetempsnode.create);
cnodeutils.procdef_block_add_implicit_finalize_nodes(procdef,codestatement);
final_used:=true;
temps_finalized:=true;
current_filepos:=entrypos;
wrappedbody:=ctryfinallynode.create_implicit(code,finalcode);
{ afterconstruction must be called after final_asmnode, because it
{ afterconstruction must be called after finalizetemps, because it
has to execute after the temps have been finalised in case of a
refcounted class (afterconstruction decreases the refcount
without freeing the instance if the count becomes nil, while
@ -947,12 +943,12 @@ implementation
addstatement(newstatement,bodyexitcode);
if not is_constructor then
begin
addstatement(newstatement,final_asmnode);
addstatement(newstatement,cfinalizetempsnode.create);
cnodeutils.procdef_block_add_implicit_finalize_nodes(procdef,newstatement);
final_used:=true;
temps_finalized:=true;
end;
end;
if not final_used then
if not temps_finalized then
begin
current_filepos:=exitpos;
cnodeutils.procdef_block_add_implicit_finalize_nodes(procdef,newstatement);
@ -1569,16 +1565,13 @@ implementation
if assigned(finalize_procinfo) then
generate_exceptfilter(tcgprocinfo(finalize_procinfo))
else
else if not temps_finalized then
begin
hlcg.gen_finalize_code(templist);
{ the finalcode must be concated if there was no position available,
using insertlistafter will result in an insert at the start
when currentai=nil }
if assigned(final_asmnode) and assigned(final_asmnode.currenttai) then
aktproccode.insertlistafter(final_asmnode.currenttai,templist)
else
aktproccode.concatlist(templist);
aktproccode.concatlist(templist);
end;
{ insert exit label at the correct position }
hlcg.a_label(templist,CurrExitLabel);
@ -1753,7 +1746,6 @@ implementation
delete_marker(exitlabel_asmnode);
delete_marker(stackcheck_asmnode);
delete_marker(init_asmnode);
delete_marker(final_asmnode);
{$ifndef NoOpt}
if not(cs_no_regalloc in current_settings.globalswitches) then

View File

@ -216,8 +216,6 @@ function tx64tryfinallynode.simplify(forinline: boolean): tnode;
if implicitframe then
begin
current_procinfo.finalize_procinfo:=finalizepi;
{ don't leave dangling pointer }
tcgprocinfo(current_procinfo).final_asmnode:=nil;
end;
end;
end;