optdeadstore.pas 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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. procinfo,pass_1,
  28. nutils,
  29. nbas,nld,
  30. optbase,
  31. symsym,symconst;
  32. function deadstoreelim(var n: tnode; arg: pointer): foreachnoderesult;
  33. var
  34. a: tassignmentnode;
  35. redundant: boolean;
  36. begin
  37. result:=fen_true;
  38. if (n.nodetype=statementn) and
  39. assigned(tstatementnode(n).statement) then
  40. begin
  41. if tstatementnode(n).statement.nodetype=assignn then
  42. begin
  43. a:=tassignmentnode(tstatementnode(n).statement);
  44. { we need to have dfa for the node }
  45. if assigned(a.left.optinfo) and
  46. (a.left.optinfo^.index<>aword(-1)) and
  47. { node must be either a local or parameter load node }
  48. (a.left.nodetype=loadn) and
  49. { its address cannot have escaped the current routine }
  50. not(tabstractvarsym(tloadnode(a.left).symtableentry).addr_taken) and
  51. ((
  52. (tloadnode(a.left).symtableentry.typ=localvarsym) and
  53. (tloadnode(a.left).symtable=current_procinfo.procdef.localst)) or
  54. ((tloadnode(a.left).symtableentry.typ=paravarsym) and
  55. (tloadnode(a.left).symtable=current_procinfo.procdef.parast) and
  56. (tparavarsym(tloadnode(a.left).symtableentry).varspez in [vs_const,vs_value])) or
  57. ((tloadnode(a.left).symtableentry.typ=staticvarsym) and
  58. (tloadnode(a.left).symtable.symtabletype=staticsymtable) and
  59. (current_procinfo.procdef.proctypeoption<>potype_unitinit)
  60. )
  61. ) and
  62. ((a.right.nodetype in [niln,stringconstn,pointerconstn,setconstn,guidconstn]) or
  63. ((a.right.nodetype=ordconstn) and not(cs_check_range in current_settings.localswitches)) or
  64. ((a.right.nodetype=realconstn) and not(cs_ieee_errors in current_settings.localswitches)) or
  65. ((cs_opt_dead_values in current_settings.optimizerswitches) and not(might_have_sideeffects(a.right)))
  66. ) then
  67. begin
  68. redundant:=not(assigned(a.successor)) or not(DFASetIn(a.successor.optinfo^.life,a.left.optinfo^.index));
  69. if redundant then
  70. begin
  71. {$ifdef DEBUG_DEADSTORE}
  72. writeln('************************** Redundant write *********************************');
  73. printnode(a);
  74. writeln('****************************************************************************');
  75. {$endif DEBUG_DEADSTORE}
  76. pboolean(arg)^:=true;
  77. tstatementnode(n).statement.free;
  78. tstatementnode(n).statement:=cnothingnode.create;
  79. Exclude(tstatementnode(n).flags, nf_pass1_done);
  80. do_firstpass(n);
  81. end
  82. end;
  83. end;
  84. end;
  85. end;
  86. function do_optdeadstoreelim(var rootnode: tnode): tnode;
  87. var
  88. changed: boolean;
  89. begin
  90. if not(pi_dfaavailable in current_procinfo.flags) then
  91. internalerror(2013110201);
  92. if not current_procinfo.has_nestedprocs then
  93. begin
  94. changed:=false;
  95. foreachnodestatic(pm_postprocess, rootnode, @deadstoreelim, @changed);
  96. end;
  97. result:=rootnode;
  98. end;
  99. end.