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