aoptbase.pas 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  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. { create a PInstr Object that loads the contents of reg1 into reg2 }
  63. Function a_load_reg_reg(reg1, reg2: TRegister): PInstr; Virtual;
  64. end;
  65. Implementation
  66. uses globals, aoptcpub, cpuinfo;
  67. Function TAOptBase.RegInInstruction(Reg: TRegister; p1: Pai): Boolean;
  68. Var Count: AWord;
  69. TmpResult: Boolean;
  70. Begin
  71. TmpResult := False;
  72. Count := 0;
  73. If (p1^.typ = ait_instruction) Then
  74. Repeat
  75. TmpResult := RegInOp(Reg, PInstr(p1)^.oper[Count]);
  76. Inc(Count)
  77. Until (Count = MaxOps) or TmpResult;
  78. RegInInstruction := TmpResult
  79. End;
  80. Function TAOptBase.RegInOp(Reg: TRegister; const op: toper): Boolean;
  81. Begin
  82. Case op.typ Of
  83. Top_Reg: RegInOp := Reg = op.reg;
  84. Top_Ref: RegInOp := RegInRef(Reg, op.ref^)
  85. Else RegInOp := False
  86. End
  87. End;
  88. Function TAOptBase.RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
  89. Begin
  90. Reg := RegMaxSize(Reg);
  91. RegInRef := (Ref.Base = Reg)
  92. {$ifdef RefsHaveIndexReg}
  93. Or (Ref.Index = Reg)
  94. {$endif RefsHaveIndexReg}
  95. End;
  96. Function TAOptBase.RefsEqual(Const R1, R2: TReference): Boolean;
  97. Begin
  98. If R1.is_immediate Then
  99. RefsEqual := R2.is_immediate and (R1.Offset = R2.Offset)
  100. Else
  101. RefsEqual := (R1.Offset+R1.OffsetFixup = R2.Offset+R2.OffsetFixup)
  102. And (R1.Base = R2.Base)
  103. {$ifdef RefsHaveindex}
  104. And (R1.Index = R2.Index)
  105. {$endif RefsHaveindex}
  106. {$ifdef RefsHaveScale}
  107. And (R1.ScaleFactor = R2.ScaleFactor)
  108. {$endif RefsHaveScale}
  109. And (R1.Symbol = R2.Symbol)
  110. {$ifdef RefsHaveSegment}
  111. And (R1.Segment = R2.Segment)
  112. {$endif RefsHaveSegment}
  113. End;
  114. Function TAOptBase.GetNextInstruction(Current: Pai; Var Next: Pai): Boolean;
  115. Begin
  116. Repeat
  117. Current := Pai(Current^.Next);
  118. While Assigned(Current) And
  119. ((Current^.typ In SkipInstr) or
  120. ((Current^.typ = ait_label) And
  121. Not(Pai_Label(Current)^.l^.is_used))) Do
  122. Current := Pai(Current^.Next);
  123. If Assigned(Current) And
  124. (Current^.typ = ait_Marker) And
  125. (Pai_Marker(Current)^.Kind = NoPropInfoStart) Then
  126. Begin
  127. While Assigned(Current) And
  128. ((Current^.typ <> ait_Marker) Or
  129. (Pai_Marker(Current)^.Kind <> NoPropInfoEnd)) Do
  130. Current := Pai(Current^.Next);
  131. End;
  132. Until Not(Assigned(Current)) Or
  133. (Current^.typ <> ait_Marker) Or
  134. (Pai_Marker(Current)^.Kind <> NoPropInfoEnd);
  135. Next := Current;
  136. If Assigned(Current) And
  137. Not((Current^.typ In SkipInstr) or
  138. ((Current^.typ = ait_label) And
  139. Not(Pai_Label(Current)^.l^.is_used)))
  140. Then GetNextInstruction := True
  141. Else
  142. Begin
  143. Next := Nil;
  144. GetNextInstruction := False;
  145. End;
  146. End;
  147. Function TAOptBase.GetLastInstruction(Current: Pai; Var Last: Pai): Boolean;
  148. Begin
  149. Repeat
  150. Current := Pai(Current^.previous);
  151. While Assigned(Current) And
  152. (((Current^.typ = ait_Marker) And
  153. Not(Pai_Marker(Current)^.Kind in [AsmBlockEnd,NoPropInfoEnd])) or
  154. (Current^.typ In SkipInstr) or
  155. ((Current^.typ = ait_label) And
  156. Not(Pai_Label(Current)^.l^.is_used))) Do
  157. Current := Pai(Current^.previous);
  158. If Assigned(Current) And
  159. (Current^.typ = ait_Marker) And
  160. (Pai_Marker(Current)^.Kind = NoPropInfoEnd) Then
  161. Begin
  162. While Assigned(Current) And
  163. ((Current^.typ <> ait_Marker) Or
  164. (Pai_Marker(Current)^.Kind <> NoPropInfoStart)) Do
  165. Current := Pai(Current^.previous);
  166. End;
  167. Until Not(Assigned(Current)) Or
  168. (Current^.typ <> ait_Marker) Or
  169. (Pai_Marker(Current)^.Kind <> NoPropInfoStart);
  170. If Not(Assigned(Current)) or
  171. (Current^.typ In SkipInstr) or
  172. ((Current^.typ = ait_label) And
  173. Not(Pai_Label(Current)^.l^.is_used)) or
  174. ((Current^.typ = ait_Marker) And
  175. (Pai_Marker(Current)^.Kind = AsmBlockEnd))
  176. Then
  177. Begin
  178. Last := Nil;
  179. GetLastInstruction := False
  180. End
  181. Else
  182. Begin
  183. Last := Current;
  184. GetLastInstruction := True;
  185. End;
  186. End;
  187. { ******************* Processor dependent stuff *************************** }
  188. Function TAOptBase.RegMaxSize(Reg: TRegister): TRegister;
  189. Begin
  190. RegMaxSize := Reg
  191. End;
  192. Function TAOptBase.RegsSameSize(Reg1, Reg2: TRegister): Boolean;
  193. Begin
  194. RegsSameSize := True
  195. End;
  196. Function TAOptBase.IsLoadMemReg(p: pai): Boolean;
  197. Begin
  198. Abstract
  199. End;
  200. Function TAOptBase.IsLoadConstReg(p: pai): Boolean;
  201. Begin
  202. Abstract
  203. End;
  204. Function TAOptBase.IsStoreRegMem(p: pai): Boolean;
  205. Begin
  206. Abstract
  207. End;
  208. Function TAoptBase.a_load_reg_reg(reg1, reg2: TRegister): PInstr;
  209. Begin
  210. Abstract
  211. End;
  212. End.
  213. {
  214. $Log$
  215. Revision 1.2 1999-08-23 14:41:12 jonas
  216. + checksequence (processor independent)\n + processor independent part of docse
  217. Revision 1.1 1999/08/18 14:32:21 jonas
  218. + compilable!
  219. + dataflow analyzer finished
  220. + start of CSE units
  221. + aoptbase which contains a base object for all optimizer objects
  222. * some constants and type definitions moved around to avoid circular
  223. dependencies
  224. * moved some methods from base objects to specialized objects because
  225. they're not used anywhere else
  226. }