aopt386.pas 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. {
  2. $Id$
  3. Copyright (c) 1998-2000 by Jonas Maebe
  4. This unit calls the optimization procedures to optimize the assembler
  5. code for i386+
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. Unit aopt386;
  20. {$i defines.inc}
  21. Interface
  22. Uses
  23. aasm;
  24. Procedure Optimize(AsmL: TAasmOutput);
  25. Implementation
  26. Uses
  27. globtype,
  28. globals,
  29. DAOpt386,POpt386,CSOpt386;
  30. Procedure Optimize(AsmL: TAAsmOutput);
  31. Var
  32. BlockStart, BlockEnd, HP: Tai;
  33. pass: longint;
  34. slowopt, changed, lastLoop: boolean;
  35. Begin
  36. slowopt := (cs_slowoptimize in aktglobalswitches);
  37. pass := 0;
  38. changed := false;
  39. repeat
  40. lastLoop :=
  41. not(slowopt) or
  42. (not changed and (pass > 2)) or
  43. { prevent endless loops }
  44. (pass = 4);
  45. changed := false;
  46. { Setup labeltable, always necessary }
  47. BlockStart := Tai(AsmL.First);
  48. BlockEnd := DFAPass1(AsmL, BlockStart);
  49. { Blockend now either contains an ait_marker with Kind = AsmBlockStart, }
  50. { or nil }
  51. While Assigned(BlockStart) Do
  52. Begin
  53. if pass = 0 then
  54. PrePeepHoleOpts(AsmL, BlockStart, BlockEnd);
  55. { Peephole optimizations }
  56. PeepHoleOptPass1(AsmL, BlockStart, BlockEnd);
  57. { Only perform them twice in the first pass }
  58. if pass = 0 then
  59. PeepHoleOptPass1(AsmL, BlockStart, BlockEnd);
  60. { Data flow analyzer }
  61. If (cs_fastoptimize in aktglobalswitches) Then
  62. Begin
  63. If DFAPass2(
  64. {$ifdef statedebug}
  65. AsmL,
  66. {$endif statedebug}
  67. BlockStart, BlockEnd) Then
  68. { common subexpression elimination }
  69. changed := CSE(asmL, blockStart, blockEnd, pass) or changed;
  70. End;
  71. { More peephole optimizations }
  72. PeepHoleOptPass2(AsmL, BlockStart, BlockEnd);
  73. if lastLoop then
  74. PostPeepHoleOpts(AsmL, BlockStart, BlockEnd);
  75. { Dispose labeltabel }
  76. ShutDownDFA;
  77. { Continue where we left off, BlockEnd is either the start of an }
  78. { assembler block or nil }
  79. BlockStart := BlockEnd;
  80. While Assigned(BlockStart) And
  81. (BlockStart.typ = ait_Marker) And
  82. (Tai_Marker(BlockStart).Kind = AsmBlockStart) Do
  83. Begin
  84. { We stopped at an assembler block, so skip it }
  85. Repeat
  86. BlockStart := Tai(BlockStart.Next);
  87. Until (BlockStart.Typ = Ait_Marker) And
  88. (Tai_Marker(Blockstart).Kind = AsmBlockEnd);
  89. { Blockstart now contains a Tai_marker(asmblockend) }
  90. If GetNextInstruction(BlockStart, HP) And
  91. ((HP.typ <> ait_Marker) Or
  92. (Tai_Marker(HP).Kind <> AsmBlockStart)) Then
  93. { There is no assembler block anymore after the current one, so }
  94. { optimize the next block of "normal" instructions }
  95. BlockEnd := DFAPass1(AsmL, BlockStart)
  96. { Otherwise, skip the next assembler block }
  97. Else BlockStart := HP;
  98. End;
  99. End;
  100. inc(pass);
  101. until lastLoop;
  102. End;
  103. End.
  104. {
  105. $Log$
  106. Revision 1.3 2000-12-25 00:07:31 peter
  107. + new tlinkedlist class (merge of old tstringqueue,tcontainer and
  108. tlinkedlist objects)
  109. Revision 1.2 2000/10/24 10:40:53 jonas
  110. + register renaming ("fixes" bug1088)
  111. * changed command line options meanings for optimizer:
  112. O2 now means peepholopts, CSE and register renaming in 1 pass
  113. O3 is the same, but repeated until no further optimizations are
  114. possible or until 5 passes have been done (to avoid endless loops)
  115. * changed aopt386 so it does this looping
  116. * added some procedures from csopt386 to the interface because they're
  117. used by rropt386 as well
  118. * some changes to csopt386 and daopt386 so that newly added instructions
  119. by the CSE get optimizer info (they were simply skipped previously),
  120. this fixes some bugs
  121. Revision 1.1 2000/10/15 09:47:42 peter
  122. * moved to i386/
  123. Revision 1.5 2000/09/24 15:06:11 peter
  124. * use defines.inc
  125. Revision 1.4 2000/08/19 09:10:08 jonas
  126. * for all optimization levels > 1, all passes are done twice (the
  127. result improves the most if -Or is used as well)
  128. Revision 1.3 2000/07/14 05:11:48 michael
  129. + Patch to 1.1
  130. Revision 1.2 2000/07/13 11:32:31 michael
  131. + removed logs
  132. }