Ver Fonte

* make actualtargetnode a normal procedure using pointers to node so it can be used also when replacing nodes
+ replacenode to replace nodes inline

git-svn-id: trunk@25013 -

florian há 12 anos atrás
pai
commit
be2ab84474
6 ficheiros alterados com 56 adições e 45 exclusões
  1. 3 3
      compiler/ncal.pas
  2. 13 21
      compiler/ncgmem.pas
  3. 0 10
      compiler/ncnv.pas
  4. 0 10
      compiler/node.pas
  5. 39 0
      compiler/nutils.pas
  6. 1 1
      compiler/optcse.pas

+ 3 - 3
compiler/ncal.pas

@@ -2307,7 +2307,7 @@ implementation
           exit;
           exit;
 
 
         { remove possible typecasts }
         { remove possible typecasts }
-        realassignmenttarget:=aktassignmentnode.left.actualtargetnode;
+        realassignmenttarget:=actualtargetnode(@aktassignmentnode.left)^;
 
 
         { when it is not passed in a parameter it will only be used after the
         { when it is not passed in a parameter it will only be used after the
           function call }
           function call }
@@ -2327,7 +2327,7 @@ implementation
           point
           point
         }
         }
         if assigned(methodpointer) and
         if assigned(methodpointer) and
-           realassignmenttarget.isequal(methodpointer.actualtargetnode) then
+           realassignmenttarget.isequal(actualtargetnode(@methodpointer)^) then
           exit;
           exit;
 
 
         { when we substitute a function result inside an inlined function,
         { when we substitute a function result inside an inlined function,
@@ -3169,7 +3169,7 @@ implementation
                { skip (absolute and other simple) type conversions -- only now,
                { skip (absolute and other simple) type conversions -- only now,
                  because the checks above have to take type conversions into
                  because the checks above have to take type conversions into
                  e.g. class reference types account }
                  e.g. class reference types account }
-               hpt:=hpt.actualtargetnode;
+               hpt:=actualtargetnode(@hpt)^;
 
 
                { R.Init then R will be initialized by the constructor,
                { R.Init then R will be initialized by the constructor,
                  Also allow it for simple loads }
                  Also allow it for simple loads }

+ 13 - 21
compiler/ncgmem.pas

@@ -803,7 +803,7 @@ implementation
       var
       var
          offsetdec,
          offsetdec,
          extraoffset : aint;
          extraoffset : aint;
-         t        : tnode;
+         rightp      : pnode;
          otl,ofl  : tasmlabel;
          otl,ofl  : tasmlabel;
          newsize  : tcgsize;
          newsize  : tcgsize;
          mulsize,
          mulsize,
@@ -981,34 +981,26 @@ implementation
                  not is_packed_array(left.resultdef) then
                  not is_packed_array(left.resultdef) then
                 begin
                 begin
                    extraoffset:=0;
                    extraoffset:=0;
-                   if (right.nodetype=addn) then
+                   rightp:=actualtargetnode(@right);
+                   if rightp^.nodetype=addn then
                      begin
                      begin
-                        if taddnode(right).right.nodetype=ordconstn then
+                        if taddnode(rightp^).right.nodetype=ordconstn then
                           begin
                           begin
-                             extraoffset:=tordconstnode(taddnode(right).right).value.svalue;
-                             t:=taddnode(right).left;
-                             taddnode(right).left:=nil;
-                             right.free;
-                             right:=t;
+                            extraoffset:=tordconstnode(taddnode(rightp^).right).value.svalue;
+                            replacenode(rightp^,taddnode(rightp^).left);
                           end
                           end
-                        else if taddnode(right).left.nodetype=ordconstn then
+                        else if taddnode(rightp^).left.nodetype=ordconstn then
                           begin
                           begin
-                             extraoffset:=tordconstnode(taddnode(right).left).value.svalue;
-                             t:=taddnode(right).right;
-                             taddnode(right).right:=nil;
-                             right.free;
-                             right:=t;
+                            extraoffset:=tordconstnode(taddnode(rightp^).left).value.svalue;
+                            replacenode(rightp^,taddnode(rightp^).right);
                           end;
                           end;
                      end
                      end
-                   else if (right.nodetype=subn) then
+                   else if rightp^.nodetype=subn then
                      begin
                      begin
-                        if taddnode(right).right.nodetype=ordconstn then
+                        if taddnode(rightp^).right.nodetype=ordconstn then
                           begin
                           begin
-                             extraoffset:=-tordconstnode(taddnode(right).right).value.svalue;
-                             t:=taddnode(right).left;
-                             taddnode(right).left:=nil;
-                             right.free;
-                             right:=t;
+                            extraoffset:=-tordconstnode(taddnode(rightp^).right).value.svalue;
+                            replacenode(rightp^,taddnode(rightp^).left);
                           end;
                           end;
                      end;
                      end;
                    inc(location.reference.offset,
                    inc(location.reference.offset,

+ 0 - 10
compiler/ncnv.pas

@@ -48,7 +48,6 @@ interface
           procedure buildderefimpl;override;
           procedure buildderefimpl;override;
           procedure derefimpl;override;
           procedure derefimpl;override;
           function dogetcopy : tnode;override;
           function dogetcopy : tnode;override;
-          function actualtargetnode: tnode;override;
           procedure printnodeinfo(var t : text);override;
           procedure printnodeinfo(var t : text);override;
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
           function pass_typecheck:tnode;override;
           function pass_typecheck:tnode;override;
@@ -2101,15 +2100,6 @@ implementation
       end;
       end;
 
 
 
 
-    function ttypeconvnode.actualtargetnode: tnode;
-      begin
-        result:=self;
-        while (result.nodetype=typeconvn) and
-              ttypeconvnode(result).retains_value_location do
-          result:=ttypeconvnode(result).left;
-      end;
-
-
     function ttypeconvnode.pass_typecheck:tnode;
     function ttypeconvnode.pass_typecheck:tnode;
 
 
       var
       var

+ 0 - 10
compiler/node.pas

@@ -367,10 +367,6 @@ interface
          { does the real copying of a node }
          { does the real copying of a node }
          function dogetcopy : tnode;virtual;
          function dogetcopy : tnode;virtual;
 
 
-         { returns the real loadn/temprefn a node refers to,
-           skipping (absolute) equal type conversions        }
-         function actualtargetnode: tnode;virtual;
-
          procedure insertintolist(l : tnodelist);virtual;
          procedure insertintolist(l : tnodelist);virtual;
          { writes a node for debugging purpose, shouldn't be called }
          { writes a node for debugging purpose, shouldn't be called }
          { direct, because there is no test for nil, use printnode  }
          { direct, because there is no test for nil, use printnode  }
@@ -952,12 +948,6 @@ implementation
       end;
       end;
 
 
 
 
-    function tnode.actualtargetnode: tnode;
-      begin
-        result:=self;
-      end;
-
-
     procedure tnode.insertintolist(l : tnodelist);
     procedure tnode.insertintolist(l : tnodelist);
       begin
       begin
       end;
       end;

+ 39 - 0
compiler/nutils.pas

@@ -82,6 +82,7 @@ interface
 
 
     { tries to simplify the given node after inlining }
     { tries to simplify the given node after inlining }
     procedure doinlinesimplify(var n : tnode);
     procedure doinlinesimplify(var n : tnode);
+
     { creates an ordinal constant, optionally based on the result from a
     { creates an ordinal constant, optionally based on the result from a
       simplify operation: normally the type is the smallest integer type
       simplify operation: normally the type is the smallest integer type
       that can hold the value, but when inlining the "def" will be used instead,
       that can hold the value, but when inlining the "def" will be used instead,
@@ -122,6 +123,18 @@ interface
       if no dirty tricks like buffer overflows or pointer magic are used }
       if no dirty tricks like buffer overflows or pointer magic are used }
     function is_const(node : tnode) : boolean;
     function is_const(node : tnode) : boolean;
 
 
+    { returns a pointer to the real node a node refers to,
+      skipping (absolute) equal type conversions. Returning
+      a pointer allows the caller to move/remove/replace this
+      node
+    }
+    function actualtargetnode(n : pnode) : pnode;
+
+    { moves src into dest, before doing so, right is set to nil and dest is freed.
+      Because dest and src are var parameters, this can be done inline in an existing
+      node tree }
+    procedure replacenode(var dest,src : tnode);
+
 implementation
 implementation
 
 
     uses
     uses
@@ -1144,4 +1157,30 @@ implementation
         result:=(node.nodetype=temprefn) and (ti_const in ttemprefnode(node).tempinfo^.flags)
         result:=(node.nodetype=temprefn) and (ti_const in ttemprefnode(node).tempinfo^.flags)
       end;
       end;
 
 
+
+    function actualtargetnode(n : pnode) : pnode;
+      begin
+        result:=n;
+        case n^.nodetype of
+          typeconvn:
+            if ttypeconvnode(n^).retains_value_location then
+              result:=actualtargetnode(@ttypeconvnode(n^).left);
+        end;
+      end;
+
+
+    procedure replacenode(var dest,src : tnode);
+      var
+        t : tnode;
+      begin
+        t:=src;
+        { set src nil before free'ing dest because
+          src could be part of dest }
+        src:=nil;
+        dest.Free;
+        dest:=t;
+      end;
+
+
+
 end.
 end.

+ 1 - 1
compiler/optcse.pas

@@ -151,7 +151,7 @@ unit optcse;
           assigned(n.resultdef) and
           assigned(n.resultdef) and
           (
           (
             { regable expressions }
             { regable expressions }
-            (n.actualtargetnode.flags*[nf_write,nf_modify]=[]) and
+            (actualtargetnode(@n)^.flags*[nf_write,nf_modify]=[]) and
             ((tstoreddef(n.resultdef).is_intregable or tstoreddef(n.resultdef).is_fpuregable) and
             ((tstoreddef(n.resultdef).is_intregable or tstoreddef(n.resultdef).is_fpuregable) and
             { is_int/fpuregable allows arrays and records to be in registers, cse cannot handle this }
             { is_int/fpuregable allows arrays and records to be in registers, cse cannot handle this }
             (not(n.resultdef.typ in [arraydef,recorddef])) and
             (not(n.resultdef.typ in [arraydef,recorddef])) and