瀏覽代碼

* do not unroll loops if the counter variable is accessed outside the current scope

git-svn-id: trunk@39163 -
florian 7 年之前
父節點
當前提交
21d785e41b
共有 7 個文件被更改,包括 37 次插入6 次删除
  1. 1 0
      .gitattributes
  2. 2 0
      compiler/htypechk.pas
  3. 2 1
      compiler/optloop.pas
  4. 1 1
      compiler/ppu.pas
  5. 8 4
      compiler/symsym.pas
  6. 1 0
      compiler/utils/ppuutils/ppudump.pp
  7. 22 0
      tests/test/cg/tfor2.pp

+ 1 - 0
.gitattributes

@@ -11991,6 +11991,7 @@ tests/test/cg/tdivz1.pp svneol=native#text/plain
 tests/test/cg/tdivz2.pp svneol=native#text/plain
 tests/test/cg/tdivz2.pp svneol=native#text/plain
 tests/test/cg/texit.pp svneol=native#text/plain
 tests/test/cg/texit.pp svneol=native#text/plain
 tests/test/cg/tfor.pp svneol=native#text/plain
 tests/test/cg/tfor.pp svneol=native#text/plain
+tests/test/cg/tfor2.pp svneol=native#text/pascal
 tests/test/cg/tformfnc.pp svneol=native#text/plain
 tests/test/cg/tformfnc.pp svneol=native#text/plain
 tests/test/cg/tfuncret.pp svneol=native#text/plain
 tests/test/cg/tfuncret.pp svneol=native#text/plain
 tests/test/cg/tin.pp svneol=native#text/plain
 tests/test/cg/tin.pp svneol=native#text/plain

+ 2 - 0
compiler/htypechk.pas

@@ -1050,6 +1050,8 @@ implementation
                   begin
                   begin
                     if (ra_addr_taken in how) then
                     if (ra_addr_taken in how) then
                       tabstractvarsym(tloadnode(p).symtableentry).addr_taken:=true;
                       tabstractvarsym(tloadnode(p).symtableentry).addr_taken:=true;
+                    if (ra_different_scope in how) then
+                      tabstractvarsym(tloadnode(p).symtableentry).different_scope:=true;
                     if (tabstractvarsym(tloadnode(p).symtableentry).varregable <> vr_none) and
                     if (tabstractvarsym(tloadnode(p).symtableentry).varregable <> vr_none) and
                        ((not records_only) or
                        ((not records_only) or
                         (tabstractvarsym(tloadnode(p).symtableentry).vardef.typ = recorddef)) then
                         (tabstractvarsym(tloadnode(p).symtableentry).vardef.typ = recorddef)) then

+ 2 - 1
compiler/optloop.pas

@@ -118,7 +118,8 @@ unit optloop;
            { the address of the counter variable might be taken if it is passed by constref to a
            { the address of the counter variable might be taken if it is passed by constref to a
              subroutine, so really check if it is not taken }
              subroutine, so really check if it is not taken }
            ((tfornode(node).left.nodetype=loadn) and (tloadnode(tfornode(node).left).symtableentry is tabstractvarsym) and
            ((tfornode(node).left.nodetype=loadn) and (tloadnode(tfornode(node).left).symtableentry is tabstractvarsym) and
-            not(tabstractvarsym(tloadnode(tfornode(node).left).symtableentry).addr_taken))
+            not(tabstractvarsym(tloadnode(tfornode(node).left).symtableentry).addr_taken) and
+            not(tabstractvarsym(tloadnode(tfornode(node).left).symtableentry).different_scope))
            ) then
            ) then
           begin
           begin
             { number of executions known? }
             { number of executions known? }

+ 1 - 1
compiler/ppu.pas

@@ -43,7 +43,7 @@ type
 {$endif Test_Double_checksum}
 {$endif Test_Double_checksum}
 
 
 const
 const
-  CurrentPPUVersion = 200;
+  CurrentPPUVersion = 201;
 
 
 { unit flags }
 { unit flags }
   uf_init                = $000001; { unit has initialization section }
   uf_init                = $000001; { unit has initialization section }

