123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- {
- 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,globals,
- procinfo,pass_1,
- nutils,
- nbas,nld,
- 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
- { its address cannot have escaped the current routine }
- not(tabstractvarsym(tloadnode(a.left).symtableentry).addr_taken) and
- ((
- (tloadnode(a.left).symtableentry.typ=localvarsym) and
- (tloadnode(a.left).symtable=current_procinfo.procdef.localst)) or
- ((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])) or
- ((tloadnode(a.left).symtableentry.typ=staticvarsym) and
- (tloadnode(a.left).symtable.symtabletype=staticsymtable) and
- (current_procinfo.procdef.proctypeoption<>potype_unitinit)
- )
- ) and
- ((a.right.nodetype in [niln,stringconstn,pointerconstn,setconstn,guidconstn]) or
- ((a.right.nodetype=ordconstn) and not(cs_check_range in current_settings.localswitches)) or
- ((a.right.nodetype=realconstn) and not(cs_ieee_errors in current_settings.localswitches)) or
- ((cs_opt_dead_values in current_settings.optimizerswitches) 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.
|