mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 23:21:57 +02:00
* generic fpc_shorstr_concat
+ fpc_shortstr_append_shortstr optimization
This commit is contained in:
parent
c48956fd16
commit
0799b0663d
@ -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
|
||||
|
@ -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
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user