+ 8 - 4
compiler/symsym.pas

@@ -172,11 +172,13 @@ interface
           varspez       : tvarspez;  { sets the type of access }
           varspez       : tvarspez;  { sets the type of access }
           varregable    : tvarregable;
           varregable    : tvarregable;
           varstate      : tvarstate;
           varstate      : tvarstate;
-          { Has the address of this variable potentially escaped the }
-          { block in which is was declared?                          }
-          { could also be part of tabstractnormalvarsym, but there's }
-          { one byte left here till the next 4 byte alignment        }
+          { Has the address of this variable potentially escaped the
+            block in which is was declared?
+            could also be part of tabstractnormalvarsym, but there's
+            one byte left here till the next 4 byte alignment        }
           addr_taken     : boolean;
           addr_taken     : boolean;
+          { true if the variable is accessed in a different scope }
+          different_scope  : boolean;
           constructor create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions;doregister:boolean);
           constructor create(st:tsymtyp;const n : string;vsp:tvarspez;def:tdef;vopts:tvaroptions;doregister:boolean);
           constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
           constructor ppuload(st:tsymtyp;ppufile:tcompilerppufile);
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
@@ -1601,6 +1603,7 @@ implementation
          varspez:=tvarspez(ppufile.getbyte);
          varspez:=tvarspez(ppufile.getbyte);
          varregable:=tvarregable(ppufile.getbyte);
          varregable:=tvarregable(ppufile.getbyte);
          addr_taken:=ppufile.getboolean;
          addr_taken:=ppufile.getboolean;
+         different_scope:=ppufile.getboolean;
          ppufile.getderef(vardefderef);
          ppufile.getderef(vardefderef);
          ppufile.getsmallset(varoptions);
          ppufile.getsmallset(varoptions);
       end;
       end;
@@ -1633,6 +1636,7 @@ implementation
          ppufile.do_crc:=false;
          ppufile.do_crc:=false;
          ppufile.putbyte(byte(varregable));
          ppufile.putbyte(byte(varregable));
          ppufile.putboolean(addr_taken);
          ppufile.putboolean(addr_taken);
+         ppufile.putboolean(different_scope);
          ppufile.do_crc:=oldintfcrc;
          ppufile.do_crc:=oldintfcrc;
          ppufile.putderef(vardefderef);
          ppufile.putderef(vardefderef);
          ppufile.putsmallset(varoptions);
          ppufile.putsmallset(varoptions);

+ 1 - 0
compiler/utils/ppuutils/ppudump.pp

@@ -2117,6 +2117,7 @@ begin
   writeln([space,'         Spez : ',Varspez2Str(i)]);
   writeln([space,'         Spez : ',Varspez2Str(i)]);
   writeln([space,'      Regable : ',Varregable2Str(ppufile.getbyte)]);
   writeln([space,'      Regable : ',Varregable2Str(ppufile.getbyte)]);
   writeln([space,'   Addr Taken : ',(ppufile.getbyte<>0)]);
   writeln([space,'   Addr Taken : ',(ppufile.getbyte<>0)]);
+  writeln([space,'Escaped Scope : ',(ppufile.getbyte<>0)]);
   write  ([space,'     Var Type : ']);
   write  ([space,'     Var Type : ']);
   if VarDef <> nil then
   if VarDef <> nil then
     readderef('',VarDef.VarType)
     readderef('',VarDef.VarType)

+ 22 - 0
tests/test/cg/tfor2.pp

@@ -0,0 +1,22 @@
+{ %OPT=-O3 }
+program LoopUnrollTest;
+procedure Test;
+var
+   I: Integer;
+   procedure Test2;
+   begin
+     if I<>1 then
+       halt(1)
+     else
+       begin
+         writeln('ok');
+         halt(0);
+       end;
+   end;
+begin
+   for I := 1 to 10 do
+     Test2;
+end;
+begin
+   Test;
+end.