aopt.pas 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. Unit aopt;
  2. Interface
  3. Uses Aasm, cobjects, aoptmsc, aoptda, aoptcs, aoptpeep
  4. {$ifdef i386}
  5. , ao386msc;
  6. {$endif i386}
  7. Type
  8. TAsmOptimizer = Object
  9. { the PAasmOutput list this optimizer instance works on }
  10. AsmL: PAasmOutput;
  11. { The labeltable contains the addresses of the Pai objects that are labels }
  12. LabelInfo: PLabelInfo;
  13. { Start and end of the block that is currently being optimized, initialized }
  14. { by InitDFA }
  15. BlockStart, BlockEnd: Pai;
  16. { How many instructions are between the current instruction and the last one }
  17. { that modified the register }
  18. NrOfInstrSinceLastMod: TInstrSinceLastMod;
  19. { _AsmL is the PAasmOutpout list that has to be optimized }
  20. Constructor Init(_AsmL: PAasmOutput);
  21. { general, processor independent procedures }
  22. { general, processor dependent procedures }
  23. Implementation
  24. Constructor TAsmOptimizer.Init(_AsmL: PAasmOutput);
  25. Begin
  26. AsmL := _AsmL;
  27. End;
  28. Procedure Optimize;
  29. Var HP: Pai;
  30. AsmDFA: TAsmDFA;
  31. Begin
  32. {setup labeltable, always necessary}
  33. BlockStart := Pai(AsmL^.First);
  34. AsmDFA.Init(AsmL, BlockStart, BlockEnd);
  35. {Blockend now either contains an ait_marker with Kind = AsmBlockStart, or nil}
  36. While Assigned(BlockStart) Do
  37. Begin
  38. LabelInfo := AsmDFA.GetLabelInfo;
  39. { peephole optimizations, twice }
  40. PeepHoleOptPass1;
  41. PeepHoleOptPass1;
  42. If (cs_slowoptimize in aktglobalswitches) Then
  43. Begin
  44. { data flow analyzer }
  45. DFAPass2;
  46. { common subexpression elimination }
  47. CSE;
  48. End;
  49. { more peephole optimizations }
  50. PeepHoleOptPass2;
  51. {dispose labeltabel}
  52. AsmDFA.Done;
  53. {continue where we left off, BlockEnd is either the start of an assembler
  54. block or nil}
  55. BlockStart := BlockEnd;
  56. While Assigned(BlockStart) And
  57. (BlockStart^.typ = ait_Marker) And
  58. (Pai_Marker(BlockStart)^.Kind = AsmBlockStart) Do
  59. Begin
  60. {we stopped at an assembler block, so skip it}
  61. While GetNextInstruction(BlockStart, BlockStart) And
  62. ((BlockStart^.Typ <> Ait_Marker) Or
  63. (Pai_Marker(Blockstart)^.Kind <> AsmBlockEnd)) Do;
  64. {blockstart now contains a pai_marker(asmblockend)}
  65. If GetNextInstruction(BlockStart, HP) And
  66. ((HP^.typ <> ait_Marker) Or
  67. (Pai_Marker(HP)^.Kind <> AsmBlockStart)) Then
  68. {there is no assembler block anymore after the current one, so
  69. optimize the next block of "normal" instructions}
  70. AsmDFA.Init(AsmL, BlockStart, BlockEnd);
  71. {otherwise, skip the next assembler block}
  72. Else BlockStart := HP;
  73. End
  74. End;
  75. End;
  76. Destructor TAsmOptimizer.Done;
  77. Begin
  78. End;
  79. {Virtual methods, most have to be overridden by processor dependent methods}