瀏覽代碼

* 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 年之前
父節點
當前提交
0d96963459
共有 1 個文件被更改,包括 20 次插入0 次删除
  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