Browse Source

* Do not promote integer comparison operations to native size if one side is a constant and its value is within range of opposite side. Instead, cast the constant to type of the opposite side.
Comparisons are already not promoted if sides are equally signed, but this wasn't true for "unsigned vs constant" case, because constants are preferably parsed as signed.
The change considerably improves generated code for i386 and even more considerably for m68k. Tested on i386-win32.

git-svn-id: trunk@28266 -

sergei 11 năm trước cách đây
mục cha
commit
0d96963459
1 tập tin đã thay đổi với 20 bổ sung0 xóa
  1. 20 0
      compiler/nadd.pas

+ 20 - 0
compiler/nadd.pas

@@ -1013,6 +1013,14 @@ implementation
         change      : boolean;
 {$endif}
 
+        function maybe_cast_ordconst(var n: tnode; adef: tdef): boolean;
+          begin
+            result:=(tordconstnode(n).value>=torddef(adef).low) and
+              (tordconstnode(n).value<=torddef(adef).high);
+            if result then
+              inserttypeconv(n,adef);
+          end;
+
       begin
          result:=nil;
          rlow:=0;
@@ -1420,6 +1428,18 @@ implementation
                      inserttypeconv(right,nd);
                    end;
                end
+             { don't extend (sign-mismatched) comparisons if either side is a constant
+               whose value is within range of opposite side }
+             else if is_integer(ld) and is_integer(rd) and
+                     (nodetype in [equaln,unequaln,gtn,gten,ltn,lten]) and
+                     (is_signed(ld)<>is_signed(rd)) and
+                     (
+                       ((lt=ordconstn) and maybe_cast_ordconst(left,rd)) or
+                       ((rt=ordconstn) and maybe_cast_ordconst(right,ld))
+                     ) then
+               begin
+                 { done here }
+               end
              { is there a signed 64 bit type ? }
              else if ((torddef(rd).ordtype=s64bit) or (torddef(ld).ordtype=s64bit)) then
                begin