From 87bdf13f9fe0c6d1ac6cb4f47d6e3ea2e345cce9 Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 5 May 2007 20:50:09 +0000 Subject: [PATCH] + first draft for dfa git-svn-id: trunk@7282 - --- .gitattributes | 2 + compiler/node.pas | 6 ++ compiler/optdfa.pas | 99 ++++++++++++++++++++++++++++++++ compiler/optutils.pas | 129 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 236 insertions(+) create mode 100644 compiler/optdfa.pas create mode 100644 compiler/optutils.pas diff --git a/.gitattributes b/.gitattributes index 2d683e5996..54ee0be2ed 100644 --- a/.gitattributes +++ b/.gitattributes @@ -279,9 +279,11 @@ compiler/oglx.pas svneol=native#text/plain compiler/ogmap.pas svneol=native#text/plain compiler/optbase.pas svneol=native#text/plain compiler/optcse.pas svneol=native#text/plain +compiler/optdfa.pas svneol=native#text/plain compiler/options.pas svneol=native#text/plain compiler/opttail.pas svneol=native#text/plain compiler/optunrol.pas svneol=native#text/plain +compiler/optutils.pas svneol=native#text/plain compiler/owar.pas svneol=native#text/plain compiler/owbase.pas svneol=native#text/plain compiler/parabase.pas svneol=native#text/plain diff --git a/compiler/node.pas b/compiler/node.pas index eb40b2097a..cb25f4724d 100644 --- a/compiler/node.pas +++ b/compiler/node.pas @@ -278,6 +278,12 @@ interface { the parent node of this is node } { this field is set by concattolist } parent : tnode; + { next node in control flow on the same block level, i.e. + for loop nodes, this is the next node after the end of the loop, + same for if and case, if this field is nil, the next node is the procedure exit, + for the last node in a loop this is set to the loop header + this field is set only for control flow nodes } + successor : tnode; { there are some properties about the node stored } flags : tnodeflags; ppuidx : longint; diff --git a/compiler/optdfa.pas b/compiler/optdfa.pas new file mode 100644 index 0000000000..cef19c4341 --- /dev/null +++ b/compiler/optdfa.pas @@ -0,0 +1,99 @@ +{ + DFA + + 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 optdfa; + +{$i fpcdefs.inc} + + interface + + uses + node; + + procedure createoptinfo(node : tnode); + + implementation + + uses + globtype,globals, + cpuinfo, + nutils, + nbas,nflw,ncon,ninl,ncal, + optutils; + + + function initnodes(var n:tnode; arg: pointer) : foreachnoderesult; + begin + { node worth to add? } + if (node_complexity(n)>1) and (tstoreddef(n.resultdef).is_intregable or tstoreddef(n.resultdef).is_fpuregable) then + begin + plists(arg)^.nodelist.Add(n); + plists(arg)^.locationlist.Add(@n); + result:=fen_false; + end + else + result:=fen_norecurse_false; + end; + + + + + { + x:=f; read: [f] + + while x do read: [] + + a:=b; read: [a,b,d] def: [a] life: read*def=[a] + c:=d; read: [a,d] def: [a,c] life: read*def=[a] + e:=a; read: [a] def: [a,c,e] life: read*def=[a] + + + function f(b,d,x : type) : type; + + begin + while x do alive: b,d,x + begin + a:=b; alive: b,d,x + c:=d; alive: a,d,x + e:=a+c; alive: a,c,x + dec(x); alive: c,e,x + end; + result:=c+e; alive: c,e + end; alive: result + + } + + type + tdfainfo = record + definitionlist : tfplist; + lifelist : tfplist; + end; + + procedure createdfainfo(node : tnode); + begin + { first, add controll flow information } + SetNodeSucessors(node); + { now, collect life information } + + end; + + +end. diff --git a/compiler/optutils.pas b/compiler/optutils.pas new file mode 100644 index 0000000000..d8c267ffc1 --- /dev/null +++ b/compiler/optutils.pas @@ -0,0 +1,129 @@ +{ + Helper routines for the optimizer + + 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 optutils; + +{$i fpcdefs.inc} + + interface + + uses + node; + + procedure SetNodeSucessors(p : tnode); + + implementation + + uses + nbas,nflw; + + procedure SetNodeSucessors(p : tnode); + var + Continuestack : TFPList; + Breakstack : TFPList; + { sets the successor nodes of a node tree block + returns the first node of the tree if it's a controll flow node } + function DoSet(p : tnode;succ : tnode) : tnode; + var + hp1,hp2 : tnode; + begin + result:=nil; + case p.nodetype of + statementn: + begin + hp1:=p; + result:=p; + while assigned(hp1) do + begin + if assigned(tstatementnode(hp1).right) then + begin + hp2:=DoSet(tstatementnode(hp1).statement,tstatementnode(hp1).next); + if assigned(hp2) then + tstatementnode(hp1).successor:=hp2 + else + tstatementnode(hp1).successor:=tstatementnode(hp1).right; + end + else + begin + hp2:=DoSet(tstatementnode(hp1).statement,successor); + if assigned(hp2) then + tstatementnode(hp1).successor:=hp2 + else + tstatementnode(hp1).successor:=successor; + end; + end; + end; + blockn: + begin + result:=DoSet(tblocknode(p).statements,successor); + end; + forn: + begin + Breakstack.Add(successor); + Continuestack.Add(p); + result:=p; + DoSet(tfornode(p).statements,successor); + Breakstack.Delete(Count-1); + Continuestack.Delete(Count-1); + end; + breakn: + begin + result:=p; + p.successor:=tnode(Breakstack.Last); + end; + continuen: + begin + result:=p; + p.successor:=tnode(Continuestack.Last); + end; + { exit is actually a jump to some final. code + exitn: + begin + result:=p; + p.successor:=nil; + end; + } + ifn, + whilerepeatn, + exitn, + withn, + casen, + labeln, + goton, + tryexceptn, + raisen, + tryfinallyn, + onn, + nothingn: + internalerror(2007050501); + end; + end; + + begin + Breakstack:=TFPList.Create; + Continuestack:=TFPList.Create; + DoSet(p,nil); + Continuestack.Free; + Breakstack.Free; + end; + +end. +