Explorar o código

* fix dfa of for nodes, loopiteration node introduced to get proper life information for the loop

git-svn-id: trunk@25974 -
florian %!s(int64=11) %!d(string=hai) anos
pai
achega
89f34965e9
Modificáronse 3 ficheiros con 49 adicións e 26 borrados
  1. 3 1
      compiler/nflw.pas
  2. 41 22
      compiler/optdfa.pas
  3. 5 3
      compiler/optutils.pas

+ 3 - 1
compiler/nflw.pas

@@ -96,7 +96,9 @@ interface
           { if count isn divisable by unrolls then
             the for loop must jump to this label to get the correct
             number of executions }
-          entrylabel : tnode;
+          entrylabel,
+          { this is a dummy node used by the dfa to store life information for the loop iteration }
+          loopiteration : tnode;
           loopvar_notid:cardinal;
           constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;reintroduce;
           procedure loop_var_access(not_type:Tnotification_flag;symbol:Tsym);

+ 41 - 22
compiler/optdfa.pas

@@ -245,7 +245,7 @@ unit optdfa;
           l : TDFASet;
           save: TDFASet;
           i : longint;
-
+          counteruse_after_loop : boolean;
         begin
           if node=nil then
             exit;
@@ -257,7 +257,6 @@ unit optdfa;
             exit;
           include(node.flags,nf_processing);
 
-
           if not(assigned(node.successor)) and (node<>resultnode) then
             node.successor:=resultnode;
 
@@ -327,6 +326,7 @@ unit optdfa;
                   t2: body
                 }
                 node.allocoptinfo;
+                tfornode(node).loopiteration.allocoptinfo;
                 if not(assigned(node.optinfo^.def)) and
                    not(assigned(node.optinfo^.use)) then
                   begin
@@ -341,37 +341,56 @@ unit optdfa;
                 { create life for the body }
                 CreateInfo(tfornode(node).t2);
 
-                { expect a blocknode as body because we need to push the life information
-                  of the counter variable into it
-                if tfornode(node).t2.nodetype<>blockn then
-                  begin
-                    printnode(tfornode(node).t2);
-                    internalerror(2013110301);
-                  end;}
+                { is the counter living after the loop?
+
+                  if left is a record element, it might not be tracked by dfa, so
+                  optinfo might not be assigned
+                }
+                counteruse_after_loop:=assigned(tfornode(node).left.optinfo) and
+                  DFASetIn(node.successor.optinfo^.life,tfornode(node).left.optinfo^.index);
 
-                { first update the body }
+                { if yes, then we should warn }
+                { !!!!!! }
+
+                { first update the dummy node }
+
+                { get the life of the loop block }
                 l:=copy(tfornode(node).t2.optinfo^.life);
 
-                { take care of the sucessor as it's possible that we don't have one execution of the body }
+                { take care of the sucessor }
                 DFASetIncludeSet(l,node.successor.optinfo^.life);
 
-                { the counter variable is living as well inside the for loop }
-                DFASetInclude(l,tfornode(node).left.optinfo^.index);
+                { the counter variable is living as well inside the for loop
+
+                  if left is a record element, it might not be tracked by dfa, so
+                  optinfo might not be assigned
+                }
+                if assigned(tfornode(node).left.optinfo) then
+                  DFASetInclude(l,tfornode(node).left.optinfo^.index);
 
                 { force block node life info }
-                UpdateLifeInfo(tfornode(node).t2,l);
+                UpdateLifeInfo(tfornode(node).loopiteration,l);
+
+                { now update the for node itself }
+
+                { get the life of the loop block }
+                l:=copy(tfornode(node).t2.optinfo^.life);
 
-                { avoid to modify the life information set above for t2 }
-                l:=copy(l);
+                { take care of the sucessor as it's possible that we don't have one execution of the body }
+                if not(tfornode(node).right.nodetype=ordconstn) or not(tfornode(node).t1.nodetype=ordconstn) then
+                  DFASetIncludeSet(l,node.successor.optinfo^.life);
 
-                { update l for the for node itself }
-                DFASetIncludeSet(l,tfornode(node).t2.optinfo^.life);
+                {
+                  the counter variable is not living at the entry of the for node
 
-                { the counter variable is not living at the entry of the for node }
-                DFASetExclude(l,tfornode(node).left.optinfo^.index);
+                  if left is a record element, it might not be tracked by dfa, so
+                    optinfo might not be assigned
+                }
+                if assigned(tfornode(node).left.optinfo) then
+                  DFASetExclude(l,tfornode(node).left.optinfo^.index);
 
-                { ... but it could be that left/right use it, so do it after
-                  removing def }
+                { ... but it could be that left/right use it, so do this after
+                  removing the def of the counter variable }
                 DFASetIncludeSet(l,node.optinfo^.use);
 
                 UpdateLifeInfo(node,l);

+ 5 - 3
compiler/optutils.pas

@@ -196,12 +196,14 @@ unit optutils;
                 Breakstack.Add(succ);
                 Continuestack.Add(p);
                 result:=p;
-                { the successor of the last node of the for body is the body itself }
-                DoSet(tfornode(p).t2,tfornode(p).t2);
+                { the successor of the last node of the for body is the dummy loop iteration node
+                  it allows the dfa to inject needed life information into the loop }
+                tfornode(p).loopiteration:=cnothingnode.create;
+
+                DoSet(tfornode(p).t2,tfornode(p).loopiteration);
                 p.successor:=succ;
                 Breakstack.Delete(Breakstack.Count-1);
                 Continuestack.Delete(Continuestack.Count-1);
-                p.successor:=succ;
               end;
             breakn:
               begin