summaryrefslogtreecommitdiff
path: root/compiler/optcse.pas
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optcse.pas')
-rw-r--r--compiler/optcse.pas79
1 files changed, 79 insertions, 0 deletions
diff --git a/compiler/optcse.pas b/compiler/optcse.pas
new file mode 100644
index 0000000000..9eaecd8290
--- /dev/null
+++ b/compiler/optcse.pas
@@ -0,0 +1,79 @@
+{
+ Common subexpression elimination on base blocks
+
+ Copyright (c) 2005 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 optcse;
+
+{$i fpcdefs.inc}
+
+ interface
+
+ procedure docse(rootnode : tnode);
+
+ implementation
+
+ procedure docse(rootnode : tnode);
+ begin
+ { create a linear list of nodes }
+
+ { create hash values }
+
+ { sort by hash values, taking care of nf_csebarrier and keeping the
+ original order of the nodes }
+
+ { compare nodes with equal hash values }
+
+ { search barrier }
+ for i:=0 to nodelist.length-1 do
+ begin
+ { and then search backward so we get always the largest equal trees }
+ j:=i+1;
+ { collect equal nodes }
+ while (j<=nodelist.length-1) and
+ nodelist[i].docompare(nodelist[j]) do
+ inc(j);
+ dec(j);
+ if j>i then
+ begin
+ { cse found }
+
+ { create temp. location }
+
+ { replace first node by
+ - temp. creation
+ - expression calculation
+ - assignment of expression to temp. }
+ tempnode:=ctempcreatenode.create(nodelist[i].resulttype,nodelist[i].resulttype.def.size,tt_persistent,
+ nodelist[i].resulttype.def.is_intregable or nodelist[i].resulttype.def.is_fpuregable);
+ addstatement(createstatement,tempnode);
+ addstatement(createstatement,cassignmentnode.create(ctemprefnode.create(tempnode),
+ caddrnode.create_internal(para.left)));
+ para.left := ctypeconvnode.create_internal(cderefnode.create(ctemprefnode.create(tempnode)),para.left.resulttype);
+ addstatement(deletestatement,ctempdeletenode.create(tempnode));
+
+ { replace next nodes by loading the temp. reference }
+
+ { replace last node by loading the temp. reference and
+ delete the temp. }
+ end;
+ end;
+ end;
+
+end.