aoptbase.pas 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. {
  2. $Id$
  3. Copyright (c) 1999 by Jonas Maebe, member of the Free Pascal
  4. Development Team
  5. This unit contains the base of all optimizer related objects
  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 aoptbase;
  20. Interface
  21. uses aasm, cpubase, cpuasm;
  22. { the number of Pai objects processed by an optimizer object since the last }
  23. { time a register was modified }
  24. Type TInstrSinceLastMod = Array[LoGPReg..HiGPReg] of byte;
  25. { the TAopBase object implements the basic methods that most other }
  26. { assembler optimizer objects require }
  27. Type
  28. TAoptBase = Object
  29. { processor independent methods }
  30. { returns true if register Reg is used by instruction p1 }
  31. Function RegInInstruction(Reg: TRegister; p1: Pai): Boolean;
  32. { returns true if register Reg occurs in operand op }
  33. Function RegInOp(Reg: TRegister; const op: toper): Boolean;
  34. { returns true if register Reg is used in the reference Ref }
  35. Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
  36. { returns true if the references are completely equal }
  37. Function RefsEqual(Const R1, R2: TReference): Boolean;
  38. { gets the next Pai object after current that contains info relevant }
  39. { to the optimizer in p1. If there is none, it returns false and }
  40. { sets p1 to nil }
  41. Function GetNextInstruction(Current: Pai; Var Next: Pai): Boolean;
  42. { gets the previous Pai object after current that contains info }
  43. { relevant to the optimizer in last. If there is none, it retuns }
  44. { false and sets last to nil }
  45. Function GetLastInstruction(Current: Pai; Var Last: Pai): Boolean;
  46. { processor dependent methods }
  47. { returns the maximum width component of Reg. Only has to be }
  48. { overridden for the 80x86 (afaik) }
  49. Function RegMaxSize(Reg: TRegister): TRegister; Virtual;
  50. { returns true if Reg1 and Reg2 are of the samae width. Only has to }
  51. { overridden for the 80x86 (afaik) }
  52. Function RegsSameSize(Reg1, Reg2: TRegister): Boolean; Virtual;
  53. { returns whether P is a load instruction (load contents from a }
  54. { memory location or (register) variable into a register) }
  55. Function IsLoadMemReg(p: pai): Boolean; Virtual;
  56. { returns whether P is a load constant instruction (load a constant }
  57. { into a register) }
  58. Function IsLoadConstReg(p: pai): Boolean;
  59. { returns whether P is a store instruction (store contents from a }
  60. { register to a memory location or to a (register) variable) }
  61. Function IsStoreRegMem(p: pai): Boolean; Virtual;
  62. end;
  63. Implementation
  64. uses globals, aoptcpub, cpuinfo;
  65. Function TAOptBase.RegInInstruction(Reg: TRegister; p1: Pai): Boolean;
  66. Var Count: AWord;
  67. TmpResult: Boolean;
  68. Begin
  69. TmpResult := False;
  70. Count := 0;
  71. If (p1^.typ = ait_instruction) Then
  72. Repeat
  73. TmpResult := RegInOp(Reg, PInstr(p1)^.oper[Count]);
  74. Inc(Count)
  75. Until (Count = MaxOps) or TmpResult;
  76. RegInInstruction := TmpResult
  77. End;
  78. Function TAOptBase.RegInOp(Reg: TRegister; const op: toper): Boolean;
  79. Begin
  80. Case op.typ Of
  81. Top_Reg: RegInOp := Reg = op.reg;
  82. Top_Ref: RegInOp := RegInRef(Reg, op.ref^)
  83. Else RegInOp := False
  84. End
  85. End;
  86. Function TAOptBase.RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
  87. Begin
  88. Reg := RegMaxSize(Reg);
  89. RegInRef := (Ref.Base = Reg)
  90. {$ifdef RefsHaveIndexReg}
  91. Or (Ref.Index = Reg)
  92. {$endif RefsHaveIndexReg}
  93. End;
  94. Function TAOptBase.RefsEqual(Const R1, R2: TReference): Boolean;
  95. Begin
  96. If R1.is_immediate Then
  97. RefsEqual := R2.is_immediate and (R1.Offset = R2.Offset)
  98. Else
  99. RefsEqual := (R1.Offset+R1.OffsetFixup = R2.Offset+R2.OffsetFixup)
  100. And (R1.Base = R2.Base)
  101. {$ifdef RefsHaveindex}
  102. And (R1.Index = R2.Index)
  103. {$endif RefsHaveindex}
  104. {$ifdef RefsHaveScale}
  105. And (R1.ScaleFactor = R2.ScaleFactor)
  106. {$endif RefsHaveScale}
  107. And (R1.Symbol = R2.Symbol)
  108. {$ifdef RefsHaveSegment}
  109. And (R1.Segment = R2.Segment)
  110. {$endif RefsHaveSegment}
  111. End;
  112. Function TAOptBase.GetNextInstruction(Current: Pai; Var Next: Pai): Boolean;
  113. Begin
  114. Repeat
  115. Current := Pai(Current^.Next);
  116. While Assigned(Current) And
  117. ((Current^.typ In SkipInstr) or
  118. ((Current^.typ = ait_label) And
  119. Not(Pai_Label(Current)^.l^.is_used))) Do
  120. Current := Pai(Current^.Next);
  121. If Assigned(Current) And
  122. (Current^.typ = ait_Marker) And
  123. (Pai_Marker(Current)^.Kind = NoPropInfoStart) Then
  124. Begin
  125. While Assigned(Current) And
  126. ((Current^.typ <> ait_Marker) Or
  127. (Pai_Marker(Current)^.Kind <> NoPropInfoEnd)) Do
  128. Current := Pai(Current^.Next);
  129. End;
  130. Until Not(Assigned(Current)) Or
  131. (Current^.typ <> ait_Marker) Or
  132. (Pai_Marker(Current)^.Kind <> NoPropInfoEnd);
  133. Next := Current;
  134. If Assigned(Current) And
  135. Not((Current^.typ In SkipInstr) or
  136. ((Current^.typ = ait_label) And
  137. Not(Pai_Label(Current)^.l^.is_used)))
  138. Then GetNextInstruction := True
  139. Else
  140. Begin
  141. Next := Nil;
  142. GetNextInstruction := False;
  143. End;
  144. End;
  145. Function TAOptBase.GetLastInstruction(Current: Pai; Var Last: Pai): Boolean;
  146. Begin
  147. Repeat
  148. Current := Pai(Current^.previous);
  149. While Assigned(Current) And
  150. (((Current^.typ = ait_Marker) And
  151. Not(Pai_Marker(Current)^.Kind in [AsmBlockEnd,NoPropInfoEnd])) or
  152. (Current^.typ In SkipInstr) or
  153. ((Current^.typ = ait_label) And
  154. Not(Pai_Label(Current)^.l^.is_used))) Do
  155. Current := Pai(Current^.previous);
  156. If Assigned(Current) And
  157. (Current^.typ = ait_Marker) And
  158. (Pai_Marker(Current)^.Kind = NoPropInfoEnd) Then
  159. Begin
  160. While Assigned(Current) And
  161. ((Current^.typ <> ait_Marker) Or
  162. (Pai_Marker(Current)^.Kind <> NoPropInfoStart)) Do
  163. Current := Pai(Current^.previous);
  164. End;
  165. Until Not(Assigned(Current)) Or
  166. (Current^.typ <> ait_Marker) Or
  167. (Pai_Marker(Current)^.Kind <> NoPropInfoStart);
  168. If Not(Assigned(Current)) or
  169. (Current^.typ In SkipInstr) or
  170. ((Current^.typ = ait_label) And
  171. Not(Pai_Label(Current)^.l^.is_used)) or
  172. ((Current^.typ = ait_Marker) And
  173. (Pai_Marker(Current)^.Kind = AsmBlockEnd))
  174. Then
  175. Begin
  176. Last := Nil;
  177. GetLastInstruction := False
  178. End
  179. Else
  180. Begin
  181. Last := Current;
  182. GetLastInstruction := True;
  183. End;
  184. End;
  185. { ******************* Processor dependent stuff *************************** }
  186. Function TAOptBase.RegMaxSize(Reg: TRegister): TRegister;
  187. Begin
  188. RegMaxSize := Reg
  189. End;
  190. Function TAOptBase.RegsSameSize(Reg1, Reg2: TRegister): Boolean;
  191. Begin
  192. RegsSameSize := True
  193. End;
  194. Function TAOptBase.IsLoadMemReg(p: pai): Boolean;
  195. Begin
  196. Abstract
  197. End;
  198. Function TAOptBase.IsLoadConstReg(p: pai): Boolean;
  199. Begin
  200. Abstract
  201. End;
  202. Function TAOptBase.IsStoreRegMem(p: pai): Boolean;
  203. Begin
  204. Abstract
  205. End;
  206. End.
  207. {
  208. $Log$
  209. Revision 1.1 1999-08-18 14:32:21 jonas
  210. + compilable!
  211. + dataflow analyzer finished
  212. + start of CSE units
  213. + aoptbase which contains a base object for all optimizer objects
  214. * some constants and type definitions moved around to avoid circular
  215. dependencies
  216. * moved some methods from base objects to specialized objects because
  217. they're not used anywhere else
  218. }