Explorar o código

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

git-svn-id: trunk@38688 -

florian %!s(int64=7) %!d(string=hai) anos
pai
achega
c59bd8c29a
Modificáronse 2 ficheiros con 24 adicións e 2 borrados
  1. 18 0
      compiler/nutils.pas
  2. 6 2
      compiler/optloop.pas

+ 18 - 0
compiler/nutils.pas

@@ -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

+ 6 - 2
compiler/optloop.pas

@@ -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;