aoptbase.pas 8.8 KB

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