optdeadstore.pas 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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,
  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. (tloadnode(a.left).symtableentry.typ=localvarsym) and
  51. (tloadnode(a.left).symtable=current_procinfo.procdef.localst)) or
  52. ((a.left.nodetype=loadn) and
  53. (tloadnode(a.left).symtableentry.typ=paravarsym) and
  54. (tloadnode(a.left).symtable=current_procinfo.procdef.parast) and
  55. (tparavarsym(tloadnode(a.left).symtableentry).varspez in [vs_const,vs_value]))
  56. ) and
  57. not(might_have_sideeffects(a.right)) then
  58. begin
  59. redundant:=not(assigned(a.successor)) or not(DFASetIn(a.successor.optinfo^.life,a.left.optinfo^.index));
  60. if redundant then
  61. begin
  62. {$ifdef DEBUG_DEADSTORE}
  63. writeln('************************** Redundant write *********************************');
  64. printnode(a);
  65. writeln('****************************************************************************');
  66. {$endif DEBUG_DEADSTORE}
  67. pboolean(arg)^:=true;
  68. tstatementnode(n).statement.free;
  69. tstatementnode(n).statement:=cnothingnode.create;
  70. Exclude(tstatementnode(n).flags, nf_pass1_done);
  71. do_firstpass(n);
  72. end
  73. end;
  74. end;
  75. end;
  76. end;
  77. function do_optdeadstoreelim(var rootnode: tnode): tnode;
  78. var
  79. changed: boolean;
  80. begin
  81. if not(pi_dfaavailable in current_procinfo.flags) then
  82. internalerror(2013110201);
  83. if not current_procinfo.has_nestedprocs then
  84. begin
  85. changed:=false;
  86. foreachnodestatic(pm_postprocess, rootnode, @deadstoreelim, @changed);
  87. end;
  88. result:=rootnode;
  89. end;
  90. end.