* generic fpc_shorstr_concat

+ fpc_shortstr_append_shortstr optimization
This commit is contained in:
peter 2003-05-26 19:38:28 +00:00
parent c48956fd16
commit 0799b0663d
4 changed files with 62 additions and 72 deletions

View File

@ -331,25 +331,16 @@ interface
{ special cases for shortstrings, handled in pass_2 (JM) }
{ can't handle fpc_shortstr_compare with compilerproc either because it }
{ returns its results in the flags instead of in eax }
if (nodetype = addn) and
is_shortstring(resulttype.def) then
if (nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) and
is_shortstring(left.resulttype.def) and
not(((left.nodetype=stringconstn) and (str_length(left)=0)) or
((right.nodetype=stringconstn) and (str_length(right)=0))) then
begin
expectloc:=LOC_REFERENCE;
expectloc:=LOC_FLAGS;
calcregisters(self,0,0,0);
result := nil;
exit;
end
else
if (nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) and
is_shortstring(left.resulttype.def) and
not(((left.nodetype=stringconstn) and (str_length(left)=0)) or
((right.nodetype=stringconstn) and (str_length(right)=0))) then
begin
expectloc:=LOC_FLAGS;
calcregisters(self,0,0,0);
result := nil;
exit;
end;
end;
{ otherwise, use the generic code }
result := inherited first_addstring;
end;
@ -358,10 +349,8 @@ interface
procedure ti386addnode.second_addstring;
var
href : treference;
cmpop : boolean;
pushed : Tpushedsavedint;
regstopush : Tsupregset;
begin
{ string operations are not commutative }
if nf_swaped in flags then
@ -370,51 +359,6 @@ interface
st_shortstring:
begin
case nodetype of
addn:
begin
cmpop:=false;
secondpass(left);
{ if str_concat is set in expr
s:=s+ ... no need to create a temp string (PM) }
{ the tempstring can also come from a typeconversion }
{ or a function result, so simply check for a }
{ temp of 256 bytes(JM) }
if not(tg.istemp(left.location.reference) and
(tg.SizeOfTemp(exprasmlist,left.location.reference) = 256)) and
not(nf_use_strconcat in flags) then
begin
tg.GetTemp(exprasmlist,256,tt_normal,href);
cg.g_copyshortstring(exprasmlist,left.location.reference,href,255,true,false);
{ location is released by copyshortstring }
location_freetemp(exprasmlist,left.location);
location_reset(left.location,LOC_REFERENCE,def_cgsize(resulttype.def));
left.location.reference:=href;
end;
secondpass(right);
{ on the right we do not need the register anymore too }
{ Instead of releasing them already, simply do not }
{ push them (so the release is in the right place, }
{ because emitpushreferenceaddr doesn't need extra }
{ registers) (JM) }
regstopush := all_intregisters;
remove_non_regvars_from_loc(right.location,regstopush);
rg.saveusedintregisters(exprasmlist,pushed,regstopush);
{ push the maximum possible length of the result }
cg.a_paramaddr_ref(exprasmlist,left.location.reference,paramanager.getintparaloc(2));
{ the optimizer can more easily put the }
{ deallocations in the right place if it happens }
{ too early than when it happens too late (if }
{ the pushref needs a "lea (..),edi; push edi") }
location_release(exprasmlist,right.location);
cg.a_paramaddr_ref(exprasmlist,right.location.reference,paramanager.getintparaloc(1));
rg.saveintregvars(exprasmlist,regstopush);
cg.a_call_name(exprasmlist,'FPC_SHORTSTR_CONCAT');
tg.ungetiftemp(exprasmlist,right.location.reference);
rg.restoreusedintregisters(exprasmlist,pushed);
end;
ltn,lten,gtn,gten,equaln,unequaln :
begin
cmpop := true;
@ -1663,7 +1607,11 @@ begin
end.
{
$Log$
Revision 1.67 2003-05-22 21:32:29 peter
Revision 1.68 2003-05-26 19:38:28 peter
* generic fpc_shorstr_concat
+ fpc_shortstr_append_shortstr optimization
Revision 1.67 2003/05/22 21:32:29 peter
* removed some unit dependencies
Revision 1.66 2003/04/26 09:12:55 peter

View File

@ -1296,11 +1296,6 @@ implementation
case nodetype of
addn:
begin
{ note: if you implemented an fpc_shortstr_concat similar to the }
{ one in i386.inc, you have to override first_addstring like in }
{ ti386addnode.first_string and implement the shortstring concat }
{ manually! The generic routine is different from the i386 one (JM) }
{ create the call to the concat routine both strings as arguments }
result := ccallnode.createintern('fpc_'+
tstringdef(resulttype.def).stringtypname+'_concat',
@ -1958,7 +1953,11 @@ begin
end.
{
$Log$
Revision 1.89 2003-05-24 21:12:57 florian
Revision 1.90 2003-05-26 19:38:28 peter
* generic fpc_shorstr_concat
+ fpc_shortstr_append_shortstr optimization
Revision 1.89 2003/05/24 21:12:57 florian
* if something doesn't work with callparatemp, the define callparatemp
should be used because other processors with reigster calling conventions
depend on this as well
@ -2179,4 +2178,4 @@ end.
with string operations
* adapted some routines to use the new cg methods
}
}

View File

@ -728,6 +728,9 @@ implementation
secondpass(hp.left);
if codegenerror then
exit;
{ Move flags and jump in register }
if hp.left.location.loc in [LOC_FLAGS,LOC_JUMP] then
location_force_reg(exprasmlist,hp.left.location,def_cgsize(hp.left.resulttype.def),false);
if dovariant then
begin
{ find the correct vtype value }
@ -919,7 +922,11 @@ begin
end.
{
$Log$
Revision 1.61 2003-05-24 11:47:27 jonas
Revision 1.62 2003-05-26 19:38:28 peter
* generic fpc_shorstr_concat
+ fpc_shortstr_append_shortstr optimization
Revision 1.61 2003/05/24 11:47:27 jonas
* fixed framepointer storage: it's now always stored at r1+12, which is
a place in the link area reserved for compiler use.

View File

@ -628,6 +628,38 @@ implementation
exit;
end;
end;
end
else
if is_shortstring(left.resulttype.def) then
begin
{ fold <shortstring>:=<shortstring>+<shortstring>,
<shortstring>+<char> is handled by an optimized node }
if (right.nodetype=addn) and
left.isequal(tbinarynode(right).left) and
{ don't fold multiple concatenations else we could get trouble
with multiple uses of s }
(tbinarynode(right).left.nodetype<>addn) and
(tbinarynode(right).right.nodetype<>addn) then
begin
{ don't do a resulttypepass(right), since then the addnode }
{ may insert typeconversions that make this optimization }
{ opportunity quite difficult to detect (JM) }
resulttypepass(tbinarynode(right).left);
resulttypepass(tbinarynode(right).right);
if is_shortstring(tbinarynode(right).right.resulttype.def) then
begin
{ remove property flag so it'll not trigger an error }
exclude(left.flags,nf_isproperty);
{ generate call to helper }
hp:=ccallparanode.create(tbinarynode(right).right,
ccallparanode.create(left,nil));
if is_shortstring(tbinarynode(right).right.resulttype.def) then
result:=ccallnode.createintern('fpc_shortstr_append_shortstr',hp);
tbinarynode(right).right:=nil;
left:=nil;
exit;
end;
end;
end;
resulttypepass(right);
@ -1213,7 +1245,11 @@ begin
end.
{
$Log$
Revision 1.95 2003-05-23 17:05:13 peter
Revision 1.96 2003-05-26 19:38:28 peter
* generic fpc_shorstr_concat
+ fpc_shortstr_append_shortstr optimization
Revision 1.95 2003/05/23 17:05:13 peter
* loadn procsym need to return procdef
Revision 1.94 2003/05/23 14:27:35 peter