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

* generate better code for length(<dyn. type>)=0, resolves #36060

git-svn-id: trunk@43272 -
florian 5 жил өмнө
parent
commit
e80eee5da5
2 өөрчлөгдсөн 75 нэмэгдсэн , 3 устгасан
  1. 33 1
      compiler/nadd.pas
  2. 42 2
      compiler/nutils.pas

+ 33 - 1
compiler/nadd.pas

@@ -22,6 +22,7 @@
 unit nadd;
 
 {$i fpcdefs.inc}
+{$modeswitch nestedprocvars}
 
 { define addstringopt}
 
@@ -446,6 +447,35 @@ implementation
           result:=true;
         end;
 
+      function IsLengthZero(n1,n2 : tnode) : Boolean;
+        begin
+          result:=is_inlinefunction(n1,in_length_x) and is_constintvalue(n2,0) and not(is_shortstring(tinlinenode(n1).left.resultdef));
+        end;
+
+
+      function TransformLengthZero(n1,n2 : tnode) : tnode;
+        var
+          len : Tconstexprint;
+        begin
+          if is_dynamic_array(tinlinenode(n1).left.resultdef) then
+            len:=-1
+          else
+            len:=0;
+          result:=caddnode.create_internal(orn,
+            caddnode.create_internal(equaln,ctypeconvnode.create_internal(tinlinenode(n1).left.getcopy,voidpointertype),
+                cpointerconstnode.create(0,voidpointertype)),
+              caddnode.create_internal(equaln,
+                ctypeconvnode.create_internal(
+                  cderefnode.create(
+                    caddnode.create_internal(subn,ctypeconvnode.create_internal(tinlinenode(n1).left.getcopy,voidpointertype),
+                      cordconstnode.create(0,sizesinttype,false))
+                  ),sizesinttype
+                ),
+              cordconstnode.create(len,sizesinttype,false))
+            );
+        end;
+
+
       var
         t       , vl: tnode;
         lt,rt   : tnodetype;
@@ -1172,7 +1202,9 @@ implementation
                       else
                         ;
                     end;
-                  end;
+                  end
+                else if (nodetype=equaln) and MatchAndTransformNodesCommutative(left,right,@IsLengthZero,@TransformLengthZero,Result) then
+                   exit;
               end;
 
             { using sqr(x) for reals instead of x*x might reduces register pressure and/or

+ 42 - 2
compiler/nutils.pas

@@ -22,13 +22,14 @@
 unit nutils;
 
 {$i fpcdefs.inc}
+{$modeswitch nestedprocvars}
 
 interface
 
   uses
     globtype,constexp,
     symtype,symsym,symbase,symtable,
-    node;
+    node,compinnr;
 
   const
     NODE_COMPLEXITY_INF = 255;
@@ -168,10 +169,24 @@ interface
       if it is not an orn/andn with boolean operans, the result is undefined }
     function doshortbooleval(p : tnode) : Boolean;
 
+    { returns true if the node has the int value l }
+    function is_constintvalue(p : tnode;l : Tconstexprint) : Boolean;
+
+    { returns true if the node is an inline node of type i }
+    function is_inlinefunction(p : tnode;i : tinlinenumber) : Boolean;
+
+    type
+      TMatchProc2 = function(n1,n2 : tnode) : Boolean is nested;
+      TTransformProc2 = function(n1,n2 : tnode) : tnode is nested;
+
+    { calls matchproc with n1 and n2 as parameters, if it returns true, transformproc is called, does the same with the nodes swapped,
+      the result of transformproc is assigned to res }
+    function MatchAndTransformNodesCommutative(n1,n2 : tnode;matchproc : TMatchProc2;transformproc : TTransformProc2;var res : tnode) : Boolean;
+
 implementation
 
     uses
-      cutils,verbose,globals,compinnr,
+      cutils,verbose,globals,
       symconst,symdef,
       defcmp,defutil,
       nbas,ncon,ncnv,nld,nflw,nset,ncal,nadd,nmem,ninl,
@@ -1530,4 +1545,29 @@ implementation
         Result:=(p.nodetype in [orn,andn]) and ((nf_short_bool in taddnode(p).flags) or not(cs_full_boolean_eval in p.localswitches));
       end;
 
+
+    function is_constintvalue(p: tnode; l: Tconstexprint): Boolean;
+      begin
+        Result:=is_constintnode(p) and (tordconstnode(p).value=l);
+      end;
+
+
+    function is_inlinefunction(p: tnode; i: tinlinenumber): Boolean;
+      begin
+        Result:=(p.nodetype=inlinen) and (tinlinenode(p).inlinenumber=i);
+      end;
+
+
+    function MatchAndTransformNodesCommutative(n1,n2 : tnode;matchproc : TMatchProc2;transformproc : TTransformProc2;var res : tnode) : Boolean;
+      begin
+        res:=nil;
+        result:=true;
+        if matchproc(n1,n2) then
+          res:=transformproc(n1,n2)
+        else if matchproc(n2,n1) then
+          res:=transformproc(n2,n1)
+        else
+          result:=false;
+      end;
+
 end.