Browse Source

+ dead store elimination, based on a patch by Jeppe Johansen

git-svn-id: trunk@25962 -
florian 11 years ago
parent
commit
1a4584f4c6
4 changed files with 123 additions and 4 deletions
  1. 1 0
      .gitattributes
  2. 4 2
      compiler/globtype.pas
  3. 112 0
      compiler/optdeadstore.pas
  4. 6 2
      compiler/psub.pas

+ 1 - 0
.gitattributes

@@ -461,6 +461,7 @@ compiler/optbase.pas svneol=native#text/plain
 compiler/optconstprop.pas svneol=native#text/pascal
 compiler/optcse.pas svneol=native#text/plain
 compiler/optdead.pas svneol=native#text/plain
+compiler/optdeadstore.pas svneol=native#text/pascal
 compiler/optdfa.pas svneol=native#text/plain
 compiler/options.pas svneol=native#text/plain
 compiler/optloop.pas svneol=native#text/plain

+ 4 - 2
compiler/globtype.pas

@@ -275,7 +275,8 @@ interface
          cs_opt_dead_values,
          { compiler checks for empty procedures/methods and removes calls to them if possible }
          cs_opt_remove_emtpy_proc,
-         cs_opt_constant_propagate
+         cs_opt_constant_propagate,
+         cs_opt_dead_store_eliminate
        );
        toptimizerswitches = set of toptimizerswitch;
 
@@ -309,7 +310,8 @@ interface
          'PEEPHOLE','ASMCSE','LOOPUNROLL','TAILREC','CSE',
          'DFA','STRENGTH','SCHEDULE','AUTOINLINE','USEEBP',
          'ORDERFIELDS','FASTMATH','DEADVALUES','REMOVEEMPTYPROCS',
-         'CONSTPROP'
+         'CONSTPROP',
+         'DEADSTORE'
        );
        WPOptimizerSwitchStr : array [twpoptimizerswitch] of string[14] = (
          'DEVIRTCALLS','OPTVMTS','SYMBOLLIVENESS'

+ 112 - 0
compiler/optdeadstore.pas

@@ -0,0 +1,112 @@
+{
+    Dead store elimination
+
+    Copyright (c) 2005-2012 by Jeppe Johansen and 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 optdeadstore;
+
+{$i fpcdefs.inc}
+
+{ $define DEBUG_DEADSTORE}
+
+  interface
+
+    uses
+      node;
+
+    function do_optdeadstoreelim(var rootnode : tnode) : tnode;
+
+  implementation
+
+    uses
+      verbose,globtype,
+      fmodule,
+      procinfo,pass_1,
+      nutils,
+      nbas,nld,nmem,nflw,nset,
+      optbase,
+      symsym,symconst;
+
+
+    function deadstoreelim(var n: tnode; arg: pointer): foreachnoderesult;
+      var
+        a: tassignmentnode;
+        redundant: boolean;
+      begin
+        result:=fen_true;
+        if (n.nodetype=statementn) and
+           assigned(tstatementnode(n).statement) then
+          begin
+            if tstatementnode(n).statement.nodetype=assignn then
+              begin
+                a:=tassignmentnode(tstatementnode(n).statement);
+
+                { we need to have dfa for the node }
+                if assigned(a.left.optinfo) and
+                   (a.left.optinfo^.index<>aword(-1)) and
+                   { node must be either a local or parameter load node }
+                   (((a.left.nodetype=loadn) and
+                     (tloadnode(a.left).symtableentry.typ=localvarsym) and
+                     (tloadnode(a.left).symtable=current_procinfo.procdef.localst)) or
+                    ((a.left.nodetype=loadn) and
+                     (tloadnode(a.left).symtableentry.typ=paravarsym) and
+                     (tloadnode(a.left).symtable=current_procinfo.procdef.parast) and
+                     (tparavarsym(tloadnode(a.left).symtableentry).varspez in [vs_const,vs_value]))
+                    ) and
+                    not(might_have_sideeffects(a.right)) then
+                  begin
+                    redundant:=not(assigned(a.successor)) or not(DFASetIn(a.successor.optinfo^.life,a.left.optinfo^.index));
+
+                    if redundant then
+                      begin
+{$ifdef DEBUG_DEADSTORE}
+                        writeln('************************** Redundant write *********************************');
+                        printnode(a);
+                        writeln('****************************************************************************');
+{$endif DEBUG_DEADSTORE}
+                        pboolean(arg)^:=true;
+
+                        tstatementnode(n).statement.free;
+
+                        tstatementnode(n).statement:=cnothingnode.create;
+                        Exclude(tstatementnode(n).flags, nf_pass1_done);
+                        do_firstpass(n);
+                      end
+                  end;
+              end;
+          end;
+      end;
+
+
+    function do_optdeadstoreelim(var rootnode: tnode): tnode;
+      var
+        changed: boolean;
+      begin
+        if not(pi_dfaavailable in current_procinfo.flags) then
+          internalerror(2013110201);
+        if not current_procinfo.has_nestedprocs then
+          begin
+            changed:=false;
+            foreachnodestatic(pm_postprocess, rootnode, @deadstoreelim, @changed);
+          end;
+        result:=rootnode;
+      end;
+
+end.
+

+ 6 - 2
compiler/psub.pas

@@ -115,7 +115,8 @@ implementation
        opttail,
        optcse,
        optloop,
-       optconstprop
+       optconstprop,
+       optdeadstore
 {$if defined(arm) or defined(avr) or defined(fpc_compiler_has_fixup_jmps)}
        ,aasmcpu
 {$endif arm}
@@ -1253,7 +1254,7 @@ implementation
           (pi_is_recursive in flags) then
           do_opttail(code,procdef);
 
-        if (cs_opt_constant_propagate in current_settings.optimizerswitches) then
+        if cs_opt_constant_propagate in current_settings.optimizerswitches then
           do_optconstpropagate(code);
 
         if (cs_opt_nodedfa in current_settings.optimizerswitches) and
@@ -1293,6 +1294,9 @@ implementation
             include(flags,pi_dfaavailable);
           end;
 
+        if (pi_dfaavailable in flags) and (cs_opt_dead_store_eliminate in current_settings.optimizerswitches) then
+          do_optdeadstoreelim(code);
+
         if (cs_opt_loopstrength in current_settings.optimizerswitches)
           { our induction variable strength reduction doesn't like
             for loops with more than one entry }