mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 20:49:49 +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/tarray15.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/tarray3.pp svneol=native#text/plain
|
||||
tests/test/tarray4.pp svneol=native#text/plain
|
||||
|
@ -1205,6 +1205,72 @@ implementation
|
||||
inserttypeconv(n,adef);
|
||||
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
|
||||
result:=nil;
|
||||
rlow:=0;
|
||||
@ -2124,6 +2190,9 @@ implementation
|
||||
{ <dyn. array>+<dyn. array> ? }
|
||||
else if (nodetype=addn) and (is_dynamic_array(ld) or is_dynamic_array(rd)) then
|
||||
begin
|
||||
result:=maybe_convert_to_insert;
|
||||
if assigned(result) then
|
||||
exit;
|
||||
if not(is_dynamic_array(ld)) then
|
||||
inserttypeconv(left,rd);
|
||||
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;
|
||||
|
||||
begin
|
||||
// p1;
|
||||
p1;
|
||||
p2;
|
||||
writeln('ok');
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user