فهرست منبع

+ enabled the load-modify-store optimization for the double argument version
(i.e. shift/rotate by k) of sar, rol and ror with type conversion on i386 and
x86_64.

git-svn-id: trunk@36755 -

nickysn 8 سال پیش
والد
کامیت
9853c4a2a3
1فایلهای تغییر یافته به همراه55 افزوده شده و 0 حذف شده
  1. 55 0
      compiler/optloadmodifystore.pas

+ 55 - 0
compiler/optloadmodifystore.pas

@@ -499,6 +499,61 @@ unit optloadmodifystore;
                 tcallparanode(tcallparanode(tinlinenode(right).left).right).left:=nil;
                 tcallparanode(tcallparanode(tinlinenode(right).left).right).left:=nil;
                 exit;
                 exit;
               end;
               end;
+            { replace i:=sar(i,k) by in_sar_assign_x_y(i,k)
+                      i:=rol(i,k) by in_rol_assign_x_y(i,k)
+                      i:=ror(i,k) by in_ror_assign_x_y(i,k)
+
+              this handles the case with two conversions (outer and inner):
+                   outer typeconv: right
+          sar/rol/ror inline node: ttypeconvnode(right).left
+                   inner typeconv: tcallparanode(tcallparanode(tinlinenode(ttypeconvnode(right).left).left).right).left
+                   right side 'i': ttypeconvnode(tcallparanode(tcallparanode(tinlinenode(ttypeconvnode(right).left).left).right).left).left
+                   right side 'k': tcallparanode(tinlinenode(ttypeconvnode(right).left).left).left }
+            if (right.nodetype=typeconvn) and
+               (ttypeconvnode(right).convtype=tc_int_2_int) and
+               (ttypeconvnode(right).left.nodetype=inlinen) and
+               (tinlinenode(ttypeconvnode(right).left).inlinenumber in [
+{$ifdef enable_sar_assign_x_y}
+                   in_sar_x_y{$ifdef enable_rox_assign_x_y},{$endif}
+{$endif enable_sar_assign_x_y}
+{$ifdef enable_rox_assign_x_y}
+                   in_rol_x_y,in_ror_x_y
+{$endif enable_rox_assign_x_y}
+                 ]) and
+               is_integer(ttypeconvnode(right).left.resultdef) and
+               (right.resultdef.size=ttypeconvnode(right).left.resultdef.size) and
+               (tinlinenode(ttypeconvnode(right).left).left.nodetype=callparan) and
+               (tcallparanode(tcallparanode(tinlinenode(ttypeconvnode(right).left).left).right).left.nodetype=typeconvn) and
+               (ttypeconvnode(tcallparanode(tcallparanode(tinlinenode(ttypeconvnode(right).left).left).right).left).convtype=tc_int_2_int) and
+               are_equal_ints(right.resultdef,ttypeconvnode(tcallparanode(tcallparanode(tinlinenode(ttypeconvnode(right).left).left).right).left).left.resultdef) and
+               ttypeconvnode(tcallparanode(tcallparanode(tinlinenode(ttypeconvnode(right).left).left).right).left).left.isequal(left) and
+               is_integer(ttypeconvnode(tcallparanode(tcallparanode(tinlinenode(ttypeconvnode(right).left).left).right).left).left.resultdef) and
+               ((localswitches*[cs_check_overflow,cs_check_range])=[]) and
+               ((right.localswitches*[cs_check_overflow,cs_check_range])=[]) and
+               valid_for_var(ttypeconvnode(tcallparanode(tcallparanode(tinlinenode(ttypeconvnode(right).left).left).right).left).left,false) and
+               not(might_have_sideeffects(ttypeconvnode(tcallparanode(tcallparanode(tinlinenode(ttypeconvnode(right).left).left).right).left).left)) then
+              begin
+                case tinlinenode(ttypeconvnode(right).left).inlinenumber of
+                  in_sar_x_y:
+                    newinlinenodetype:=in_sar_assign_x_y;
+                  in_rol_x_y:
+                    newinlinenodetype:=in_rol_assign_x_y;
+                  in_ror_x_y:
+                    newinlinenodetype:=in_ror_assign_x_y;
+                  else
+                    internalerror(2017072002);
+                end;
+                result:=cinlinenode.createintern(
+                  newinlinenodetype,false,ccallparanode.create(
+                  tcallparanode(tinlinenode(ttypeconvnode(right).left).left).left,
+                  ccallparanode.create(ttypeconvnode(tcallparanode(tcallparanode(tinlinenode(ttypeconvnode(right).left).left).right).left).left,nil)));
+                result.localswitches:=localswitches;
+                result.fileinfo:=fileinfo;
+                result.verbosity:=verbosity;
+                tcallparanode(tinlinenode(ttypeconvnode(right).left).left).left:=nil;
+                ttypeconvnode(tcallparanode(tcallparanode(tinlinenode(ttypeconvnode(right).left).left).right).left).left:=nil;
+                exit;
+              end;
 {$endif enable_sar_assign_x_y or enable_rox_assign_x_y}
 {$endif enable_sar_assign_x_y or enable_rox_assign_x_y}
             { replace i:=not i  by in_not_assign_x(i)
             { replace i:=not i  by in_not_assign_x(i)
                       i:=-i     by in_neg_assign_x(i)
                       i:=-i     by in_neg_assign_x(i)