mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-30 18:42:34 +02:00
* 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:
parent
d1361ca6ed
commit
3b9f5a5e96
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*****************************************************************************}
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -963,6 +963,11 @@ implementation
|
||||
end;
|
||||
|
||||
end;
|
||||
finalizetempsn:
|
||||
begin
|
||||
result:=NODE_COMPLEXITY_INF;
|
||||
exit;
|
||||
end;
|
||||
else
|
||||
begin
|
||||
result := NODE_COMPLEXITY_INF;
|
||||
|
@ -156,7 +156,8 @@ implementation
|
||||
'loadparentfpn',
|
||||
'objselectorn',
|
||||
'objcprotocoln',
|
||||
'specializen'
|
||||
'specializen',
|
||||
'finalizetemps'
|
||||
);
|
||||
var
|
||||
p: pchar;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user