mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-02 19:43:15 +01:00
+ dead store elimination, based on a patch by Jeppe Johansen
git-svn-id: trunk@25962 -
This commit is contained in:
parent
aef0841fe4
commit
1a4584f4c6
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -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
|
||||
|
||||
@ -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
compiler/optdeadstore.pas
Normal file
112
compiler/optdeadstore.pas
Normal file
@ -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.
|
||||
|
||||
@ -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 }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user