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

* at -O3 level, convert i:=i and/or/xor k to the new in_[and/or/xor]_assign_x_y
inline nodes, which should generate better code for certain CPU targets,
including x86. Note that the optimization isn't applied yet for all integer
types (those that have extra implicit typecasts, inserted by the compiler,
aren't handled yet).

git-svn-id: trunk@35685 -

nickysn 8 жил өмнө
parent
commit
f29492bdea
1 өөрчлөгдсөн 54 нэмэгдсэн , 13 устгасан
  1. 54 13
      compiler/nld.pas

+ 54 - 13
compiler/nld.pas

@@ -589,8 +589,13 @@ implementation
               end;
             if cs_opt_level3 in current_settings.optimizerswitches then
               begin
-                { replace i:=i+k/i:=i-k by inc/dec(i,k)? }
-                if (right.nodetype in [addn,subn]) and
+                { replace i:=i+k by inc(i,k)
+                          i:=i-k by dec(i,k)
+                          i:=i and/or/xor k  by in_[and/or/xor]_assign_x_y(i,k)
+                  todo: for some integer types, there are extra implicit
+                        typecasts inserted by the compiler; this code should be
+                        updated to handle them as well }
+                if (right.nodetype in [addn,subn,andn,orn,xorn]) and
                   (taddnode(right).left.isequal(left)) and
                   is_integer(taddnode(right).left.resultdef) and
                   is_integer(taddnode(right).right.resultdef) and
@@ -599,19 +604,38 @@ implementation
                   valid_for_var(taddnode(right).left,false) and
                   not(might_have_sideeffects(taddnode(right).left)) then
                   begin
-                    if right.nodetype=addn then
-                      newinlinenodetype:=in_inc_x
+                    case right.nodetype of
+                      addn:
+                        newinlinenodetype:=in_inc_x;
+                      subn:
+                        newinlinenodetype:=in_dec_x;
+                      andn:
+                        newinlinenodetype:=in_and_assign_x_y;
+                      orn:
+                        newinlinenodetype:=in_or_assign_x_y;
+                      xorn:
+                        newinlinenodetype:=in_xor_assign_x_y;
+                      else
+                        internalerror(2017032901);
+                    end;
+                    if right.nodetype in [addn,subn] then
+                      result:=cinlinenode.createintern(
+                        newinlinenodetype,false,ccallparanode.create(
+                        left,ccallparanode.create(taddnode(right).right,nil)))
                     else
-                      newinlinenodetype:=in_dec_x;
-                    result:=cinlinenode.createintern(
-                      newinlinenodetype,false,ccallparanode.create(
-                      left,ccallparanode.create(taddnode(right).right,nil)));
+                      result:=cinlinenode.createintern(
+                        newinlinenodetype,false,ccallparanode.create(
+                        taddnode(right).right,ccallparanode.create(left,nil)));
                     left:=nil;
                     taddnode(right).right:=nil;
                     exit;
                   end;
-                { replace i:=k+i by inc(i,k)? }
-                if (right.nodetype=addn) and
+                { replace i:=k+i by inc(i,k)
+                          i:=k and/or/xor i  by in_[and/or/xor]_assign_x_y(i,k)
+                  todo: for some integer types, there are extra implicit
+                        typecasts inserted by the compiler; this code should be
+                        updated to handle them as well }
+                if (right.nodetype in [addn,andn,orn,xorn]) and
                   (taddnode(right).right.isequal(left)) and
                   is_integer(taddnode(right).left.resultdef) and
                   is_integer(taddnode(right).right.resultdef) and
@@ -620,9 +644,26 @@ implementation
                   valid_for_var(taddnode(right).right,false) and
                   not(might_have_sideeffects(taddnode(right).right)) then
                   begin
-                    result:=cinlinenode.createintern(
-                      in_inc_x,false,ccallparanode.create(
-                      left,ccallparanode.create(taddnode(right).left,nil)));
+                    case right.nodetype of
+                      addn:
+                        newinlinenodetype:=in_inc_x;
+                      andn:
+                        newinlinenodetype:=in_and_assign_x_y;
+                      orn:
+                        newinlinenodetype:=in_or_assign_x_y;
+                      xorn:
+                        newinlinenodetype:=in_xor_assign_x_y;
+                      else
+                        internalerror(2017032902);
+                    end;
+                    if right.nodetype=addn then
+                      result:=cinlinenode.createintern(
+                        newinlinenodetype,false,ccallparanode.create(
+                        left,ccallparanode.create(taddnode(right).left,nil)))
+                    else
+                      result:=cinlinenode.createintern(
+                        newinlinenodetype,false,ccallparanode.create(
+                        taddnode(right).left,ccallparanode.create(left,nil)));
                     left:=nil;
                     taddnode(right).left:=nil;
                     exit;