+ calculate loop unrolling using node_count_weighted which takes care of nodes generating no code

* optimized unrolling calculation

git-svn-id: trunk@38688 -
This commit is contained in:
florian 2018-04-04 21:39:46 +00:00
parent 512328deee
commit c59bd8c29a
2 changed files with 24 additions and 2 deletions

View File

@ -123,6 +123,8 @@ interface
rough estimation how large the tree "node" is }
function node_count(node : tnode) : dword;
function node_count_weighted(node : tnode) : dword;
{ returns true, if the value described by node is constant/immutable, this approximation is safe
if no dirty tricks like buffer overflows or pointer magic are used }
function is_const(node : tnode) : boolean;
@ -1359,6 +1361,22 @@ implementation
end;
function donodecount_weighted(var n: tnode; arg: pointer): foreachnoderesult;
begin
if not(n.nodetype in [blockn,statementn,callparan,nothingn]) then
inc(nodecount);
result:=fen_false;
end;
function node_count_weighted(node : tnode) : dword;
begin
nodecount:=0;
foreachnodestatic(node,@donodecount_weighted,nil);
result:=nodecount;
end;
function is_const(node : tnode) : boolean;
begin
result:=is_constnode(node) or

View File

@ -51,13 +51,17 @@ unit optloop;
function number_unrolls(node : tnode) : cardinal;
begin
{ calculate how often a loop shall be unrolled.
The term (60*ord(node_count_weighted(node)<15)) is used to get small loops unrolled more often as
the counter management takes more time in this case. }
{$ifdef i386}
{ multiply by 2 for CPUs with a long pipeline }
if current_settings.optimizecputype in [cpu_Pentium4] then
number_unrolls:=60 div node_count(node)
number_unrolls:=trunc(round((60+(60*ord(node_count_weighted(node)<15)))/max(node_count_weighted(node),1)))
else
{$endif i386}
number_unrolls:=30 div node_count(node);
number_unrolls:=trunc(round((30+(60*ord(node_count_weighted(node)<15)))/max(node_count_weighted(node),1)));
if number_unrolls=0 then
number_unrolls:=1;