* 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 }
if assigned(resulttype.def) then
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);
while assigned(para) do
begin
@ -2627,7 +2632,11 @@ begin
end.
{
$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()
method. Useful to use instead of copying the contents from one temp to
another

View File

@ -409,6 +409,8 @@ implementation
var
cgsize : tcgsize;
r,hregister : tregister;
href: treference;
tempnode: tnode;
begin
{ structured results are easy to handle.... }
{ needed also when result_no_used !! }
@ -423,13 +425,34 @@ implementation
if is_ansistring(resulttype.def) or
is_widestring(resulttype.def) then
begin
location_reset(location,LOC_CREFERENCE,OS_ADDR);
location.reference:=refcountedtemp;
r.enum:=R_INTREGISTER;
r.number:=NR_FUNCTION_RETURN_REG;
cg.a_reg_alloc(exprasmlist,r);
cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,r,location.reference);
cg.a_reg_dealloc(exprasmlist,r);
if not assigned(funcretnode) then
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
else
{ we have only to handle the result if it is used }
@ -611,18 +634,22 @@ implementation
iolabel:=nil;
rg.saveunusedstate(unusedstate);
{ if we allocate the temp. location for ansi- or widestrings }
{ already here, we avoid later a push/pop }
if is_widestring(resulttype.def) then
if not assigned(funcretnode) then
begin
tg.gettemp(exprasmlist,pointer_size,tt_widestring,refcountedtemp);
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);
{ if we allocate the temp. location for ansi- or widestrings }
{ already here, we avoid later a push/pop }
if is_widestring(resulttype.def) then
begin
tg.gettemp(exprasmlist,pointer_size,tt_widestring,refcountedtemp);
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;
if (procdefinition.proccalloption in [pocall_cdecl,pocall_cppdecl,pocall_stdcall]) then
para_alignment:=4
@ -1382,7 +1409,11 @@ begin
end.
{
$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 :)
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 }
{ still be an argument to the function or even accessed in the }
{ function }
(left.nodetype = temprefn) and
{ doesn't work correctlyfor refcounted things }
not(not is_class(right.resulttype.def) and
right.resulttype.def.needs_inittable) and
paramanager.ret_in_param(right.resulttype.def,
tcallnode(right).procdefinition.proccalloption) then
(((left.nodetype = temprefn) and
paramanager.ret_in_param(right.resulttype.def,
tcallnode(right).procdefinition.proccalloption)) or
{ there's special support for ansi/widestrings in the callnode }
is_ansistring(right.resulttype.def) or
is_widestring(right.resulttype.def)) then
begin
tcallnode(right).funcretnode := left;
result := right;
@ -1286,7 +1286,11 @@ begin
end.
{
$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()
method. Useful to use instead of copying the contents from one temp to
another