* properly fold string+string const+string const., resolves #38267

git-svn-id: trunk@47977 -
This commit is contained in:
florian 2021-01-02 17:18:54 +00:00
parent 8b08079224
commit 7de94e7a1d
3 changed files with 113 additions and 3 deletions

1
.gitattributes vendored
View File

@ -18621,6 +18621,7 @@ tests/webtbs/tw38238.pp svneol=native#text/pascal
tests/webtbs/tw38249.pp svneol=native#text/pascal
tests/webtbs/tw38259.pp svneol=native#text/pascal
tests/webtbs/tw38267a.pp svneol=native#text/pascal
tests/webtbs/tw38267b.pp svneol=native#text/pascal
tests/webtbs/tw3827.pp svneol=native#text/plain
tests/webtbs/tw3829.pp svneol=native#text/plain
tests/webtbs/tw3833.pp svneol=native#text/plain

View File

@ -512,9 +512,10 @@ implementation
var
hp,hp2 : tnode;
begin
{ keep the order of val+const else pointer operations might cause an error }
{ keep the order of val+const else pointer and string operations might cause an error }
hp:=taddnode(left).left;
taddnode(left).left:=right;
taddnode(left).left:=taddnode(left).right;
taddnode(left).right:=right;
left.resultdef:=nil;
do_typecheckpass(left);
hp2:=left.simplify(forinline);
@ -1206,7 +1207,23 @@ implementation
exit;
end;
{ set constant evaluation }
{ try to fold
op
/ \
op const1
/ \
val const2
while operating on strings
}
if (cs_opt_level2 in current_settings.optimizerswitches) and (nodetype=addn) and ((rt=stringconstn) or is_constcharnode(right)) and (left.nodetype=nodetype) and
(compare_defs(resultdef,left.resultdef,nothingn)=te_exact) and ((taddnode(left).right.nodetype=stringconstn) or is_constcharnode(taddnode(left).right)) then
begin
Result:=SwapRightWithLeftLeft;
exit;
end;
{ set constant evaluation }
if (right.nodetype=setconstn) and
not assigned(tsetconstnode(right).left) and
(left.nodetype=setconstn) and

92
tests/webtbs/tw38267b.pp Normal file
View File

@ -0,0 +1,92 @@
{ %opt=-O3 -Sg }
{$mode objfpc} {$longstrings+}
label start1, end1, start2, end2, start3, end3;
var
s: string;
begin
writeln('31 concatenated string literals, completely folded:');
start1:
s :=
'Once like a Great House' + LineEnding +
'founded on sand,' + LineEnding +
'Stood our Temple' + LineEnding +
'whose pillars on troubles were based.' + LineEnding +
'Now mischievous spirits, bound,' + LineEnding +
'in dim corners stand,' + LineEnding +
'Rotted columns, but' + LineEnding +
'with iron-bound bands embraced' + LineEnding +
'Cracked, crumbling marble,' + LineEnding +
'tempered on every hand,' + LineEnding +
'By strong steel' + LineEnding +
'forged in fire and faith.' + LineEnding +
'Shackled, these wayward servants' + LineEnding +
'serve the land,' + LineEnding +
'The Temple secured' + LineEnding +
'by the Builders grace.';
end1:
writeln(Copy(s, 1, 0), PtrUint(CodePointer(@end1) - CodePointer(@start1)), ' b of code');
{ more than 100 bytes of code might point out that the constants are not folded }
if PtrUint(CodePointer(@end1) - CodePointer(@start1))>100 then
halt(1);
writeln;
writeln('1 dynamic string concatenated with 31 literals, they could fold but didn''t at all:');
start2:
s := Copy('', 1, 0) +
'Once like a Great House' + LineEnding +
'founded on sand,' + LineEnding +
'Stood our Temple' + LineEnding +
'whose pillars on troubles were based.' + LineEnding +
'Now mischievous spirits, bound,' + LineEnding +
'in dim corners stand,' + LineEnding +
'Rotted columns, but' + LineEnding +
'with iron-bound bands embraced' + LineEnding +
'Cracked, crumbling marble,' + LineEnding +
'tempered on every hand,' + LineEnding +
'By strong steel' + LineEnding +
'forged in fire and faith.' + LineEnding +
'Shackled, these wayward servants' + LineEnding +
'serve the land,' + LineEnding +
'The Temple secured' + LineEnding +
'by the Builders grace.';
end2:
writeln(Copy(s, 1, 0), PtrUint(CodePointer(@end2) - CodePointer(@start2)), ' b of code');
{ more than 100 bytes of code might point out that the constants are not folded,
example x86_64-linux: not folded: 639 bytes; folded: 76 bytes
}
if PtrUint(CodePointer(@end2) - CodePointer(@start2))>100 then
halt(2);
writeln;
writeln('16 literals concatenated with 1 dynamic string and 15 more literals, first 16 folded but last 15 did not:');
start3:
s :=
'Once like a Great House' + LineEnding +
'founded on sand,' + LineEnding +
'Stood our Temple' + LineEnding +
'whose pillars on troubles were based.' + LineEnding +
'Now mischievous spirits, bound,' + LineEnding +
'in dim corners stand,' + LineEnding +
'Rotted columns, but' + LineEnding +
'with iron-bound bands embraced' + LineEnding +
Copy('', 1, 0) +
'Cracked, crumbling marble,' + LineEnding +
'tempered on every hand,' + LineEnding +
'By strong steel' + LineEnding +
'forged in fire and faith.' + LineEnding +
'Shackled, these wayward servants' + LineEnding +
'serve the land,' + LineEnding +
'The Temple secured' + LineEnding +
'by the Builders grace.';
end3:
writeln(Copy(s, 1, 0), PtrUint(CodePointer(@end3) - CodePointer(@start3)), ' b of code');
{ more than 300 bytes of code might point out that the constants are not folded,
example x86_64-linux: not folded: 369 bytes; folded: 120 bytes
}
if PtrUint(CodePointer(@end3) - CodePointer(@start3))>300 then
halt(3);
writeln;
writeln('ok');
end.