فهرست منبع

* properly reset nf_write/nf_modify flags for min/max inline nodes, needed by dead store optimization, resolves #39958
* factored out nutils.node_reset_pass1_write

florian 2 سال پیش
والد
کامیت
5670a7543c
4فایلهای تغییر یافته به همراه45 افزوده شده و 15 حذف شده
  1. 1 0
      compiler/nflw.pas
  2. 2 15
      compiler/ninl.pas
  3. 25 0
      compiler/nutils.pas
  4. 17 0
      tests/webtbs/tw39958.pp

+ 1 - 0
compiler/nflw.pas

@@ -1707,6 +1707,7 @@ implementation
                 cinlinenode.create(in_nr,false,ccallparanode.create(tassignmentnode(elsestmnt).right.getcopy,
                       ccallparanode.create(tassignmentnode(thenstmnt).right.getcopy,nil)))
                 );
+            node_reset_pass1_write(Result);
           end;
 {$endif defined(i386) or defined(x86_64) or defined(xtensa) or defined(aarch64)}
 {$endif llvm}

+ 2 - 15
compiler/ninl.pas

@@ -4558,6 +4558,7 @@ implementation
         temp_pnode^ := nil;
       end;
 
+
      function tinlinenode.first_abs_long : tnode;
       begin
         expectloc:=LOC_REGISTER;
@@ -4565,20 +4566,6 @@ implementation
       end;
 
 
-     function node_reset_pass1_write(var n: tnode; arg: pointer): foreachnoderesult;
-       begin
-         Result := fen_false;
-         n.flags := n.flags - [nf_pass1_done,nf_write,nf_modify];
-         if n.nodetype = assignn then
-           begin
-             { Force re-evaluation of assignments so nf_modify and nf_write
-               flags are correctly set. }
-             n.resultdef := nil;
-             Result := fen_true;
-           end;
-       end;
-
-
      function tinlinenode.getaddsub_for_incdec : tnode;
        var
          hp,hpp,resultnode  : tnode;
@@ -4680,7 +4667,7 @@ implementation
 
          { force pass 1, so copied trees get first pass'ed as well and flags like
            nf_call_unique get set right }
-         foreachnodestatic(hpp,@node_reset_pass1_write,nil);
+         node_reset_pass1_write(hpp);
          do_typecheckpass(hpp);
 
          addstatement(newstatement,cassignmentnode.create(resultnode,hpp));

+ 25 - 0
compiler/nutils.pas

@@ -201,6 +201,10 @@ interface
     }
     function MatchAndTransformNodesCommutative(n1,n2,n3,n4 : tnode;matchproc : TMatchProc4;transformproc : TTransformProc4;var res : tnode) : Boolean;
 
+    {
+      resets all flags so that nf_write/nf_modify information is regenerated
+    }
+    procedure node_reset_pass1_write(n: tnode);
 
 implementation
 
@@ -1693,4 +1697,25 @@ implementation
           result:=false;
       end;
 
+
+     function _node_reset_pass1_write(var n: tnode; arg: pointer): foreachnoderesult;
+       begin
+         Result := fen_false;
+         n.flags := n.flags - [nf_pass1_done,nf_write,nf_modify];
+         if n.nodetype = assignn then
+           begin
+             { Force re-evaluation of assignments so nf_modify and nf_write
+               flags are correctly set. }
+             n.resultdef := nil;
+             Result := fen_true;
+           end;
+       end;
+
+
+     procedure node_reset_pass1_write(n: tnode);
+       begin
+         foreachnodestatic(n,@_node_reset_pass1_write,nil);
+       end;
+
+
 end.

+ 17 - 0
tests/webtbs/tw39958.pp

@@ -0,0 +1,17 @@
+{ %opt=-O4 -Oodeadstore}
+var
+	data: array[0 .. 1] of single = (8, 7);
+	minData, maxData: single;
+
+begin
+	minData := data[0];
+	maxData := data[0];
+	if data[1] < minData then minData := data[1];
+	if data[1] > maxData then maxData := data[1];
+	writeln('min = ', minData:0:2, ' (must be 7), max = ', maxData:0:2, ' (must be 8).');
+    if minData<>7 then
+      halt(1);
+    if maxData<>8 then
+      halt(1);
+    writeln('ok');
+end.