mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-05 13:25:58 +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);
|
cleanup_regvars(list);
|
||||||
{$endif OLDREGVARS}
|
{$endif OLDREGVARS}
|
||||||
|
|
||||||
{ finalize temporary data }
|
|
||||||
finalizetempvariables(list);
|
|
||||||
|
|
||||||
{ finalize paras data }
|
{ finalize paras data }
|
||||||
if assigned(current_procinfo.procdef.parast) and
|
if assigned(current_procinfo.procdef.parast) and
|
||||||
not(po_assembler in current_procinfo.procdef.procoptions) then
|
not(po_assembler in current_procinfo.procdef.procoptions) then
|
||||||
current_procinfo.procdef.parast.SymList.ForEachCall(@final_paras,list);
|
current_procinfo.procdef.parast.SymList.ForEachCall(@final_paras,list);
|
||||||
|
|
||||||
|
{ finalize temporary data }
|
||||||
|
finalizetempvariables(list);
|
||||||
|
|
||||||
current_procinfo:=old_current_procinfo;
|
current_procinfo:=old_current_procinfo;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -247,8 +247,6 @@ function ti386tryfinallynode.simplify(forinline: boolean): tnode;
|
|||||||
if implicitframe then
|
if implicitframe then
|
||||||
begin
|
begin
|
||||||
current_procinfo.finalize_procinfo:=finalizepi;
|
current_procinfo.finalize_procinfo:=finalizepi;
|
||||||
{ don't leave dangling pointer }
|
|
||||||
tcgprocinfo(current_procinfo).final_asmnode:=nil;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -59,6 +59,13 @@ interface
|
|||||||
end;
|
end;
|
||||||
tspecializenodeclass = class of tspecializenode;
|
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)
|
tasmnode = class(tnode)
|
||||||
p_asm : TAsmList;
|
p_asm : TAsmList;
|
||||||
currenttai : tai;
|
currenttai : tai;
|
||||||
@ -289,6 +296,7 @@ interface
|
|||||||
cnothingnode : tnothingnodeclass = tnothingnode;
|
cnothingnode : tnothingnodeclass = tnothingnode;
|
||||||
cerrornode : terrornodeclass = terrornode;
|
cerrornode : terrornodeclass = terrornode;
|
||||||
cspecializenode : tspecializenodeclass = tspecializenode;
|
cspecializenode : tspecializenodeclass = tspecializenode;
|
||||||
|
cfinalizetempsnode: tfinalizetempsnodeclass = tfinalizetempsnode;
|
||||||
casmnode : tasmnodeclass = tasmnode;
|
casmnode : tasmnodeclass = tasmnode;
|
||||||
cstatementnode : tstatementnodeclass = tstatementnode;
|
cstatementnode : tstatementnodeclass = tstatementnode;
|
||||||
cblocknode : tblocknodeclass = tblocknode;
|
cblocknode : tblocknodeclass = tblocknode;
|
||||||
@ -363,7 +371,6 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
TFIRSTNOTHING
|
TFIRSTNOTHING
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
@ -456,6 +463,28 @@ implementation
|
|||||||
end;
|
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
|
TSTATEMENTNODE
|
||||||
*****************************************************************************}
|
*****************************************************************************}
|
||||||
|
@ -68,6 +68,10 @@ interface
|
|||||||
procedure pass_generate_code;override;
|
procedure pass_generate_code;override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
tcgfinalizetempsnode = class(tfinalizetempsnode)
|
||||||
|
procedure pass_generate_code; override;
|
||||||
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -714,6 +718,17 @@ interface
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{*****************************************************************************
|
||||||
|
TCGFINALIZETEMPSNODE
|
||||||
|
*****************************************************************************}
|
||||||
|
|
||||||
|
procedure tcgfinalizetempsnode.pass_generate_code;
|
||||||
|
begin
|
||||||
|
hlcg.gen_finalize_code(current_asmdata.CurrAsmList);
|
||||||
|
location.loc:=LOC_VOID;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
cnothingnode:=tcgnothingnode;
|
cnothingnode:=tcgnothingnode;
|
||||||
casmnode:=tcgasmnode;
|
casmnode:=tcgasmnode;
|
||||||
@ -722,4 +737,5 @@ begin
|
|||||||
ctempcreatenode:=tcgtempcreatenode;
|
ctempcreatenode:=tcgtempcreatenode;
|
||||||
ctemprefnode:=tcgtemprefnode;
|
ctemprefnode:=tcgtemprefnode;
|
||||||
ctempdeletenode:=tcgtempdeletenode;
|
ctempdeletenode:=tcgtempdeletenode;
|
||||||
|
cfinalizetempsnode:=tcgfinalizetempsnode;
|
||||||
end.
|
end.
|
||||||
|
@ -110,7 +110,8 @@ interface
|
|||||||
loadparentfpn, { Load the framepointer of the parent for nested procedures }
|
loadparentfpn, { Load the framepointer of the parent for nested procedures }
|
||||||
objcselectorn, { node for an Objective-C message selector }
|
objcselectorn, { node for an Objective-C message selector }
|
||||||
objcprotocoln, { node for an Objective-C @protocol() expression (returns metaclass associated with protocol) }
|
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;
|
tnodetypeset = set of tnodetype;
|
||||||
@ -194,7 +195,8 @@ interface
|
|||||||
'loadparentfpn',
|
'loadparentfpn',
|
||||||
'objcselectorn',
|
'objcselectorn',
|
||||||
'objcprotocoln',
|
'objcprotocoln',
|
||||||
'specializen');
|
'specializen',
|
||||||
|
'finalizetempsn');
|
||||||
|
|
||||||
{ a set containing all const nodes }
|
{ a set containing all const nodes }
|
||||||
nodetype_const = [niln,
|
nodetype_const = [niln,
|
||||||
|
@ -963,6 +963,11 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
finalizetempsn:
|
||||||
|
begin
|
||||||
|
result:=NODE_COMPLEXITY_INF;
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
result := NODE_COMPLEXITY_INF;
|
result := NODE_COMPLEXITY_INF;
|
||||||
|
@ -156,7 +156,8 @@ implementation
|
|||||||
'loadparentfpn',
|
'loadparentfpn',
|
||||||
'objselectorn',
|
'objselectorn',
|
||||||
'objcprotocoln',
|
'objcprotocoln',
|
||||||
'specializen'
|
'specializen',
|
||||||
|
'finalizetemps'
|
||||||
);
|
);
|
||||||
var
|
var
|
||||||
p: pchar;
|
p: pchar;
|
||||||
|
@ -47,9 +47,8 @@ interface
|
|||||||
loadpara_asmnode,
|
loadpara_asmnode,
|
||||||
exitlabel_asmnode,
|
exitlabel_asmnode,
|
||||||
stackcheck_asmnode,
|
stackcheck_asmnode,
|
||||||
init_asmnode,
|
init_asmnode : tasmnode;
|
||||||
final_asmnode : tasmnode;
|
temps_finalized : boolean;
|
||||||
final_used : boolean;
|
|
||||||
dfabuilder : TDFABuilder;
|
dfabuilder : TDFABuilder;
|
||||||
|
|
||||||
destructor destroy;override;
|
destructor destroy;override;
|
||||||
@ -678,8 +677,6 @@ implementation
|
|||||||
destructor tcgprocinfo.destroy;
|
destructor tcgprocinfo.destroy;
|
||||||
begin
|
begin
|
||||||
code.free;
|
code.free;
|
||||||
if not final_used then
|
|
||||||
final_asmnode.free;
|
|
||||||
inherited destroy;
|
inherited destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -768,9 +765,9 @@ implementation
|
|||||||
(cs_implicit_exceptions in current_settings.moduleswitches)) then
|
(cs_implicit_exceptions in current_settings.moduleswitches)) then
|
||||||
begin
|
begin
|
||||||
include(tocode.flags,nf_block_with_exit);
|
include(tocode.flags,nf_block_with_exit);
|
||||||
addstatement(newstatement,final_asmnode);
|
addstatement(newstatement,cfinalizetempsnode.create);
|
||||||
cnodeutils.procdef_block_add_implicit_finalize_nodes(procdef,newstatement);
|
cnodeutils.procdef_block_add_implicit_finalize_nodes(procdef,newstatement);
|
||||||
final_used:=true;
|
temps_finalized:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ construction successful -> beforedestruction should be called
|
{ construction successful -> beforedestruction should be called
|
||||||
@ -880,8 +877,7 @@ implementation
|
|||||||
{ Generate code/locations used at end of proc }
|
{ Generate code/locations used at end of proc }
|
||||||
current_filepos:=exitpos;
|
current_filepos:=exitpos;
|
||||||
exitlabel_asmnode:=casmnode.create_get_position;
|
exitlabel_asmnode:=casmnode.create_get_position;
|
||||||
final_asmnode:=casmnode.create_get_position;
|
temps_finalized:=false;
|
||||||
final_used:=false;
|
|
||||||
bodyexitcode:=generate_bodyexit_block;
|
bodyexitcode:=generate_bodyexit_block;
|
||||||
|
|
||||||
{ Generate procedure by combining init+body+final,
|
{ Generate procedure by combining init+body+final,
|
||||||
@ -914,13 +910,13 @@ implementation
|
|||||||
current_filepos:=exitpos;
|
current_filepos:=exitpos;
|
||||||
{ Generate code that will be in the try...finally }
|
{ Generate code that will be in the try...finally }
|
||||||
finalcode:=internalstatements(codestatement);
|
finalcode:=internalstatements(codestatement);
|
||||||
addstatement(codestatement,final_asmnode);
|
addstatement(codestatement,cfinalizetempsnode.create);
|
||||||
cnodeutils.procdef_block_add_implicit_finalize_nodes(procdef,codestatement);
|
cnodeutils.procdef_block_add_implicit_finalize_nodes(procdef,codestatement);
|
||||||
final_used:=true;
|
temps_finalized:=true;
|
||||||
|
|
||||||
current_filepos:=entrypos;
|
current_filepos:=entrypos;
|
||||||
wrappedbody:=ctryfinallynode.create_implicit(code,finalcode);
|
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
|
has to execute after the temps have been finalised in case of a
|
||||||
refcounted class (afterconstruction decreases the refcount
|
refcounted class (afterconstruction decreases the refcount
|
||||||
without freeing the instance if the count becomes nil, while
|
without freeing the instance if the count becomes nil, while
|
||||||
@ -947,12 +943,12 @@ implementation
|
|||||||
addstatement(newstatement,bodyexitcode);
|
addstatement(newstatement,bodyexitcode);
|
||||||
if not is_constructor then
|
if not is_constructor then
|
||||||
begin
|
begin
|
||||||
addstatement(newstatement,final_asmnode);
|
addstatement(newstatement,cfinalizetempsnode.create);
|
||||||
cnodeutils.procdef_block_add_implicit_finalize_nodes(procdef,newstatement);
|
cnodeutils.procdef_block_add_implicit_finalize_nodes(procdef,newstatement);
|
||||||
final_used:=true;
|
temps_finalized:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
if not final_used then
|
if not temps_finalized then
|
||||||
begin
|
begin
|
||||||
current_filepos:=exitpos;
|
current_filepos:=exitpos;
|
||||||
cnodeutils.procdef_block_add_implicit_finalize_nodes(procdef,newstatement);
|
cnodeutils.procdef_block_add_implicit_finalize_nodes(procdef,newstatement);
|
||||||
@ -1569,16 +1565,13 @@ implementation
|
|||||||
|
|
||||||
if assigned(finalize_procinfo) then
|
if assigned(finalize_procinfo) then
|
||||||
generate_exceptfilter(tcgprocinfo(finalize_procinfo))
|
generate_exceptfilter(tcgprocinfo(finalize_procinfo))
|
||||||
else
|
else if not temps_finalized then
|
||||||
begin
|
begin
|
||||||
hlcg.gen_finalize_code(templist);
|
hlcg.gen_finalize_code(templist);
|
||||||
{ the finalcode must be concated if there was no position available,
|
{ the finalcode must be concated if there was no position available,
|
||||||
using insertlistafter will result in an insert at the start
|
using insertlistafter will result in an insert at the start
|
||||||
when currentai=nil }
|
when currentai=nil }
|
||||||
if assigned(final_asmnode) and assigned(final_asmnode.currenttai) then
|
aktproccode.concatlist(templist);
|
||||||
aktproccode.insertlistafter(final_asmnode.currenttai,templist)
|
|
||||||
else
|
|
||||||
aktproccode.concatlist(templist);
|
|
||||||
end;
|
end;
|
||||||
{ insert exit label at the correct position }
|
{ insert exit label at the correct position }
|
||||||
hlcg.a_label(templist,CurrExitLabel);
|
hlcg.a_label(templist,CurrExitLabel);
|
||||||
@ -1753,7 +1746,6 @@ implementation
|
|||||||
delete_marker(exitlabel_asmnode);
|
delete_marker(exitlabel_asmnode);
|
||||||
delete_marker(stackcheck_asmnode);
|
delete_marker(stackcheck_asmnode);
|
||||||
delete_marker(init_asmnode);
|
delete_marker(init_asmnode);
|
||||||
delete_marker(final_asmnode);
|
|
||||||
|
|
||||||
{$ifndef NoOpt}
|
{$ifndef NoOpt}
|
||||||
if not(cs_no_regalloc in current_settings.globalswitches) then
|
if not(cs_no_regalloc in current_settings.globalswitches) then
|
||||||
|
@ -216,8 +216,6 @@ function tx64tryfinallynode.simplify(forinline: boolean): tnode;
|
|||||||
if implicitframe then
|
if implicitframe then
|
||||||
begin
|
begin
|
||||||
current_procinfo.finalize_procinfo:=finalizepi;
|
current_procinfo.finalize_procinfo:=finalizepi;
|
||||||
{ don't leave dangling pointer }
|
|
||||||
tcgprocinfo(current_procinfo).final_asmnode:=nil;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user