diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-11-06 21:10:26 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-11-06 21:10:26 +0000 |
commit | 49a5e4e6e433dc206e05833d83d5edb41fe0ddec (patch) | |
tree | aca3ace20664b5d8ae7d5d451dbae001eeaa2c73 /compiler | |
parent | 82e39ee84eea94b94b302fcc340470a230802b0f (diff) | |
download | fpc-49a5e4e6e433dc206e05833d83d5edb41fe0ddec.tar.gz |
+ dead store elimination, based on a patch by Jeppe Johansen
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@25962 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/globtype.pas | 6 | ||||
-rw-r--r-- | compiler/optdeadstore.pas | 112 | ||||
-rw-r--r-- | compiler/psub.pas | 8 |
3 files changed, 122 insertions, 4 deletions
diff --git a/compiler/globtype.pas b/compiler/globtype.pas index 4fdee35095..6af3bb93a8 100644 --- a/compiler/globtype.pas +++ b/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' diff --git a/compiler/optdeadstore.pas b/compiler/optdeadstore.pas new file mode 100644 index 0000000000..c216dc6b70 --- /dev/null +++ b/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. + diff --git a/compiler/psub.pas b/compiler/psub.pas index cff7e15312..e09701c8d2 100644 --- a/compiler/psub.pas +++ b/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 } |