* load all complex loads of parameters that are needed multiple times

to a temp to prevent calling functions twice
This commit is contained in:
peter 2005-04-05 21:07:43 +00:00
parent 50bbe3c205
commit 521b7cfa3b

View File

@ -221,28 +221,35 @@ type
procedure maybe_load_para_in_temp(var p:tnode);
function is_simple_node(hp:tnode):boolean;
begin
is_simple_node:=(hp.nodetype in [typen,loadvmtaddrn,loadn,arrayconstructorn]);
end;
var
hp : tnode;
hp,
loadp,
refp : tnode;
htype : ttype;
ptemp : ttempcreatenode;
usederef : boolean;
newinitstatement,
newdonestatement : tstatementnode;
begin
if not assigned(aktcallnode) then
internalerror(200410121);
{ Load all complex loads into a temp to prevent
double calls to a function. We can't simply check for a hp.nodetype=calln
}
hp:=p;
while assigned(hp) and
(hp.nodetype=typeconvn) do
(hp.nodetype=typeconvn) and
(ttypeconvnode(hp).convtype=tc_equal) do
hp:=tunarynode(hp).left;
if assigned(hp) and
(
{ call result must always be loaded in temp to prevent
double creation }
(hp.nodetype=calln)
{ Also optimize also complex loads }
{$warning Complex loads can also be optimized}
// or not(hp.nodetype in [typen,loadvmtaddrn,loadn])
) then
not is_simple_node(hp) then
begin
if not assigned(aktcallnode.methodpointerinit) then
begin
@ -255,17 +262,35 @@ type
newdonestatement:=laststatement(aktcallnode.methodpointerdone);
end;
{ temp create }
ptemp:=ctempcreatenode.create(p.resulttype,p.resulttype.def.size,tt_persistent,true);
usederef:=(p.resulttype.def.deftype in [arraydef,recorddef]) or
is_shortstring(p.resulttype.def) or
is_object(p.resulttype.def);
if usederef then
htype.setdef(tpointerdef.create(p.resulttype))
else
htype:=p.resulttype;
ptemp:=ctempcreatenode.create(htype,htype.def.size,tt_persistent,true);
if usederef then
begin
loadp:=caddrnode.create_internal(p);
refp:=cderefnode.create(ctemprefnode.create(ptemp));
end
else
begin
loadp:=p;
refp:=ctemprefnode.create(ptemp);
end;
addstatement(newinitstatement,ptemp);
addstatement(newinitstatement,cassignmentnode.create(
ctemprefnode.create(ptemp),
p));
resulttypepass(aktcallnode.methodpointerinit);
loadp));
{ new tree is only a temp reference }
p:=ctemprefnode.create(ptemp);
resulttypepass(p);
p:=refp;
{ temp release }
addstatement(newdonestatement,ctempdeletenode.create(ptemp));
{ call resulttypepass for new nodes }
resulttypepass(p);
resulttypepass(aktcallnode.methodpointerinit);
resulttypepass(aktcallnode.methodpointerdone);
end;
end;
@ -504,6 +529,8 @@ type
{ set some settings needed for arrayconstructor }
if is_array_constructor(left.resulttype.def) then
begin
if left.nodetype<>arrayconstructorn then
internalerror(200504041);
if is_array_of_const(parasym.vartype.def) then
begin
{ force variant array }
@ -2520,7 +2547,11 @@ begin
end.
{
$Log$
Revision 1.282 2005-03-28 15:05:17 peter
Revision 1.283 2005-04-05 21:07:43 peter
* load all complex loads of parameters that are needed multiple times
to a temp to prevent calling functions twice
Revision 1.282 2005/03/28 15:05:17 peter
fix type of temps generated for parameters during inlining
Revision 1.281 2005/03/25 22:20:18 peter