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

* moved conversion of for into while loops in a separate pass, so node optimizations on the node tree can be
carried out without losing information from for loops

git-svn-id: trunk@43910 -

florian 5 жил өмнө
parent
commit
2f2b378c03

+ 46 - 14
compiler/nflw.pas

@@ -110,6 +110,7 @@ interface
           constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;reintroduce;
           constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;reintroduce;
           function pass_typecheck:tnode;override;
           function pass_typecheck:tnode;override;
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
+          function makewhileloop : tnode;
           function simplify(forinline : boolean) : tnode;override;
           function simplify(forinline : boolean) : tnode;override;
        end;
        end;
        tfornodeclass = class of tfornode;
        tfornodeclass = class of tfornode;
@@ -280,6 +281,10 @@ interface
        enumerator_get, enumerator_move: tprocdef; enumerator_current: tpropertysym): tnode;
        enumerator_get, enumerator_move: tprocdef; enumerator_current: tpropertysym): tnode;
     function create_for_in_loop(hloopvar, hloopbody, expr: tnode): tnode;
     function create_for_in_loop(hloopvar, hloopbody, expr: tnode): tnode;
 
 
+    { converts all for nodes in the tree into while nodes,
+      returns true if something was converted }
+    function ConvertForLoops(var n : tnode) : Boolean;
+
 implementation
 implementation
 
 
     uses
     uses
@@ -993,6 +998,28 @@ implementation
         current_filepos:=storefilepos;
         current_filepos:=storefilepos;
       end;
       end;
 
 
+
+    function _ConvertForLoops(var n: tnode; arg: pointer): foreachnoderesult;
+      var
+        hp : tnode;
+      begin
+        Result:=fen_false;
+        if n.nodetype=forn then
+          begin
+            Result:=fen_true;
+            hp:=n;
+            n:=tfornode(n).makewhileloop;
+            do_firstpass(n);
+            hp.Free;
+          end;
+      end;
+
+
+    function ConvertForLoops(var n : tnode) : boolean;
+      begin
+        result:=foreachnodestatic(pm_postprocess,n,@_ConvertForLoops,nil);
+      end;
+
 {****************************************************************************
 {****************************************************************************
                                  TLOOPNODE
                                  TLOOPNODE
 *****************************************************************************}
 *****************************************************************************}
@@ -1702,6 +1729,20 @@ implementation
 
 
 
 
     function tfornode.pass_1 : tnode;
     function tfornode.pass_1 : tnode;
+      begin
+        result:=nil;
+        expectloc:=LOC_VOID;
+
+        firstpass(left);
+        firstpass(right);
+        firstpass(t1);
+
+        if assigned(t2) then
+          firstpass(t2);
+      end;
+
+
+    function tfornode.makewhileloop : tnode;
       var
       var
         ifblock,loopblock : tblocknode;
         ifblock,loopblock : tblocknode;
         ifstatements,statements,loopstatements : tstatementnode;
         ifstatements,statements,loopstatements : tstatementnode;
@@ -1716,6 +1757,7 @@ implementation
         usetotemp : boolean;
         usetotemp : boolean;
         { if the lower bound is not constant, it must be store in a temp before calculating the upper bound }
         { if the lower bound is not constant, it must be store in a temp before calculating the upper bound }
         usefromtemp : boolean;
         usefromtemp : boolean;
+        storefilepos: tfileposinfo;
 
 
       procedure iterate_counter(var s : tstatementnode;fw : boolean);
       procedure iterate_counter(var s : tstatementnode;fw : boolean);
         begin
         begin
@@ -1737,21 +1779,10 @@ implementation
 
 
       begin
       begin
         result:=nil;
         result:=nil;
-        expectloc:=LOC_VOID;
-        fromtemp:=nil;
         totemp:=nil;
         totemp:=nil;
