aoptbase.pas 8.9 KB

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