mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 23:49:22 +02:00
* optimize "dynarr := dynarr + [elem]" to "Insert(elem, dynarr, High(SizeInt))" and "dynarr := [elem] + dynarr" to "Insert(elem, dynarr, 0)" (we need to do this in the typecheck of taddnode as otherwise the array constructor is already converted)
+ added test * adjusted test for Mantis #30463 as p1 triggers the optimization as well git-svn-id: trunk@39119 -
This commit is contained in:
parent
85439a0fa0
commit
199b5809a3
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -12504,6 +12504,7 @@ tests/test/tarray13.pp svneol=native#text/pascal
|
|||||||
tests/test/tarray14.pp svneol=native#text/pascal
|
tests/test/tarray14.pp svneol=native#text/pascal
|
||||||
tests/test/tarray15.pp svneol=native#text/pascal
|
tests/test/tarray15.pp svneol=native#text/pascal
|
||||||
tests/test/tarray16.pp svneol=native#text/pascal
|
tests/test/tarray16.pp svneol=native#text/pascal
|
||||||
|
tests/test/tarray17.pp svneol=native#text/pascal
|
||||||
tests/test/tarray2.pp svneol=native#text/plain
|
tests/test/tarray2.pp svneol=native#text/plain
|
||||||
tests/test/tarray3.pp svneol=native#text/plain
|
tests/test/tarray3.pp svneol=native#text/plain
|
||||||
tests/test/tarray4.pp svneol=native#text/plain
|
tests/test/tarray4.pp svneol=native#text/plain
|
||||||
|
@ -1205,6 +1205,72 @@ implementation
|
|||||||
inserttypeconv(n,adef);
|
inserttypeconv(n,adef);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function maybe_convert_to_insert:tnode;
|
||||||
|
|
||||||
|
function element_count(arrconstr: tarrayconstructornode):asizeint;
|
||||||
|
begin
|
||||||
|
result:=0;
|
||||||
|
while assigned(arrconstr) do
|
||||||
|
begin
|
||||||
|
if arrconstr.nodetype=arrayconstructorrangen then
|
||||||
|
internalerror(2018052501);
|
||||||
|
inc(result);
|
||||||
|
arrconstr:=tarrayconstructornode(tarrayconstructornode(arrconstr).right);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
elem : tnode;
|
||||||
|
para : tcallparanode;
|
||||||
|
isarrconstrl,
|
||||||
|
isarrconstrr : boolean;
|
||||||
|
index : asizeint;
|
||||||
|
begin
|
||||||
|
result:=nil;
|
||||||
|
|
||||||
|
isarrconstrl:=left.nodetype=arrayconstructorn;
|
||||||
|
isarrconstrr:=right.nodetype=arrayconstructorn;
|
||||||
|
|
||||||
|
if not assigned(aktassignmentnode) or
|
||||||
|
(aktassignmentnode.right<>self) or
|
||||||
|
not(
|
||||||
|
isarrconstrl or
|
||||||
|
isarrconstrr
|
||||||
|
) or
|
||||||
|
not(
|
||||||
|
left.isequal(aktassignmentnode.left) or
|
||||||
|
right.isequal(aktassignmentnode.left)
|
||||||
|
) or
|
||||||
|
not valid_for_var(aktassignmentnode.left,false) or
|
||||||
|
(isarrconstrl and (element_count(tarrayconstructornode(left))>1)) or
|
||||||
|
(isarrconstrr and (element_count(tarrayconstructornode(right))>1)) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
if isarrconstrl then
|
||||||
|
begin
|
||||||
|
index:=0;
|
||||||
|
elem:=tarrayconstructornode(left).left;
|
||||||
|
tarrayconstructornode(left).left:=nil;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
index:=high(asizeint);
|
||||||
|
elem:=tarrayconstructornode(right).left;
|
||||||
|
tarrayconstructornode(right).left:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ we use the fact that insert() caps the index to avoid a copy }
|
||||||
|
para:=ccallparanode.create(
|
||||||
|
cordconstnode.create(index,sizesinttype,false),
|
||||||
|
ccallparanode.create(
|
||||||
|
aktassignmentnode.left.getcopy,
|
||||||
|
ccallparanode.create(
|
||||||
|
elem,nil)));
|
||||||
|
|
||||||
|
result:=cinlinenode.create(in_insert_x_y_z,false,para);
|
||||||
|
include(aktassignmentnode.flags,nf_assign_done_in_right);
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
result:=nil;
|
result:=nil;
|
||||||
rlow:=0;
|
rlow:=0;
|
||||||
@ -2124,6 +2190,9 @@ implementation
|
|||||||
{ <dyn. array>+<dyn. array> ? }
|
{ <dyn. array>+<dyn. array> ? }
|
||||||
else if (nodetype=addn) and (is_dynamic_array(ld) or is_dynamic_array(rd)) then
|
else if (nodetype=addn) and (is_dynamic_array(ld) or is_dynamic_array(rd)) then
|
||||||
begin
|
begin
|
||||||
|
result:=maybe_convert_to_insert;
|
||||||
|
if assigned(result) then
|
||||||
|
exit;
|
||||||
if not(is_dynamic_array(ld)) then
|
if not(is_dynamic_array(ld)) then
|
||||||
inserttypeconv(left,rd);
|
inserttypeconv(left,rd);
|
||||||
if not(is_dynamic_array(rd)) then
|
if not(is_dynamic_array(rd)) then
|
||||||
|
36
tests/test/tarray17.pp
Normal file
36
tests/test/tarray17.pp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
program tarray17;
|
||||||
|
|
||||||
|
{$mode objfpc}
|
||||||
|
{$COperators on}
|
||||||
|
|
||||||
|
function CheckArray(aArr, aExpected: array of LongInt): Boolean;
|
||||||
|
var
|
||||||
|
i: LongInt;
|
||||||
|
begin
|
||||||
|
if Length(aArr) <> Length(aExpected) then
|
||||||
|
Exit(False);
|
||||||
|
for i := Low(aArr) to High(aArr) do
|
||||||
|
if aArr[i] <> aExpected[i] then
|
||||||
|
Exit(False);
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
a: array of LongInt;
|
||||||
|
begin
|
||||||
|
a := [1, 2, 3];
|
||||||
|
|
||||||
|
a := a + [4];
|
||||||
|
if not CheckArray(a, [1, 2, 3, 4]) then
|
||||||
|
Halt(1);
|
||||||
|
|
||||||
|
a := [0] + a;
|
||||||
|
if not CheckArray(a, [0, 1, 2, 3, 4]) then
|
||||||
|
Halt(2);
|
||||||
|
|
||||||
|
a += [5];
|
||||||
|
if not CheckArray(a, [0, 1, 2, 3, 4, 5]) then
|
||||||
|
Halt(3);
|
||||||
|
|
||||||
|
Writeln('ok');
|
||||||
|
end.
|
@ -39,7 +39,7 @@ procedure p2;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
// p1;
|
p1;
|
||||||
p2;
|
p2;
|
||||||
writeln('ok');
|
writeln('ok');
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user