Sfoglia il codice sorgente

* 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 anni fa
parent
commit
2f2b378c03
3 ha cambiato i file con 73 aggiunte e 22 eliminazioni
  1. 46 14
      compiler/nflw.pas
  2. 4 0
      compiler/optdfa.pas
  3. 23 8
      compiler/psub.pas

+ 46 - 14
compiler/nflw.pas

@@ -110,6 +110,7 @@ interface
           constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;reintroduce;
           function pass_typecheck:tnode;override;
           function pass_1 : tnode;override;
+          function makewhileloop : tnode;
           function simplify(forinline : boolean) : tnode;override;
        end;
        tfornodeclass = class of tfornode;
@@ -280,6 +281,10 @@ interface
        enumerator_get, enumerator_move: tprocdef; enumerator_current: tpropertysym): 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
 
     uses
@@ -993,6 +998,28 @@ implementation
         current_filepos:=storefilepos;
       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
 *****************************************************************************}
@@ -1702,6 +1729,20 @@ implementation
 
 
     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
         ifblock,loopblock : tblocknode;
         ifstatements,statements,loopstatements : tstatementnode;
@@ -1716,6 +1757,7 @@ implementation
         usetotemp : boolean;
         { if the lower bound is not constant, it must be store in a temp before calculating the upper bound }
         usefromtemp : boolean;
+        storefilepos: tfileposinfo;
 
       procedure iterate_counter(var s : tstatementnode;fw : boolean);
         begin
@@ -1737,21 +1779,10 @@ implementation
 
       begin
         result:=nil;
-        expectloc:=LOC_VOID;
-        fromtemp:=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)
         { 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
@@ -1890,6 +1921,7 @@ implementation
             addstatement(ifstatements,cwhilerepeatnode.create(caddnode.create_internal(cond,left.getcopy,t1.getcopy),loopblock,false,true));
             addstatement(statements,ifblock);
           end;
+        current_filepos:=storefilepos;
       end;
 
 

+ 4 - 0
compiler/optdfa.pas

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

+ 23 - 8
compiler/psub.pas

@@ -1139,6 +1139,7 @@ implementation
     procedure tcgprocinfo.OptimizeNodeTree;
       var
         i : integer;
+        RedoDFA: Boolean;
         {RedoDFA : boolean;}
       begin
        { do this before adding the entry code else the tail recursion recognition won't work,
@@ -1158,6 +1159,24 @@ implementation
            dfabuilder:=TDFABuilder.Create;
            dfabuilder.createdfainfo(code);
            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
              variables ...
@@ -1186,19 +1205,15 @@ implementation
                        tabstractnormalvarsym(tloadnode(dfabuilder.nodemap[i]).symtableentry).noregvarinitneeded:=true
                    end;
                end;
+         end
+       else
+         begin
+           ConvertForLoops(code);
          end;
 
        if (pi_dfaavailable in flags) and (cs_opt_dead_store_eliminate in current_settings.optimizerswitches) then
          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
          (procdef.proctypeoption in [potype_operator,potype_procedure,potype_function]) and
          (code.nodetype=blockn) and (tblocknode(code).statements=nil) then