-
-        firstpass(left);
-        firstpass(right);
-        firstpass(t1);
-
-        if assigned(t2) then
-          begin
-            firstpass(t2);
-            if codegenerror then
-              exit;
-          end;
-
+        fromtemp:=nil;
+        storefilepos:=current_filepos;
+        current_filepos:=fileinfo;
         do_loopvar_at_end:=(lnf_dont_mind_loopvar_on_exit in loopflags)
         do_loopvar_at_end:=(lnf_dont_mind_loopvar_on_exit in loopflags)
         { if the loop is unrolled and there is a jump into the loop,
         { if the loop is unrolled and there is a jump into the loop,
           then we can't do the trick with incrementing the loop var only at the
           then we can't do the trick with incrementing the loop var only at the
@@ -1890,6 +1921,7 @@ implementation
             addstatement(ifstatements,cwhilerepeatnode.create(caddnode.create_internal(cond,left.getcopy,t1.getcopy),loopblock,false,true));
             addstatement(ifstatements,cwhilerepeatnode.create(caddnode.create_internal(cond,left.getcopy,t1.getcopy),loopblock,false,true));
             addstatement(statements,ifblock);
             addstatement(statements,ifblock);
           end;
           end;
+        current_filepos:=storefilepos;
       end;
       end;
 
 
 
 

+ 4 - 0
compiler/optdfa.pas

@@ -602,6 +602,10 @@ unit optdfa;
       if the tree has been changed without updating dfa }
       if the tree has been changed without updating dfa }
     procedure TDFABuilder.resetdfainfo(node : tnode);
     procedure TDFABuilder.resetdfainfo(node : tnode);
       begin
       begin
+        nodemap.Free;
+        nodemap:=nil;
+        resultnode.Free;
+        resultnode:=nil;
         foreachnodestatic(pm_postprocess,node,@ResetDFA,nil);
         foreachnodestatic(pm_postprocess,node,@ResetDFA,nil);
       end;
       end;
 
 

+ 23 - 8
compiler/psub.pas

@@ -1139,6 +1139,7 @@ implementation
     procedure tcgprocinfo.OptimizeNodeTree;
     procedure tcgprocinfo.OptimizeNodeTree;
       var
       var
         i : integer;
         i : integer;
+        RedoDFA: Boolean;
         {RedoDFA : boolean;}
         {RedoDFA : boolean;}
       begin
       begin
        { do this before adding the entry code else the tail recursion recognition won't work,
        { do this before adding the entry code else the tail recursion recognition won't work,
@@ -1158,6 +1159,24 @@ implementation
            dfabuilder:=TDFABuilder.Create;
            dfabuilder:=TDFABuilder.Create;
            dfabuilder.createdfainfo(code);
            dfabuilder.createdfainfo(code);
            include(flags,pi_dfaavailable);
            include(flags,pi_dfaavailable);
+           RedoDFA:=false;
+
+           if (cs_opt_loopstrength in current_settings.optimizerswitches)
+             { our induction variable strength reduction doesn't like
+               for loops with more than one entry }
+             and not(pi_has_label in flags) then
+             begin
+               RedoDFA:=OptimizeInductionVariables(code);
+             end;
+
+           RedoDFA:=ConvertForLoops(code) or RedoDFA;
+
+           if RedoDFA then
+             begin
+               dfabuilder.resetdfainfo(code);
+               dfabuilder.createdfainfo(code);
+               include(flags,pi_dfaavailable);
+             end;
 
 
            { when life info is available, we can give more sophisticated warning about uninitialized
            { when life info is available, we can give more sophisticated warning about uninitialized
              variables ...
              variables ...
@@ -1186,19 +1205,15 @@ implementation
                        tabstractnormalvarsym(tloadnode(dfabuilder.nodemap[i]).symtableentry).noregvarinitneeded:=true
                        tabstractnormalvarsym(tloadnode(dfabuilder.nodemap[i]).symtableentry).noregvarinitneeded:=true
                    end;
                    end;
                end;
                end;
+         end
+       else
+         begin
+           ConvertForLoops(code);
          end;
          end;
 
 
        if (pi_dfaavailable in flags) and (cs_opt_dead_store_eliminate in current_settings.optimizerswitches) then
        if (pi_dfaavailable in flags) and (cs_opt_dead_store_eliminate in current_settings.optimizerswitches) then
          do_optdeadstoreelim(code);
          do_optdeadstoreelim(code);
 
 
-       if (cs_opt_loopstrength in current_settings.optimizerswitches)
-         { our induction variable strength reduction doesn't like
-           for loops with more than one entry }
-         and not(pi_has_label in flags) then
-         begin
-           {RedoDFA:=}OptimizeInductionVariables(code);
-         end;
-
        if (cs_opt_remove_emtpy_proc in current_settings.optimizerswitches) and
        if (cs_opt_remove_emtpy_proc in current_settings.optimizerswitches) and
          (procdef.proctypeoption in [potype_operator,potype_procedure,potype_function]) and
          (procdef.proctypeoption in [potype_operator,potype_procedure,potype_function]) and
          (code.nodetype=blockn) and (tblocknode(code).statements=nil) then
          (code.nodetype=blockn) and (tblocknode(code).statements=nil) then