| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 | {    Basic node optimizer stuff    Copyright (c) 2007 by Florian Klaempfl    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ****************************************************************************}unit optbase;{$i fpcdefs.inc}  interface    uses      globtype;    type      { this should maybe replaced by a spare set,        using a dyn. array makes assignments cheap }      tdfaset = array of byte;      PDFASet = ^TDFASet;      toptinfo = record        { index of the current node inside the dfa sets, aword(-1) if no entry }        index : aword;        { dfa }        def : tdfaset;        use : tdfaset;        life : tdfaset;        { all definitions made by this node and its children }        defsum : tdfaset;        { all used nodes by this node and its children }        usesum : tdfaset;        avail : tdfaset;        { estimation, how often the node is executed per subroutine call times 100, calculated by optutils.CalcExecutionWeight }        executionweight : longint;      end;      poptinfo = ^toptinfo;    { basic set operations for dfa sets }    { add e to s }    procedure DFASetInclude(var s : tdfaset;e : integer);    { add s to d }    procedure DFASetIncludeSet(var d : tdfaset;const s : tdfaset);    { remove s to d }    procedure DFASetExcludeSet(var d : tdfaset;const s : tdfaset);    { remove e from s }    procedure DFASetExclude(var s : tdfaset;e : integer);    { test if s contains e }    function DFASetIn(const s : tdfaset;e : integer) : boolean;    { d:=s1+s2; }    procedure DFASetUnion(var d : tdfaset;const s1,s2 : tdfaset);    { d:=s1*s2; }    procedure DFASetIntersect(var d : tdfaset;const s1,s2 : tdfaset);    { d:=s1-s2; }    procedure DFASetDiff(var d : tdfaset;const s1,s2 : tdfaset);    { s1<>s2; }    function DFASetNotEqual(const s1,s2 : tdfaset) : boolean;    { output DFA set }    procedure PrintDFASet(var f : text;s : TDFASet);  implementation    uses      cutils;    procedure DFASetInclude(var s : tdfaset;e : integer);      var        e8 : Integer;      begin        e8:=e div 8;        if e8>high(s) then          SetLength(s,e8+1);        s[e8]:=s[e8] or (1 shl (e mod 8));      end;    procedure DFASetIncludeSet(var d : tdfaset;const s : tdfaset);      var        i : integer;      begin        if length(s)>length(d) then          SetLength(d,length(s));        for i:=0 to high(s) do          d[i]:=d[i] or s[i];      end;    procedure DFASetExcludeSet(var d : tdfaset;const s : tdfaset);      var        i : integer;      begin        if length(s)>length(d) then          SetLength(d,length(s));        for i:=0 to high(s) do          d[i]:=d[i] and not(s[i]);      end;    procedure DFASetExclude(var s : tdfaset;e : integer);      var        e8 : Integer;      begin        e8:=e div 8;        if e8<=high(s) then          s[e8]:=s[e8] and not(1 shl (e mod 8));      end;    function DFASetIn(const s : tdfaset;e : integer) : boolean;      var        e8 : Integer;      begin        e8:=e div 8;        if e8<=high(s) then          result:=(s[e8] and (1 shl (e mod 8)))<>0        else          result:=false;      end;    procedure DFASetUnion(var d : tdfaset;const s1,s2 : tdfaset);      var        i : integer;      begin        SetLength(d,max(Length(s1),Length(s2)));        for i:=0 to min(high(s1),high(s2)) do          d[i]:=s1[i] or s2[i];        if high(s1)<high(s2) then          for i:=high(s1)+1 to high(s2) do            d[i]:=s2[i]        else          for i:=high(s2)+1 to high(s1) do            d[i]:=s1[i];      end;    procedure DFASetIntersect(var d : tdfaset;const s1,s2 : tdfaset);      var        i : integer;      begin        SetLength(d,min(Length(s1),Length(s2)));        for i:=0 to high(d) do          d[i]:=s1[i] and s2[i];      end;    procedure DFASetDiff(var d : tdfaset;const s1,s2 : tdfaset);      var        i : integer;      begin        SetLength(d,length(s1));        for i:=0 to high(d) do          if i>high(s2) then            d[i]:=s1[i]          else            d[i]:=s1[i] and not(s2[i]);      end;    function DFASetNotEqual(const s1,s2 : tdfaset) : boolean;      var        i : integer;      begin        result:=true;        { one set could be larger than the other }        if length(s1)>length(s2) then          begin            for i:=0 to high(s2) do              if s1[i]<>s2[i] then                exit;            { check remaining part being zero }            for i:=length(s2) to high(s1) do              if s1[i]<>0 then                exit;          end        else          begin            for i:=0 to high(s1) do              if s1[i]<>s2[i] then                exit;            { check remaining part being zero }            for i:=length(s1) to high(s2) do              if s2[i]<>0 then                exit;          end;        result:=false;      end;    procedure PrintDFASet(var f : text;s : TDFASet);      var        i : integer;        first : boolean;      begin        first:=true;        for i:=0 to Length(s)*8 do          begin            if DFASetIn(s,i) then              begin                if not(first) then                  write(f,',');                write(f,i);                first:=false;              end;          end;      end;end.
 |