Ver Fonte

+ propagate constants across call nodes

git-svn-id: trunk@44184 -
florian há 5 anos atrás
pai
commit
e350264db1
1 ficheiros alterados com 23 adições e 4 exclusões
  1. 23 4
      compiler/optconstprop.pas

+ 23 - 4
compiler/optconstprop.pas

@@ -76,8 +76,8 @@ unit optconstprop;
       var
         st2, oldnode: tnode;
         old: pnode;
-        changed, tree_modified2,tree_modified3: boolean;
-        written : Boolean;
+        changed, tree_modified2, tree_modified3: boolean;
+        written, tree_modified4, tree_modified5: Boolean;
       begin
         result:=true;
 
@@ -87,6 +87,8 @@ unit optconstprop;
         tree_modified:=false;
         tree_modified2:=false;
         tree_modified3:=false;
+        tree_modified4:=false;
+        tree_modified5:=false;
 
         { while it might be usefull, to use foreach to iterate all nodes, it is safer to
           iterate manually here so we have full controll how all nodes are processed }
@@ -94,7 +96,8 @@ unit optconstprop;
         { We cannot analyze beyond those nodes, so we terminate to be on the safe side }
         if (n.nodetype in [addrn,derefn,asmn,casen,whilerepeatn,labeln,continuen,breakn,
                            tryexceptn,raisen,tryfinallyn,onn,loadparentfpn,loadvmtaddrn,guidconstn,rttin,addoptn,asn,goton,
-                           objcselectorn,objcprotocoln]) then
+                           objcselectorn,objcprotocoln,
+                           arrayconstructorn,arrayconstructorrangen]) then
           exit(false)
         else if n.nodetype=assignn then
           begin
@@ -219,7 +222,23 @@ unit optconstprop;
             result:=false;
           end
         else if n.nodetype=calln then
-          exit(false)
+          begin
+            { only propagate simply variables which are regable, this means that their address is not
+              taken }
+            if (tassignmentnode(arg).left.nodetype=loadn) and
+              (tabstractvarsym(tloadnode(tassignmentnode(arg).left).symtableentry).varregable in [vr_fpureg,vr_mmreg,vr_intreg]) then
+              begin
+                result:=replaceBasicAssign(tnode(tcallnode(n).callinitblock), arg, tree_modified);
+                result:=result and replaceBasicAssign(tcallnode(n).left, arg, tree_modified2);
+                result:=result and replaceBasicAssign(tcallnode(n).vmt_entry, arg, tree_modified3);
+                result:=result and replaceBasicAssign(tcallnode(n).right, arg, tree_modified4);
+                result:=result and replaceBasicAssign(tnode(tcallnode(n).callcleanupblock), arg, tree_modified5);
+                tree_modified:=tree_modified or tree_modified2 or tree_modified3 or tree_modified4 or tree_modified5;
+              end
+            else
+              result:=false;
+            exit;
+          end
         else if n.InheritsFrom(tbinarynode) then
           begin
             result:=replaceBasicAssign(tbinarynode(n).left, arg, tree_modified);