Browse Source

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

git-svn-id: trunk@25974 -
florian 11 years ago
parent
commit
89f34965e9
3 changed files with 49 additions and 26 deletions
  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
           { if count isn divisable by unrolls then
             the for loop must jump to this label to get the correct
             the for loop must jump to this label to get the correct
             number of executions }
             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;
           loopvar_notid:cardinal;
           constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;reintroduce;
           constructor create(l,r,_t1,_t2 : tnode;back : boolean);virtual;reintroduce;
           procedure loop_var_access(not_type:Tnotification_flag;symbol:Tsym);
           procedure loop_var_access(not_type:Tnotification_flag;symbol:Tsym);

+ 41 - 22
compiler/optdfa.pas

@@ -245,7 +245,7 @@ unit optdfa;
           l : TDFASet;
           l : TDFASet;
           save: TDFASet;
           save: TDFASet;
           i : longint;
           i : longint;
-
+          counteruse_after_loop : boolean;
         begin
         begin
           if node=nil then
           if node=nil then
             exit;
             exit;
@@ -257,7 +257,6 @@ unit optdfa;
             exit;
             exit;
           include(node.flags,nf_processing);
           include(node.flags,nf_processing);
 
 
-
           if not(assigned(node.successor)) and (node<>resultnode) then
           if not(assigned(node.successor)) and (node<>resultnode) then
             node.successor:=resultnode;
             node.successor:=resultnode;
 
 
@@ -327,6 +326,7 @@ unit optdfa;
                   t2: body
                   t2: body
                 }
                 }
                 node.allocoptinfo;
                 node.allocoptinfo;
+                tfornode(node).loopiteration.allocoptinfo;
                 if not(assigned(node.optinfo^.def)) and
                 if not(assigned(node.optinfo^.def)) and
                    not(assigned(node.optinfo^.use)) then
                    not(assigned(node.optinfo^.use)) then
                   begin
                   begin
@@ -341,37 +341,56 @@ unit optdfa;
                 { create life for the body }
                 { create life for the body }
                 CreateInfo(tfornode(node).t2);
                 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);
                 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);
                 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 }
                 { 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);
                 DFASetIncludeSet(l,node.optinfo^.use);
 
 
                 UpdateLifeInfo(node,l);
                 UpdateLifeInfo(node,l);

+ 5 - 3
compiler/optutils.pas

@@ -196,12 +196,14 @@ unit optutils;
                 Breakstack.Add(succ);
                 Breakstack.Add(succ);
                 Continuestack.Add(p);
                 Continuestack.Add(p);
                 result:=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;
                 p.successor:=succ;
                 Breakstack.Delete(Breakstack.Count-1);
                 Breakstack.Delete(Breakstack.Count-1);
                 Continuestack.Delete(Continuestack.Count-1);
                 Continuestack.Delete(Continuestack.Count-1);
-                p.successor:=succ;
               end;
               end;
             breakn:
             breakn:
               begin
               begin