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

Merged revisions 2621 via svnmerge from
svn+ssh://[email protected]/FPC/svn/fpc/trunk

........
r2621 | jonas | 2006-02-18 21:59:44 +0100 (Sat, 18 Feb 2006) | 2 lines

* optimize some more range checks away again, fixes 64bit cpu issues

........

git-svn-id: branches/fixes_2_0@2622 -

Jonas Maebe 19 жил өмнө
parent
commit
cbfd98e330
1 өөрчлөгдсөн 45 нэмэгдсэн , 2 устгасан
  1. 45 2
      compiler/cgobj.pas

+ 45 - 2
compiler/cgobj.pas

@@ -1642,7 +1642,8 @@ implementation
         hreg : tregister;
         lto,hto,
         lfrom,hfrom : TConstExprInt;
-        from_signed: boolean;
+        fromsize, tosize: cardinal;
+        from_signed, to_signed: boolean;
       begin
         { range checking on and range checkable value? }
         if not(cs_check_range in aktlocalswitches) or
@@ -1661,6 +1662,7 @@ implementation
         getrange(fromdef,lfrom,hfrom);
         getrange(todef,lto,hto);
         from_signed := is_signed(fromdef);
+        to_signed := is_signed(todef);
         { no range check if from and to are equal and are both longint/dword }
         { (if we have a 32bit processor) or int64/qword, since such          }
         { operations can at most cause overflows (JM)                        }
@@ -1688,6 +1690,47 @@ implementation
           exit;
 {$endif cpu64bit}
 
+        { optimize some range checks away in safe cases }
+        fromsize := fromdef.size;
+        tosize := todef.size;
+        if ((from_signed = to_signed) or
+            (not from_signed)) and
+           (lto<=lfrom) and (hto>=hfrom) and
+           (fromsize <= tosize) then
+          begin
+            { if fromsize < tosize, and both have the same signed-ness or }
+            { fromdef is unsigned, then all bit patterns from fromdef are }
+            { valid for todef as well                                     }
+            if (fromsize < tosize) then
+              exit;
+            if (fromsize = tosize) and
+               (from_signed = to_signed) then
+              { only optimize away if all bit patterns which fit in fromsize }
+              { are valid for the todef                                      }
+              begin
+{$ifopt Q+}
+{$defined overflowon}
+{$Q-}
+{$endif}
+                if to_signed then
+                  begin
+                    if (lto = (-(int64(1) << (tosize * 4)))) and
+                       (hto = (int64(1) << (tosize * 4) - 1)) then
+                      exit
+                  end
+                else
+                  begin
+                    if (lto = 0) and
+                       (qword(hto) = qword((int64(1) << (tosize * 8)) - 1)) then
+                      exit
+                  end;
+{$ifdef overflowon}
+{$Q+}
+{$undef overflowon}
+{$endif}
+              end
+          end;
+
         { generate the rangecheck code for the def where we are going to }
         { store the result                                               }
 
@@ -1699,7 +1742,7 @@ implementation
         { the parts < 0 and > maxlongint out                                 }
 
         { is_signed now also works for arrays (it checks the rangetype) (JM) }
-        if from_signed xor is_signed(todef) then
+        if from_signed xor to_signed then
           begin
              if from_signed then
                { from is signed, to is unsigned }