mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 18:29:09 +02:00
* optimized assignments with on the right side a function that returns
an ansi- or widestring
This commit is contained in:
parent
706de77ef7
commit
10eb92c546
@ -977,6 +977,11 @@ type
|
|||||||
{ everything }
|
{ everything }
|
||||||
if assigned(resulttype.def) then
|
if assigned(resulttype.def) then
|
||||||
begin
|
begin
|
||||||
|
{ these are returned as values, but we can optimize their loading }
|
||||||
|
{ as well }
|
||||||
|
if is_ansistring(resulttype.def) or
|
||||||
|
is_widestring(resulttype.def) then
|
||||||
|
exit;
|
||||||
para := tcallparanode(left);
|
para := tcallparanode(left);
|
||||||
while assigned(para) do
|
while assigned(para) do
|
||||||
begin
|
begin
|
||||||
@ -2627,7 +2632,11 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.167 2003-06-08 18:27:15 jonas
|
Revision 1.168 2003-06-08 20:01:53 jonas
|
||||||
|
* optimized assignments with on the right side a function that returns
|
||||||
|
an ansi- or widestring
|
||||||
|
|
||||||
|
Revision 1.167 2003/06/08 18:27:15 jonas
|
||||||
+ ability to change the location of a ttempref node with changelocation()
|
+ ability to change the location of a ttempref node with changelocation()
|
||||||
method. Useful to use instead of copying the contents from one temp to
|
method. Useful to use instead of copying the contents from one temp to
|
||||||
another
|
another
|
||||||
|
@ -409,6 +409,8 @@ implementation
|
|||||||
var
|
var
|
||||||
cgsize : tcgsize;
|
cgsize : tcgsize;
|
||||||
r,hregister : tregister;
|
r,hregister : tregister;
|
||||||
|
href: treference;
|
||||||
|
tempnode: tnode;
|
||||||
begin
|
begin
|
||||||
{ structured results are easy to handle.... }
|
{ structured results are easy to handle.... }
|
||||||
{ needed also when result_no_used !! }
|
{ needed also when result_no_used !! }
|
||||||
@ -423,13 +425,34 @@ implementation
|
|||||||
if is_ansistring(resulttype.def) or
|
if is_ansistring(resulttype.def) or
|
||||||
is_widestring(resulttype.def) then
|
is_widestring(resulttype.def) then
|
||||||
begin
|
begin
|
||||||
location_reset(location,LOC_CREFERENCE,OS_ADDR);
|
|
||||||
location.reference:=refcountedtemp;
|
|
||||||
r.enum:=R_INTREGISTER;
|
r.enum:=R_INTREGISTER;
|
||||||
r.number:=NR_FUNCTION_RETURN_REG;
|
r.number:=NR_FUNCTION_RETURN_REG;
|
||||||
cg.a_reg_alloc(exprasmlist,r);
|
cg.a_reg_alloc(exprasmlist,r);
|
||||||
cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,r,location.reference);
|
if not assigned(funcretnode) then
|
||||||
cg.a_reg_dealloc(exprasmlist,r);
|
begin
|
||||||
|
location_reset(location,LOC_CREFERENCE,OS_ADDR);
|
||||||
|
location.reference:=refcountedtemp;
|
||||||
|
cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,r,location.reference);
|
||||||
|
cg.a_reg_dealloc(exprasmlist,r);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
tg.gettemp(exprasmlist,pointer_size,tt_normal,href);
|
||||||
|
cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,r,href);
|
||||||
|
cg.a_reg_dealloc(exprasmlist,r);
|
||||||
|
{ in case of a regular funcretnode with ret_in_param, the }
|
||||||
|
{ original funcretnode isn't touched -> make sure it's }
|
||||||
|
{ the same here (not sure if it's necessary) }
|
||||||
|
tempnode := funcretnode.getcopy;
|
||||||
|
tempnode.pass_2;
|
||||||
|
location := tempnode.location;
|
||||||
|
tempnode.free;
|
||||||
|
cg.g_decrrefcount(exprasmlist,resulttype.def,location.reference, false);
|
||||||
|
cg.a_load_ref_ref(exprasmlist,OS_ADDR,OS_ADDR,href,location.reference);
|
||||||
|
{ since we used a normal temp, it won't be finalized or }
|
||||||
|
{ decref'd later -> no need to zero it }
|
||||||
|
tg.ungettemp(exprasmlist,href);
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
{ we have only to handle the result if it is used }
|
{ we have only to handle the result if it is used }
|
||||||
@ -611,18 +634,22 @@ implementation
|
|||||||
iolabel:=nil;
|
iolabel:=nil;
|
||||||
rg.saveunusedstate(unusedstate);
|
rg.saveunusedstate(unusedstate);
|
||||||
|
|
||||||
{ if we allocate the temp. location for ansi- or widestrings }
|
if not assigned(funcretnode) then
|
||||||
{ already here, we avoid later a push/pop }
|
|
||||||
if is_widestring(resulttype.def) then
|
|
||||||
begin
|
begin
|
||||||
tg.gettemp(exprasmlist,pointer_size,tt_widestring,refcountedtemp);
|
{ if we allocate the temp. location for ansi- or widestrings }
|
||||||
cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false);
|
{ already here, we avoid later a push/pop }
|
||||||
end
|
if is_widestring(resulttype.def) then
|
||||||
else if is_ansistring(resulttype.def) then
|
begin
|
||||||
begin
|
tg.gettemp(exprasmlist,pointer_size,tt_widestring,refcountedtemp);
|
||||||
tg.GetTemp(exprasmlist,pointer_size,tt_ansistring,refcountedtemp);
|
cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false);
|
||||||
cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false);
|
end
|
||||||
|
else if is_ansistring(resulttype.def) then
|
||||||
|
begin
|
||||||
|
tg.GetTemp(exprasmlist,pointer_size,tt_ansistring,refcountedtemp);
|
||||||
|
cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
if (procdefinition.proccalloption in [pocall_cdecl,pocall_cppdecl,pocall_stdcall]) then
|
if (procdefinition.proccalloption in [pocall_cdecl,pocall_cppdecl,pocall_stdcall]) then
|
||||||
para_alignment:=4
|
para_alignment:=4
|
||||||
@ -1382,7 +1409,11 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.87 2003-06-08 18:21:47 jonas
|
Revision 1.88 2003-06-08 20:01:53 jonas
|
||||||
|
* optimized assignments with on the right side a function that returns
|
||||||
|
an ansi- or widestring
|
||||||
|
|
||||||
|
Revision 1.87 2003/06/08 18:21:47 jonas
|
||||||
* fixed weird error in the copyleft statement :)
|
* fixed weird error in the copyleft statement :)
|
||||||
|
|
||||||
Revision 1.86 2003/06/07 18:57:04 jonas
|
Revision 1.86 2003/06/07 18:57:04 jonas
|
||||||
|
@ -838,12 +838,12 @@ implementation
|
|||||||
{ result, the current left node is modified and that one may }
|
{ result, the current left node is modified and that one may }
|
||||||
{ still be an argument to the function or even accessed in the }
|
{ still be an argument to the function or even accessed in the }
|
||||||
{ function }
|
{ function }
|
||||||
(left.nodetype = temprefn) and
|
(((left.nodetype = temprefn) and
|
||||||
{ doesn't work correctlyfor refcounted things }
|
paramanager.ret_in_param(right.resulttype.def,
|
||||||
not(not is_class(right.resulttype.def) and
|
tcallnode(right).procdefinition.proccalloption)) or
|
||||||
right.resulttype.def.needs_inittable) and
|
{ there's special support for ansi/widestrings in the callnode }
|
||||||
paramanager.ret_in_param(right.resulttype.def,
|
is_ansistring(right.resulttype.def) or
|
||||||
tcallnode(right).procdefinition.proccalloption) then
|
is_widestring(right.resulttype.def)) then
|
||||||
begin
|
begin
|
||||||
tcallnode(right).funcretnode := left;
|
tcallnode(right).funcretnode := left;
|
||||||
result := right;
|
result := right;
|
||||||
@ -1286,7 +1286,11 @@ begin
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.100 2003-06-08 18:27:15 jonas
|
Revision 1.101 2003-06-08 20:01:53 jonas
|
||||||
|
* optimized assignments with on the right side a function that returns
|
||||||
|
an ansi- or widestring
|
||||||
|
|
||||||
|
Revision 1.100 2003/06/08 18:27:15 jonas
|
||||||
+ ability to change the location of a ttempref node with changelocation()
|
+ ability to change the location of a ttempref node with changelocation()
|
||||||
method. Useful to use instead of copying the contents from one temp to
|
method. Useful to use instead of copying the contents from one temp to
|
||||||
another
|
another
|
||||||
|
Loading…
Reference in New Issue
Block a user