Browse Source

* remove tempref mess for simple inlined functions

git-svn-id: trunk@45217 -
florian 5 years ago
parent
commit
e3870079b2
2 changed files with 60 additions and 7 deletions
  1. 35 5
      compiler/nbas.pas
  2. 25 2
      compiler/nutils.pas

+ 35 - 5
compiler/nbas.pas

@@ -341,7 +341,7 @@ implementation
       ppu,
       symconst,symdef,defutil,defcmp,
       pass_1,
-      nutils,nld,
+      nutils,nld,ncnv,
       procinfo
 {$ifdef DEBUG_NODE_XML}
 {$ifndef jvm}
@@ -696,13 +696,24 @@ implementation
       end;
 
 
+    function NodesEqual(var n: tnode; arg: pointer): foreachnoderesult;
+      begin
+        if n.IsEqual(tnode(arg)) then
+          result:=fen_norecurse_true
+        else
+          result:=fen_false;
+      end;
+
+
     function tblocknode.simplify(forinline : boolean): tnode;
+      var
+        a : array[0..3] of tstatementnode;
       begin
         result := nil;
-        { Warning: never replace a blocknode with another node type,      }
-        {  since the block may be the main block of a procedure/function/ }
-        {  main program body, and those nodes should always be blocknodes }
-        {  since that's what the compiler expects elsewhere.              }
+        { Warning: never replace a blocknode with another node type,
+          since the block may be the main block of a procedure/function/
+          main program body, and those nodes should always be blocknodes
+          since that's what the compiler expects elsewhere. }
 
         if assigned(left) and
            not assigned(tstatementnode(left).right) then
@@ -731,6 +742,25 @@ implementation
                 ;
             end;
           end;
+        { simple sequence of tempcreate, assign and return temp.? }
+        if GetStatements(left,a) and
+          (a[0].left.nodetype=tempcreaten) and
+          (a[1].left.nodetype=assignn) and
+          (actualtargetnode(@tassignmentnode(a[1].left).left)^.nodetype=temprefn) and
+          (a[2].left.nodetype=tempdeleten) and
+          (a[3].left.nodetype=temprefn) and
+          (ttempcreatenode(a[0].left).tempinfo=ttemprefnode(actualtargetnode(@tassignmentnode(a[1].left).left)^).tempinfo) and
+          (ttempcreatenode(a[0].left).tempinfo=ttempdeletenode(a[2].left).tempinfo) and
+          (ttempcreatenode(a[0].left).tempinfo=ttemprefnode(a[3].left).tempinfo) and
+          { the temp. node might not be references inside the assigned expression }
+          not(foreachnodestatic(tassignmentnode(a[1].left).right,@NodesEqual,actualtargetnode(@tassignmentnode(a[1].left).left)^)) then
+          begin
+            result:=tassignmentnode(a[1].left).right;
+            tassignmentnode(a[1].left).right:=nil;
+            result:=ctypeconvnode.create_internal(result,ttemprefnode(a[3].left).resultdef);
+            firstpass(result);
+            exit;
+          end;
       end;
 
 

+ 25 - 2
compiler/nutils.pas

@@ -29,7 +29,8 @@ interface
   uses
     globtype,constexp,
     symtype,symsym,symbase,symtable,
-    node,compinnr;
+    node,compinnr,
+    nbas;
 
   const
     NODE_COMPLEXITY_INF = 255;
@@ -175,6 +176,10 @@ interface
     { returns true if the node is an inline node of type i }
     function is_inlinefunction(p : tnode;i : tinlinenumber) : Boolean;
 
+    { checks if p is a series of length(a) statments, if yes, they are returned
+      in a and the function returns true }
+    function GetStatements(p : tnode;var a : array of tstatementnode) : Boolean;
+
     type
       TMatchProc2 = function(n1,n2 : tnode) : Boolean is nested;
       TTransformProc2 = function(n1,n2 : tnode) : tnode is nested;
@@ -189,7 +194,7 @@ implementation
       cutils,verbose,globals,
       symconst,symdef,
       defcmp,defutil,
-      nbas,ncon,ncnv,nld,nflw,nset,ncal,nadd,nmem,ninl,
+      ncon,ncnv,nld,nflw,nset,ncal,nadd,nmem,ninl,
       cpubase,cgbase,procinfo,
       pass_1;
 
@@ -1583,6 +1588,24 @@ implementation
       end;
 
 
+    { checks if p is a series of length(a) statments, if yes, they are returned
+      in a and the function returns true }
+    function GetStatements(p : tnode;var a : array of tstatementnode) : Boolean;
+      var
+        i: Integer;
+      begin
+        Result:=false;
+        for i:=0 to high(a) do
+          begin
+            if not(assigned(p)) or not(p.nodetype=statementn) then
+              exit;
+            a[i]:=tstatementnode(p);
+            p:=tstatementnode(p).right;
+          end;
+        Result:=true;
+      end;
+
+
     function MatchAndTransformNodesCommutative(n1,n2 : tnode;matchproc : TMatchProc2;transformproc : TTransformProc2;var res : tnode) : Boolean;
       begin
         res:=nil;