浏览代码

+ nf_addr_taken: it marks nodes which address is taken
+ check if tnodeflags is 4 bytes or less
* do not do cse on expressions which address is taken

git-svn-id: trunk@26713 -

florian 11 年之前
父节点
当前提交
1366498255
共有 7 个文件被更改,包括 21 次插入5 次删除
  1. 1 0
      .gitattributes
  2. 2 0
      compiler/htypechk.pas
  3. 2 2
      compiler/ncal.pas
  4. 6 1
      compiler/node.pas
  5. 1 1
      compiler/optcse.pas
  6. 1 1
      compiler/optloop.pas
  7. 8 0
      tests/tbs/tb0603.pp

+ 1 - 0
.gitattributes

@@ -10158,6 +10158,7 @@ tests/tbs/tb0599.pp svneol=native#text/plain
 tests/tbs/tb0600.pp svneol=native#text/plain
 tests/tbs/tb0601.pp svneol=native#text/pascal
 tests/tbs/tb0602.pp svneol=native#text/plain
+tests/tbs/tb0603.pp svneol=native#text/pascal
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/tbs0594.pp svneol=native#text/pascal
 tests/tbs/ub0060.pp svneol=native#text/plain

+ 2 - 0
compiler/htypechk.pas

@@ -974,6 +974,8 @@ implementation
     { marks an lvalue as "unregable" }
     procedure make_not_regable_intern(p : tnode; how: tregableinfoflags; records_only: boolean);
       begin
+        if ra_addr_taken in how then
+          include(p.flags,nf_address_taken);
         repeat
           case p.nodetype of
             subscriptn:

+ 2 - 2
compiler/ncal.pas

@@ -3748,7 +3748,7 @@ implementation
                     begin
                       temp:=paras.left.getcopy;
                       { inherit modification information, this is needed by the dfa/cse }
-                      temp.flags:=temp.flags+(n.flags*[nf_modify,nf_write]);
+                      temp.flags:=temp.flags+(n.flags*[nf_modify,nf_write,nf_address_taken]);
                       n.free;
                       n:=temp;
                       typecheckpass(n);
@@ -3766,7 +3766,7 @@ implementation
                     internalerror(20040720);
                   temp := tnode(inlinelocals[indexnr]).getcopy;
                   { inherit modification information, this is needed by the dfa/cse }
-                  temp.flags:=temp.flags+(n.flags*[nf_modify,nf_write]);
+                  temp.flags:=temp.flags+(n.flags*[nf_modify,nf_write,nf_address_taken]);
                   n.free;
                   n:=temp;
                   typecheckpass(n);

+ 6 - 1
compiler/node.pas

@@ -219,6 +219,8 @@ interface
          nf_write,
          { Node is modified      }
          nf_modify,
+         { address of node is taken }
+         nf_address_taken,
          nf_is_funcret,
          nf_isproperty,
          nf_processing,
@@ -1317,9 +1319,12 @@ implementation
 
 begin
 {$push}{$warnings off}
-  { tvaroption should fit into a 4 byte set for speed reasons }
+  { tvaroption must fit into a 4 byte set for speed reasons }
   if ord(high(tvaroption))>31 then
     internalerror(201110301);
+  { tnodeflags must fit into a 4 byte set for speed reasons }
+  if ord(high(tnodeflags))>31 then
+    internalerror(2014020701);
 {$pop}
 end.
 

+ 1 - 1
compiler/optcse.pas

@@ -151,7 +151,7 @@ unit optcse;
           assigned(n.resultdef) and
           (
             { regable expressions }
-            (actualtargetnode(@n)^.flags*[nf_write,nf_modify]=[]) and
+            (actualtargetnode(@n)^.flags*[nf_write,nf_modify,nf_address_taken]=[]) and
             ((tstoreddef(n.resultdef).is_intregable or tstoreddef(n.resultdef).is_fpuregable) and
             { is_int/fpuregable allows arrays and records to be in registers, cse cannot handle this }
             (not(n.resultdef.typ in [arraydef,recorddef])) and

+ 1 - 1
compiler/optloop.pas

@@ -86,7 +86,7 @@ unit optloop;
           ((n.nodetype=temprefn) and (preplaceinfo(arg)^.node.nodetype=temprefn) and
           (ttemprefnode(n).tempinfo=ttemprefnode(preplaceinfo(arg)^.node).tempinfo)) then
           begin
-            if n.flags*[nf_modify,nf_write]<>[] then
+            if n.flags*[nf_modify,nf_write,nf_address_taken]<>[] then
               internalerror(2012090402);
             n.free;
             n:=cordconstnode.create(preplaceinfo(arg)^.value,preplaceinfo(arg)^.node.resultdef,false);

+ 8 - 0
tests/tbs/tb0603.pp

@@ -0,0 +1,8 @@
+{ %OPT=-O3 }
+{ %norun }
+program test4;
+var
+  S : ansistring;
+begin
+  writeln((PByte(@S[1])^ = $1) or (S[1] = '.'));
+end.