optdeadstore.pas 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. {
  2. Dead store elimination
  3. Copyright (c) 2005-2012 by Jeppe Johansen and Florian Klaempfl
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit optdeadstore;
  18. {$i fpcdefs.inc}
  19. { $define DEBUG_DEADSTORE}
  20. interface
  21. uses
  22. node;
  23. function do_optdeadstoreelim(var rootnode : tnode) : tnode;
  24. implementation
  25. uses
  26. verbose,globtype,globals,
  27. fmodule,
  28. procinfo,pass_1,
  29. nutils,
  30. nbas,nld,nmem,nflw,nset,
  31. optbase,
  32. symsym,symconst;
  33. function deadstoreelim(var n: tnode; arg: pointer): foreachnoderesult;
  34. var
  35. a: tassignmentnode;
  36. redundant: boolean;
  37. begin
  38. result:=fen_true;
  39. if (n.nodetype=statementn) and
  40. assigned(tstatementnode(n).statement) then
  41. begin
  42. if tstatementnode(n).statement.nodetype=assignn then
  43. begin
  44. a:=tassignmentnode(tstatementnode(n).statement);
  45. { we need to have dfa for the node }
  46. if assigned(a.left.optinfo) and
  47. (a.left.optinfo^.index<>aword(-1)) and
  48. { node must be either a local or parameter load node }
  49. (a.left.nodetype=loadn) and
  50. { its address cannot have escaped the current routine }
  51. not(tabstractvarsym(tloadnode(a.left).symtableentry).addr_taken) and
  52. ((
  53. (tloadnode(a.left).symtableentry.typ=localvarsym) and
  54. (tloadnode(a.left).symtable=current_procinfo.procdef.localst)) or
  55. ((tloadnode(a.left).symtableentry.typ=paravarsym) and
  56. (tloadnode(a.left).symtable=current_procinfo.procdef.parast) and
  57. (tparavarsym(tloadnode(a.left).symtableentry).varspez in [vs_const,vs_value])) or
  58. ((tloadnode(a.left).symtableentry.typ=staticvarsym) and
  59. (tloadnode(a.left).symtable.symtabletype=staticsymtable) and
  60. (current_procinfo.procdef.proctypeoption<>potype_unitinit)
  61. )
  62. ) and
  63. ((a.right.nodetype in [niln,stringconstn,pointerconstn,setconstn,guidconstn]) or
  64. ((a.right.nodetype=ordconstn) and not(cs_check_range in current_settings.localswitches)) or
  65. ((a.right.nodetype=realconstn) and not(cs_ieee_errors in current_settings.localswitches)) or
  66. ((cs_opt_dead_values in current_settings.optimizerswitches) and not(might_have_sideeffects(a.right)))
  67. ) then
  68. begin
  69. redundant:=not(assigned(a.successor)) or not(DFASetIn(a.successor.optinfo^.life,a.left.optinfo^.index));
  70. if redundant then
  71. begin
  72. {$ifdef DEBUG_DEADSTORE}
  73. writeln('************************** Redundant write *********************************');
  74. printnode(a);
  75. writeln('****************************************************************************');
  76. {$endif DEBUG_DEADSTORE}
  77. pboolean(arg)^:=true;
  78. tstatementnode(n).statement.free;
  79. tstatementnode(n).statement:=cnothingnode.create;
  80. Exclude(tstatementnode(n).flags, nf_pass1_done);
  81. do_firstpass(n);
  82. end
  83. end;
  84. end;
  85. end;
  86. end;
  87. function do_optdeadstoreelim(var rootnode: tnode): tnode;
  88. var
  89. changed: boolean;
  90. begin
  91. if not(pi_dfaavailable in current_procinfo.flags) then
  92. internalerror(2013110201);
  93. if not current_procinfo.has_nestedprocs then
  94. begin
  95. changed:=false;
  96. foreachnodestatic(pm_postprocess, rootnode, @deadstoreelim, @changed);
  97. end;
  98. result:=rootnode;
  99. end;
  100. end.