Ver código fonte

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

git-svn-id: trunk@39759 -
florian 6 anos atrás
pai
commit
a21397e356
1 arquivos alterados com 88 adições e 1 exclusões
  1. 88 1
      compiler/nadd.pas

+ 88 - 1
compiler/nadd.pas

@@ -376,9 +376,76 @@ implementation
 
 
     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
-        t       : tnode;
+        t       , vl: tnode;
         lt,rt   : tnodetype;
+        hdef,
         rd,ld   : tdef;
         rv,lv,v : tconstexprint;
         rvd,lvd : bestreal;
@@ -390,6 +457,7 @@ implementation
         resultset : Tconstset;
         res,
         b       : boolean;
+        cr, cl  : qword;
       begin
         result:=nil;
         l1:=0;
@@ -984,6 +1052,25 @@ implementation
             }
             if is_boolean(left.resultdef) and is_boolean(right.resultdef) then
               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
                   optimization cannot be performed in case the node has
                   side effects, because this can change the result (e.g., in an