Sfoglia il codice sorgente

+ based on a patch by Laksen, optimize (v>=x) and (v<=y) into (v-x)<(y-x)

git-svn-id: trunk@39759 -
florian 6 anni fa
parent
commit
a21397e356
1 ha cambiato i file con 88 aggiunte e 1 eliminazioni
  1. 88 1
      compiler/nadd.pas

+ 88 - 1
compiler/nadd.pas

@@ -376,9 +376,76 @@ implementation
 
 
 
 
     function taddnode.simplify(forinline : boolean) : tnode;
     function taddnode.simplify(forinline : boolean) : tnode;
+
+      function is_range_test(nodel, noder: taddnode; var value: tnode; var cl,cr: qword): boolean;
+        const
+          is_upper_test: array[ltn..gten] of boolean = (true,true,false,false);
+          inclusive_adjust: array[boolean,ltn..gten] of integer = ((1,0,-1,0),
+                                                                   (-1,0,1,0));
+        var
+          swapl, swapr: Boolean;
+          valuer: tnode;
+          t: QWord;
+        begin
+          result:=false;
+          swapl:=false;
+          swapr:=false;
+
+          if nodel.left.nodetype=ordconstn then
+            begin
+              swapl:=true;
+              cl:=tordconstnode(nodel.left).value.uvalue;
+              value:=nodel.right;
+            end
+          else if nodel.right.nodetype=ordconstn then
+            begin
+              cl:=tordconstnode(nodel.right).value.uvalue;
+              value:=nodel.left;
+            end
+          else
+            exit;
+
+          if is_signed(value.resultdef) then
+            exit;
+
+          if noder.left.nodetype=ordconstn then
+            begin
+              swapl:=true;
+              cr:=tordconstnode(noder.left).value.uvalue;
+              valuer:=noder.right;
+            end
+          else if noder.right.nodetype=ordconstn then
+            begin
+              cr:=tordconstnode(noder.right).value.uvalue;
+              valuer:=noder.left;
+            end
+          else
+            exit;
+
+          if not value.isequal(valuer) then
+            exit;
+
+          { this could be simplified too, but probably never happens }
+          if (is_upper_test[nodel.nodetype] xor swapl)=(is_upper_test[noder.nodetype] xor swapr) then
+            exit;
+
+          cl:=cl+inclusive_adjust[swapl,nodel.nodetype];
+          cr:=cr+inclusive_adjust[swapr,noder.nodetype];
+
+          if is_upper_test[nodel.nodetype] xor swapl then
+            begin
+              t:=cl;
+              cl:=cr;
+              cr:=t;
+            end;
+
+          result:=true;
+        end;
+
       var
       var
-        t       : tnode;
+        t       , vl: tnode;
         lt,rt   : tnodetype;
         lt,rt   : tnodetype;
+        hdef,
         rd,ld   : tdef;
         rd,ld   : tdef;
         rv,lv,v : tconstexprint;
         rv,lv,v : tconstexprint;
         rvd,lvd : bestreal;
         rvd,lvd : bestreal;
@@ -390,6 +457,7 @@ implementation
         resultset : Tconstset;
         resultset : Tconstset;
         res,
         res,
         b       : boolean;
         b       : boolean;
+        cr, cl  : qword;
       begin
       begin
         result:=nil;
         result:=nil;
         l1:=0;
         l1:=0;
@@ -984,6 +1052,25 @@ implementation
             }
             }
             if is_boolean(left.resultdef) and is_boolean(right.resultdef) then
             if is_boolean(left.resultdef) and is_boolean(right.resultdef) then
               begin
               begin
+                { transform unsigned comparisons of (v>=x) and (v<=y)
+                  into (v-x)<(y-x)
+                }
+                if (nodetype=andn) and
+                   (left.nodetype in [ltn,lten,gtn,gten]) and
+                   (right.nodetype in [ltn,lten,gtn,gten]) and
+                   (not might_have_sideeffects(left)) and
+                   (not might_have_sideeffects(right)) and
+                   is_range_test(taddnode(left),taddnode(right),vl,cl,cr) then
+                  begin
+                    hdef:=get_unsigned_inttype(vl.resultdef);
+                    vl:=ctypeconvnode.create_internal(vl.getcopy,hdef);
+
+                    result:=caddnode.create_internal(lten,
+                              ctypeconvnode.create_internal(caddnode.create_internal(subn,vl,cordconstnode.create(cl,hdef,false)),hdef),
+                              cordconstnode.create(cr-cl,hdef,false));
+                    exit;
+                  end;
+
                 { even when short circuit boolean evaluation is active, this
                 { even when short circuit boolean evaluation is active, this
                   optimization cannot be performed in case the node has
                   optimization cannot be performed in case the node has
                   side effects, because this can change the result (e.g., in an
                   side effects, because this can change the result (e.g., in an