* optimized assignments with on the right side a function that returns

an ansi- or widestring
This commit is contained in:
Jonas Maebe 2003-06-08 20:01:53 +00:00
parent 706de77ef7
commit 10eb92c546
3 changed files with 67 additions and 23 deletions

View File

@ -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

View File

@ -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

View File

@ -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