2
0
Эх сурвалжийг харах

* Improved shift-to-rotate node optimisation to reduce code size and permit the use of a variable index

J. Gareth "Curious Kit" Moreton 1 долоо хоног өмнө
parent
commit
0af3f2a903
1 өөрчлөгдсөн 66 нэмэгдсэн , 53 устгасан
  1. 66 53
      compiler/nadd.pas

+ 66 - 53
compiler/nadd.pas

@@ -664,6 +664,59 @@ const
         end;
 
 
+      function TryVariableShiftPair(lin, rin: tnode; bitsize: asizeint): boolean;
+        begin
+          Result:=(rin.nodetype=subn) and
+            is_constintnode(taddnode(rin).left) and
+            (tordconstnode(taddnode(rin).left).value=bitsize) and
+            not might_have_sideeffects(lin) and
+            taddnode(rin).right.isequal(lin);
+        end;
+
+
+      function CheckRotateOptimization(standard_op, reverse_op: TInlineNumber): tnode;
+        var
+          bitsize: asizeint;
+        begin
+          Result:=nil;
+          if is_integer(tshlshrnode(left).left.resultdef) and
+            { Avoid using custom integers due to the risk of unusual sizes and
+              undesired effects in, say, bitpacked records. [Kit] }
+            (torddef(tshlshrnode(left).left.resultdef).ordtype<>customint) and
+            not might_have_sideeffects(tshlshrnode(left).left) and
+            tshlshrnode(left).left.isequal(tshlshrnode(right).left) then
+            begin
+              bitsize:=tshlshrnode(left).left.resultdef.size*8;
+
+              { Check for constants first }
+              if (
+                  is_constintnode(tshlshrnode(left).right) and
+                  (tordconstnode(tshlshrnode(left).right).value>0) and
+                  is_constintnode(tshlshrnode(right).right) and
+                  (tordconstnode(tshlshrnode(right).right).value>0) and
+                  (tordconstnode(tshlshrnode(right).right).value=bitsize-tordconstnode(tshlshrnode(left).right).value)
+                ) or
+                  { Try (X op1 Y) or (X op2 (S-Y)) for variable rotation}
+                  TryVariableShiftPair(tshlshrnode(left).right, tshlshrnode(right).right, bitsize) then
+                begin
+                  result:=cinlinenode.create(standard_op,false,
+                    ccallparanode.create(tshlshrnode(left).PruneKeepRight(),
+                    ccallparanode.create(tshlshrnode(left).PruneKeepLeft(),nil)));
+                  Exit;
+                end;
+
+              { Try (X op1 (S-Y)) or (X op2 Y) for variable rotation }
+              if TryVariableShiftPair(tshlshrnode(right).right, tshlshrnode(left).right, bitsize) then
+                begin
+                  result:=cinlinenode.create(reverse_op,false,
+                    ccallparanode.create(tshlshrnode(right).PruneKeepRight(),
+                    ccallparanode.create(tshlshrnode(right).PruneKeepLeft(),nil)));
+                  Exit;
+                end;
+            end;
+        end;
+
+
       var
         hp: taddnode;
         t,vl,lefttarget,righttarget: tnode;
@@ -1849,7 +1902,7 @@ const
               end;
 {$ifdef cpurox}
             { optimize (i shl x) or (i shr (bitsizeof(i)-x)) into rol(x,i) (and different flavours with shl/shr swapped etc.) }
-            if (nodetype=orn)
+            if (nodetype in [addn,orn]) { add also works here }
 {$ifdef m68k}
                and (CPUM68K_HAS_ROLROR in cpu_capabilities[current_settings.cputype])
 {$endif m68k}
@@ -1862,58 +1915,18 @@ const
 {$endif cpu64bitalu}
               then
               begin
-                if (left.nodetype=shrn) and (right.nodetype=shln) and
-                   is_constintnode(tshlshrnode(left).right) and
-                   is_constintnode(tshlshrnode(right).right) and
-                   (tordconstnode(tshlshrnode(right).right).value>0) and
-                   (tordconstnode(tshlshrnode(left).right).value>0) and
-                   tshlshrnode(left).left.isequal(tshlshrnode(right).left) and
-                   not(might_have_sideeffects(tshlshrnode(left).left)) then
-                   begin
-                     if (tordconstnode(tshlshrnode(left).right).value=
-                       tshlshrnode(left).left.resultdef.size*8-tordconstnode(tshlshrnode(right).right).value) then
-                       begin
-                         result:=cinlinenode.create(in_ror_x_y,false,
-                           ccallparanode.create(tshlshrnode(left).PruneKeepRight(),
-                           ccallparanode.create(tshlshrnode(left).PruneKeepLeft(),nil)));
-                         exit;
-                       end
-                     else if (tordconstnode(tshlshrnode(right).right).value=
-                       tshlshrnode(left).left.resultdef.size*8-tordconstnode(tshlshrnode(left).right).value) then
-                       begin
-                         result:=cinlinenode.create(in_rol_x_y,false,
-                           ccallparanode.create(tshlshrnode(right).PruneKeepRight(),
-                           ccallparanode.create(tshlshrnode(left).PruneKeepLeft(),nil)));
-                         exit;
-                       end;
-                   end;
-                if (left.nodetype=shln) and (right.nodetype=shrn) and
-                   is_constintnode(tshlshrnode(left).right) and
-                   is_constintnode(tshlshrnode(right).right) and
-                   (tordconstnode(tshlshrnode(right).right).value>0) and
-                   (tordconstnode(tshlshrnode(left).right).value>0) and
-                   tshlshrnode(left).left.isequal(tshlshrnode(right).left) and
-                   not(might_have_sideeffects(tshlshrnode(left).left)) then
-                   begin
-                     if (tordconstnode(tshlshrnode(left).right).value=
-                       tshlshrnode(left).left.resultdef.size*8-tordconstnode(tshlshrnode(right).right).value)
-                        then
-                       begin
-                         result:=cinlinenode.create(in_rol_x_y,false,
-                           ccallparanode.create(tshlshrnode(left).PruneKeepRight(),
-                           ccallparanode.create(tshlshrnode(left).PruneKeepLeft(),nil)));
-                         exit;
-                       end
-                     else if (tordconstnode(tshlshrnode(right).right).value=
-                       tshlshrnode(left).left.resultdef.size*8-tordconstnode(tshlshrnode(left).right).value)
-                        then
-                       begin
-                         result:=cinlinenode.create(in_ror_x_y,false,
-                           ccallparanode.create(tshlshrnode(right).PruneKeepRight(),
-                           ccallparanode.create(tshlshrnode(left).PruneKeepLeft(),nil)));
-                         exit;
-                       end;
-                   end;
+                if (left.nodetype=shln) and (right.nodetype=shrn) then
+                  begin
+                    result:=CheckRotateOptimization(in_rol_x_y,in_ror_x_y);
+                    if Assigned(result) then
+                      Exit;
+                  end
+                else if (left.nodetype=shrn) and (right.nodetype=shln) then
+                  begin
+                    result:=CheckRotateOptimization(in_ror_x_y,in_rol_x_y);
+                    if Assigned(result) then
+                      Exit;
+                  end
               end;
 {$endif cpurox}
             { optimize