mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-14 14:59:32 +02:00
* nf_is_funcret node flag added
* remove ti_is_funcret, use new node flag instead * check for funcret node in doreplace instead of funcretsym git-svn-id: trunk@8578 -
This commit is contained in:
parent
eb7aedc285
commit
4525df9ea0
@ -94,12 +94,11 @@ interface
|
||||
|
||||
ttempcreatenode = class;
|
||||
|
||||
ttempinfoflag = (ti_may_be_in_reg,ti_valid,ti_nextref_set_hookoncopy_nil,ti_is_funcret,
|
||||
ti_addr_taken);
|
||||
ttempinfoflag = (ti_may_be_in_reg,ti_valid,ti_nextref_set_hookoncopy_nil,ti_addr_taken);
|
||||
ttempinfoflags = set of ttempinfoflag;
|
||||
|
||||
const
|
||||
tempinfostoreflags = [ti_may_be_in_reg,ti_is_funcret,ti_addr_taken];
|
||||
tempinfostoreflags = [ti_may_be_in_reg,ti_addr_taken];
|
||||
|
||||
type
|
||||
{ to allow access to the location by temp references even after the temp has }
|
||||
@ -133,7 +132,6 @@ type
|
||||
{ to it and *not* generate a ttempdeletenode }
|
||||
constructor create(_typedef: tdef; _size: aint; _temptype: ttemptype;allowreg:boolean); virtual;
|
||||
constructor create_withnode(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean; withnode: tnode); virtual;
|
||||
constructor create_funcret(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean); virtual;
|
||||
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
|
||||
procedure ppuwrite(ppufile:tcompilerppufile);override;
|
||||
procedure buildderefimpl;override;
|
||||
@ -742,13 +740,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
constructor ttempcreatenode.create_funcret(_typedef: tdef; _size: aint; _temptype: ttemptype; allowreg:boolean);
|
||||
begin
|
||||
self.create(_typedef,_size,_temptype,allowreg);
|
||||
include(tempinfo^.flags,ti_is_funcret);
|
||||
end;
|
||||
|
||||
|
||||
function ttempcreatenode.dogetcopy: tnode;
|
||||
var
|
||||
n: ttempcreatenode;
|
||||
|
@ -1696,11 +1696,14 @@ implementation
|
||||
) then
|
||||
begin
|
||||
funcretnode:=aktassignmentnode.left.getcopy;
|
||||
include(funcretnode.flags,nf_is_funcret);
|
||||
{ notify the assignment node that the assignment can be removed }
|
||||
include(aktassignmentnode.flags,nf_assign_done_in_right);
|
||||
end
|
||||
else
|
||||
begin
|
||||
temp:=ctempcreatenode.create_funcret(resultdef,resultdef.size,tt_persistent,false);
|
||||
temp:=ctempcreatenode.create(resultdef,resultdef.size,tt_persistent,false);
|
||||
include(temp.flags,nf_is_funcret);
|
||||
add_init_statement(temp);
|
||||
{ When the function result is not used in an inlined function
|
||||
we need to delete the temp. This can currently only be done by
|
||||
@ -1711,6 +1714,7 @@ implementation
|
||||
else
|
||||
add_done_statement(ctempdeletenode.create_normal_temp(temp));
|
||||
funcretnode:=ctemprefnode.create(temp);
|
||||
include(funcretnode.flags,nf_is_funcret);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -3056,7 +3060,6 @@ implementation
|
||||
hp : tstatementnode;
|
||||
hp2 : tnode;
|
||||
resassign : tassignmentnode;
|
||||
funcrettemp : ttempcreatenode;
|
||||
begin
|
||||
result:=nil;
|
||||
if not assigned(funcretnode) or
|
||||
@ -3067,9 +3070,8 @@ implementation
|
||||
hp:=tstatementnode(inlineblock.left);
|
||||
if not(assigned(hp)) or
|
||||
(hp.left.nodetype <> tempcreaten) or
|
||||
not(ti_is_funcret in ttempcreatenode(hp.left).tempinfo^.flags) then
|
||||
not(nf_is_funcret in hp.left.flags) then
|
||||
exit;
|
||||
funcrettemp:=ttempcreatenode(hp.left);
|
||||
|
||||
{ constant assignment? right must be a constant (mainly to avoid trying
|
||||
to reuse local temps which may already be freed afterwards once these
|
||||
@ -3088,7 +3090,7 @@ implementation
|
||||
if (hp2.nodetype=typeconvn) and (ttypeconvnode(hp2).convtype=tc_equal) then
|
||||
hp2:=ttypeconvnode(hp2).left;
|
||||
if (hp2.nodetype<>temprefn) or
|
||||
(ttemprefnode(hp2).tempinfo^.owner<>funcrettemp) then
|
||||
not(nf_is_funcret in hp2.flags) then
|
||||
exit;
|
||||
|
||||
{ tempdelete to normal of the function result }
|
||||
@ -3101,7 +3103,7 @@ implementation
|
||||
hp:=tstatementnode(hp.right);
|
||||
if not(assigned(hp)) or
|
||||
(hp.left.nodetype<>temprefn) or
|
||||
(ttemprefnode(hp.left).tempinfo^.owner<>funcrettemp) then
|
||||
not(nf_is_funcret in hp.left.flags) then
|
||||
exit;
|
||||
|
||||
{ should be the end }
|
||||
|
@ -2488,14 +2488,14 @@ implementation
|
||||
rr: preplaceregrec absolute para;
|
||||
begin
|
||||
result := fen_false;
|
||||
if (nf_is_funcret in n.flags) and (fc_exit in flowcontrol) then
|
||||
exit;
|
||||
case n.nodetype of
|
||||
loadn:
|
||||
begin
|
||||
if (tabstractvarsym(tloadnode(n).symtableentry).varoptions * [vo_is_dll_var, vo_is_thread_var] = []) and
|
||||
not assigned(tloadnode(n).left) and
|
||||
(((tloadnode(n).symtableentry <> rr^.ressym) and
|
||||
not(vo_is_funcret in tabstractvarsym(tloadnode(n).symtableentry).varoptions)) or
|
||||
not(fc_exit in flowcontrol)) and
|
||||
(tloadnode(n).symtableentry <> rr^.ressym) and
|
||||
(tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.loc in [LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMXREGISTER,LOC_CMMREGISTER]) and
|
||||
(tabstractnormalvarsym(tloadnode(n).symtableentry).localloc.register = rr^.old) then
|
||||
begin
|
||||
@ -2516,9 +2516,7 @@ implementation
|
||||
begin
|
||||
if (ti_valid in ttemprefnode(n).tempinfo^.flags) and
|
||||
(ttemprefnode(n).tempinfo^.location.loc in [LOC_CREGISTER,LOC_CFPUREGISTER,LOC_CMMXREGISTER,LOC_CMMREGISTER]) and
|
||||
(ttemprefnode(n).tempinfo^.location.register = rr^.old) and
|
||||
(not(ti_is_funcret in ttemprefnode(n).tempinfo^.flags) or
|
||||
not(fc_exit in flowcontrol)) then
|
||||
(ttemprefnode(n).tempinfo^.location.register = rr^.old) then
|
||||
begin
|
||||
{$ifndef cpu64bit}
|
||||
{ it's possible a 64 bit location was shifted and/xor typecasted }
|
||||
|
@ -202,6 +202,7 @@ interface
|
||||
{ general }
|
||||
nf_pass1_done,
|
||||
nf_write, { Node is written to }
|
||||
nf_is_funcret,
|
||||
nf_isproperty,
|
||||
nf_processing,
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user