csopt386.pas 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. {
  2. $Id$
  3. Copyright (c) 1997-98 by Jonas Maebe
  4. This unit contains the common subexpression elimination procedure.
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. Unit CSOpt386;
  19. Interface
  20. Uses aasm;
  21. {Procedure CSOpt386(First, Last: Pai);}
  22. Procedure CSE(AsmL: PAasmOutput; First, Last: Pai);
  23. Implementation
  24. Uses
  25. CObjects, verbose, hcodegen, globals,cpubase,cpuasm,DAOpt386;
  26. {
  27. Function PaiInSequence(P: Pai; Const Seq: TContent): Boolean;
  28. Var P1: Pai;
  29. Counter: Byte;
  30. TmpResult: Boolean;
  31. Begin
  32. TmpResult := False;
  33. P1 := Seq.StartMod;
  34. Counter := 1;
  35. While Not(TmpResult) And
  36. (Counter <= Seq.NrOfMods) Do
  37. Begin
  38. If (P = P1) Then TmpResult := True;
  39. Inc(Counter);
  40. p1 := Pai(p1^.Next);
  41. End;
  42. PaiInSequence := TmpResult;
  43. End;
  44. }
  45. Function CheckSequence(p: Pai; Reg: TRegister; Var Found: Longint; Var RegInfo: TRegInfo): Boolean;
  46. {checks whether the current instruction sequence (starting with p) and the
  47. one between StartMod and EndMod of Reg are the same. If so, the number of
  48. instructions that match is stored in Found and true is returned, otherwise
  49. Found holds the number of instructions between StartMod and EndMod and false
  50. is returned}
  51. Var hp2, hp3{, EndMod}: Pai;
  52. PrevNonRemovablePai: Pai;
  53. OrgRegInfo, HighRegInfo: TRegInfo;
  54. HighFound, OrgRegFound: Byte;
  55. RegCounter: TRegister;
  56. OrgRegResult: Boolean;
  57. TmpResult: Boolean;
  58. OldNrOfMods: Byte;
  59. Begin {CheckSequence}
  60. Reg := Reg32(Reg);
  61. TmpResult := False;
  62. FillChar(OrgRegInfo, SizeOf(OrgRegInfo), 0);
  63. OrgRegFound := 0;
  64. HighFound := 0;
  65. OrgRegResult := False;
  66. RegCounter := R_EAX;
  67. GetLastInstruction(p, PrevNonRemovablePai);
  68. While (RegCounter <= R_EDI) And
  69. (PPaiProp(PrevNonRemovablePai^.OptInfo)^.Regs[RegCounter].Typ <> Con_Ref) Do
  70. Inc(RegCounter);
  71. While (RegCounter <= R_EDI) Do
  72. Begin
  73. FillChar(RegInfo, SizeOf(RegInfo), 0);
  74. RegInfo.NewRegsEncountered := [ProcInfo.FramePointer, R_ESP];
  75. RegInfo.OldRegsEncountered := RegInfo.NewRegsEncountered;
  76. RegInfo.New2OldReg[ProcInfo.FramePointer] := ProcInfo.FramePointer;
  77. RegInfo.New2OldReg[R_ESP] := R_ESP;
  78. Found := 0;
  79. hp2 := PPaiProp(PrevNonRemovablePai^.OptInfo)^.Regs[RegCounter].StartMod;
  80. If (PrevNonRemovablePai <> PPaiProp(PrevNonRemovablePai^.OptInfo)^.Regs[RegCounter].StartMod)
  81. Then OldNrOfMods := PPaiProp(PrevNonRemovablePai^.OptInfo)^.Regs[RegCounter].NrOfMods
  82. Else OldNrOfMods := 1;
  83. hp3 := p;
  84. While (Found <> OldNrOfMods) And
  85. { old new }
  86. InstructionsEquivalent(hp2, hp3, RegInfo) Do
  87. Begin
  88. GetNextInstruction(hp2, hp2);
  89. GetNextInstruction(hp3, hp3);
  90. Inc(Found)
  91. End;
  92. If (Found <> OldNrOfMods)
  93. Then
  94. Begin
  95. (* If ((Found+1) = OldNrOfMods) And
  96. Assigned(hp2) And
  97. (Pai(hp2)^.typ = ait_instruction) And
  98. ((Pai386(hp2)^.opcode = A_MOV) or
  99. (Pai386(p1)^.opcode = A_MOVZX)) And
  100. (Pai386(hp2)^.oper[0].typ = top_ref) And
  101. (Pai386(hp2)^.optype[1] = top_reg) And
  102. Assigned(hp3) And
  103. (Pai(hp3)^.typ = ait_instruction) And
  104. ((Pai386(hp3)^.opcode = A_MOV) or
  105. (Pai386(hp3)^.opcode = A_MOVZX)) And
  106. (Pai386(hp3)^.oper[0].typ = top_ref) And
  107. (Pai386(hp3)^.optype[1] = top_reg) And
  108. (Pai386(hp2)^.opcode <> Pai386(hp3)^.opcode) And
  109. RefsEquivalent(TReference(Pai386(hp2)^.oper[1]^),TReference(Pai386(hp3)^.oper[1]^), RegInfo)
  110. Then
  111. {hack to be able to optimize
  112. mov (mem), reg
  113. mov (reg), reg
  114. mov (reg), reg [*]
  115. test reg, reg and the oposite (where the marked instructions are
  116. jne l1 switched)
  117. mov (mem), reg
  118. mov (reg), reg
  119. movzx (reg), reg [*]}
  120. If (Pai386(hp2)^.opcode = A_MOV)
  121. Then
  122. Begin
  123. If (Pai386(hp2)^.opsize = S_B) And
  124. RegsEquivalent(Reg8toReg32(TRegister(Pai386(hp2)^.oper[1])),
  125. TRegister(Pai386(hp3)^.oper[1]), RegInfo)
  126. Then
  127. Begin
  128. Pai386(hp2)^.opcode := A_MOVZX;
  129. Pai386(hp2)^.opsize := S_BL;
  130. Pai386(hp2)^.loadoper(1,Pai386(hp3)^.oper[1]);
  131. Inc(Found);
  132. TmpResult := True;
  133. End
  134. Else
  135. Begin
  136. TmpResult := False;
  137. If (Found > 0) Then
  138. Found := PPaiProp(Pai(p)^.OptInfo)^.Regs[Reg].NrOfMods
  139. End
  140. End
  141. Else
  142. Begin
  143. If (Pai386(hp3)^.opsize = S_B) And
  144. RegsEquivalent(TRegister(Pai386(hp2)^.oper[1]),
  145. Reg8toReg32(TRegister(Pai386(hp3)^.oper[1])),
  146. RegInfo)
  147. Then
  148. Begin
  149. TmpResult := True;
  150. Inc(Found)
  151. End
  152. Else
  153. Begin
  154. TmpResult := False;
  155. If (Found > 0) Then
  156. Found := PPaiProp(Pai(p)^.OptInfo)^.Regs[Reg].NrOfMods
  157. End
  158. End
  159. Else *)
  160. Begin
  161. TmpResult := False;
  162. If (found > 0) then
  163. {this is correct because we only need to turn off the CanBeRemoved flag
  164. when an instruction has already been processed by CheckSequence
  165. (otherwise CanBeRemoved can't be true and thus can't have to be turned off).
  166. If it has already been processed by CheckSequence and flagged to be
  167. removed, it means that it has been checked against a previous sequence
  168. and that it was equal (otherwise CheckSequence would have returned false
  169. and the instruction wouldn't have been removed). If this "If found > 0"
  170. check is left out, incorrect optimizations are performed.}
  171. Found := PPaiProp(Pai(p)^.OptInfo)^.Regs[Reg].NrOfMods
  172. End
  173. End
  174. Else TmpResult := True;
  175. If TmpResult And
  176. (Found > HighFound)
  177. Then
  178. Begin
  179. HighFound := Found;
  180. HighRegInfo := RegInfo;
  181. End;
  182. If (RegCounter = Reg) Then
  183. Begin
  184. OrgRegFound := Found;
  185. OrgRegResult := TmpResult;
  186. OrgRegInfo := RegInfo
  187. End;
  188. Repeat
  189. Inc(RegCounter);
  190. Until (RegCounter > R_EDI) or
  191. ((PPaiProp(PrevNonRemovablePai^.OptInfo)^.Regs[RegCounter].Typ = Con_Ref) {And
  192. ((Regcounter = Reg) Or
  193. Not(PaiInSequence(p, PPaiProp(PrevNonRemovablePai^.OptInfo)^.Regs[RegCounter]))) }
  194. );
  195. End;
  196. If (HighFound > 0) And
  197. (Not(OrgRegResult) Or
  198. (HighFound > OrgRegFound))
  199. Then
  200. Begin
  201. CheckSequence := True;
  202. RegInfo := HighRegInfo;
  203. Found := HighFound
  204. End
  205. Else
  206. Begin
  207. CheckSequence := OrgRegResult;
  208. Found := OrgRegFound;
  209. RegInfo := OrgRegInfo;
  210. End;
  211. End; {CheckSequence}
  212. Procedure DoCSE(AsmL: PAasmOutput; First, Last: Pai);
  213. {marks the instructions that can be removed by RemoveInstructs. They're not
  214. removed immediately because sometimes an instruction needs to be checked in
  215. two different sequences}
  216. Var Cnt, Cnt2: Longint;
  217. p, hp1, hp2: Pai;
  218. hp3, hp4: Pai;
  219. {$ifdef csdebug}
  220. hp5: pai;
  221. {$endif csdebug}
  222. RegInfo: TRegInfo;
  223. RegCounter: TRegister;
  224. TmpState: Byte;
  225. Begin
  226. p := First;
  227. SkipHead(p);
  228. First := p;
  229. While (p <> Last) Do
  230. Begin
  231. Case p^.typ Of
  232. ait_instruction:
  233. Begin
  234. Case Pai386(p)^.opcode Of
  235. A_CLD: If GetLastInstruction(p, hp1) And
  236. (PPaiProp(hp1^.OptInfo)^.DirFlag = F_NotSet) Then
  237. PPaiProp(Pai(p)^.OptInfo)^.CanBeRemoved := True;
  238. A_MOV, A_MOVZX, A_MOVSX:
  239. Begin
  240. Case Pai386(p)^.oper[0].typ Of
  241. { Top_Reg:
  242. Case Pai386(p)^.optype[1] Of
  243. Top_Reg:;
  244. Top_Ref:;
  245. End;}
  246. Top_Ref:
  247. Begin {destination is always a register in this case}
  248. With PPaiProp(p^.OptInfo)^.Regs[Reg32(Pai386(p)^.oper[1].reg)] Do
  249. Begin
  250. If (p = StartMod) And
  251. GetLastInstruction (p, hp1) And
  252. (hp1^.typ <> ait_marker)
  253. Then
  254. {so we don't try to check a sequence when p is the first instruction of the block}
  255. If CheckSequence(p, Pai386(p)^.oper[1].reg, Cnt, RegInfo) And
  256. (Cnt > 0)
  257. Then
  258. Begin
  259. hp1 := nil;
  260. {although it's perfectly ok to remove an instruction which doesn't contain
  261. the register that we've just checked (CheckSequence takes care of that),
  262. the sequence containing this other register should also be completely
  263. checked and removed, otherwise we may get situations like this:
  264. movl 12(%ebp), %edx movl 12(%ebp), %edx
  265. movl 16(%ebp), %eax movl 16(%ebp), %eax
  266. movl 8(%edx), %edx movl 8(%edx), %edx
  267. movl (%eax), eax movl (%eax), eax
  268. cmpl %eax, %edx cmpl %eax, %edx
  269. jnz l123 getting converted to jnz l123
  270. movl 12(%ebp), %edx movl 4(%eax), eax
  271. movl 16(%ebp), %eax
  272. movl 8(%edx), %edx
  273. movl 4(%eax), eax}
  274. hp2 := p;
  275. Cnt2 := 1;
  276. While Cnt2 <= Cnt Do
  277. Begin
  278. If (hp1 = nil) And
  279. Not(RegInInstruction(Pai386(hp2)^.oper[1].reg, p) Or
  280. RegInInstruction(Reg32(Pai386(hp2)^.oper[1].reg), p)) And
  281. Not((p^.typ = ait_instruction) And
  282. (pai386(p)^.OpCode = A_MOV) And
  283. (pai386(p)^.Oper[0].typ = top_ref) And
  284. (PPaiProp(p^.OptInfo)^.Regs[Reg32(pai386(p)^.Oper[1].reg)].NrOfMods
  285. <= (Cnt - Cnt2 + 1)))
  286. Then hp1 := p;
  287. {$ifndef noremove}
  288. PPaiProp(p^.OptInfo)^.CanBeRemoved := True;
  289. {$endif noremove}
  290. Inc(Cnt2);
  291. GetNextInstruction(p, p);
  292. End;
  293. hp3 := New(Pai_Marker,Init(NoPropInfoStart));
  294. InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3);
  295. {imagine the following code:
  296. normal wrong optimized
  297. movl 8(%ebp), %eax movl 8(%ebp), %eax
  298. movl (%eax), %eax movl (%eax), %eax
  299. cmpl 8(%ebp), %eax cmpl 8(%ebp), %eax
  300. jne l1 jne l1
  301. movl 8(%ebp), %eax
  302. movl (%eax), %edi movl %eax, %edi
  303. movl %edi, -4(%ebp) movl %edi, -4(%ebp)
  304. movl 8(%ebp), %eax
  305. pushl 70(%eax) pushl 70(%eax)
  306. The error is that at the moment that the last instruction is executed,
  307. %eax doesn't contain 8(%ebp) anymore. Solution: the contents of registers
  308. that are completely removed from a sequence, have to be changed to their
  309. contents from before the sequence.}
  310. {hp4 is used to get the contents of the registers before the sequence}
  311. GetLastInstruction(hp2, hp4);
  312. {If some registers were different in the old and the new sequence, move
  313. the contents of those old registers to the new ones}
  314. {$IfDef CSDebug}
  315. For RegCounter := R_EAX To R_EDI Do
  316. If (RegCounter in RegInfo.RegsLoadedForRef) Then
  317. Begin
  318. hp5 := new(pai_asm_comment,init(strpnew('New: '+att_reg2str[RegCounter]+', Old: '+
  319. att_reg2str[RegInfo.New2OldReg[RegCounter]])));
  320. InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp5);
  321. End;
  322. {$EndIf CSDebug}
  323. For RegCounter := R_EAX To R_EDI Do
  324. Begin
  325. If (RegInfo.New2OldReg[RegCounter] <> R_NO) Then
  326. If Not(RegCounter In RegInfo.RegsLoadedForRef) And
  327. {old reg new reg}
  328. (RegInfo.New2OldReg[RegCounter] <> RegCounter) Then
  329. Begin
  330. hp3 := New(Pai386,Op_Reg_Reg(A_MOV, S_L,
  331. {old reg new reg}
  332. RegInfo.New2OldReg[RegCounter], RegCounter));
  333. hp3^.fileinfo := hp2^.fileinfo;
  334. InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp3);
  335. End
  336. Else
  337. If (RegCounter In RegInfo.RegsLoadedForRef) Then
  338. {change the contents of this register to the its contents before the
  339. sequence (for all instructions in and after the sequence, until the register
  340. is reloaded)}
  341. Begin
  342. {load Cnt2 with the total number of instructions of this sequence}
  343. Cnt2 := PPaiProp(hp4^.OptInfo)^.
  344. Regs[RegInfo.New2OldReg[RegCounter]].NrOfMods;
  345. {sometimes, a register can not be removed from a sequence, because it's
  346. still used afterwards:
  347. movl -8(%ebp), %eax movl -8(%ebp), %eax
  348. movl 70(%eax), %eax movl 70(%eax), %eax
  349. cmpl 74(%eax), %eax cmpl 74(%eax), %eax
  350. jne l1 can't be changed to jne l1
  351. movl -8(%ebp), %eax
  352. movl 70(%eax), %edi movl %eax, %edi
  353. boundl R_282, %edi boundl R_282, %edi
  354. pushl 70(%eax) pushl 70(%eax)
  355. because eax now contains the wrong value when 70(%eax) is pushed}
  356. hp3 := hp2;
  357. For Cnt := 1 to Pred(Cnt2) Do
  358. GetNextInstruction(hp3, hp3);
  359. TmpState := PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState;
  360. GetNextInstruction(hp3, hp3);
  361. If (TmpState <> PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState) Or
  362. Not(RegCounter in PPaiProp(hp3^.OptInfo)^.UsedRegs) Then
  363. Begin
  364. {$ifdef csdebug}
  365. Writeln('Cnt2: ',Cnt2);
  366. hp5 := new(pai_asm_comment,init(strpnew('starting here...')));
  367. InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp5);
  368. {$endif csdebug}
  369. hp3 := hp2;
  370. {first change the contents of the register inside the sequence}
  371. For Cnt := 1 to Cnt2 Do
  372. Begin
  373. {save the WState of the last pai object of the sequence for later use}
  374. TmpState := PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState;
  375. {$ifdef csdebug}
  376. hp5 := new(pai_asm_comment,init(strpnew('WState for '+att_reg2str[Regcounter]+': '
  377. +tostr(tmpstate))));
  378. InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
  379. {$endif csdebug}
  380. PPaiProp(hp3^.OptInfo)^.Regs[RegCounter] :=
  381. PPaiProp(hp4^.OptInfo)^.Regs[RegCounter];
  382. GetNextInstruction(hp3, hp3);
  383. End;
  384. {here, hp3 = p = Pai object right after the sequence, TmpState = WState of
  385. RegCounter at the last Pai object of the sequence}
  386. GetLastInstruction(hp3, hp3);
  387. While GetNextInstruction(hp3, hp3) And
  388. (PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState
  389. = TmpState) Do
  390. {$ifdef csdebug}
  391. begin
  392. hp5 := new(pai_asm_comment,init(strpnew('WState for '+att_reg2str[Regcounter]+': '+
  393. tostr(PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState))));
  394. InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
  395. {$endif csdebug}
  396. PPaiProp(hp3^.OptInfo)^.Regs[RegCounter] :=
  397. PPaiProp(hp4^.OptInfo)^.Regs[RegCounter];
  398. {$ifdef csdebug}
  399. end;
  400. {$endif csdebug}
  401. End
  402. Else
  403. Begin
  404. {$ifdef csdebug}
  405. Writeln('Got there for ',att_Reg2Str[RegCounter]);
  406. {$endif csdebug}
  407. hp3 := hp2;
  408. For Cnt := 1 to Cnt2 Do
  409. Begin
  410. If RegModifiedByInstruction(RegCounter, hp3)
  411. Then PPaiProp(hp3^.OptInfo)^.CanBeRemoved := False;
  412. GetNextInstruction(hp3, hp3);
  413. End;
  414. End;
  415. {$ifdef csdebug}
  416. hp5 := new(pai_asm_comment,init(strpnew('stopping here...')));
  417. InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
  418. {$endif csdebug}
  419. End;
  420. End;
  421. hp3 := New(Pai_Marker,Init(NoPropInfoEnd));
  422. InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3);
  423. If hp1 <> nil Then p := hp1;
  424. Continue;
  425. End
  426. Else
  427. If (Cnt > 0) And
  428. (PPaiProp(p^.OptInfo)^.
  429. Regs[Reg32(Pai386(p)^.oper[1].reg)].Typ = Con_Ref) And
  430. (PPaiProp(p^.OptInfo)^.CanBeRemoved) Then
  431. Begin
  432. hp2 := p;
  433. Cnt2 := 1;
  434. While Cnt2 <= Cnt Do
  435. Begin
  436. If RegInInstruction(Pai386(hp2)^.oper[1].reg, p) Or
  437. RegInInstruction(Reg32(Pai386(hp2)^.oper[1].reg), p) Then
  438. PPaiProp(p^.OptInfo)^.CanBeRemoved := False;
  439. Inc(Cnt2);
  440. GetNextInstruction(p, p);
  441. End;
  442. Continue;
  443. End;
  444. End;
  445. End;
  446. Top_Const:
  447. Begin
  448. Case Pai386(p)^.oper[1].typ Of
  449. Top_Reg:
  450. Begin
  451. If GetLastInstruction(p, hp1) Then
  452. With PPaiProp(hp1^.OptInfo)^.Regs[Reg32(Pai386(p)^.oper[1].reg)] Do
  453. If (Typ = Con_Const) And
  454. (StartMod = p) Then
  455. PPaiProp(p^.OptInfo)^.CanBeRemoved := True;
  456. End;
  457. { Top_Ref:;}
  458. End;
  459. End;
  460. End;
  461. End;
  462. A_STD: If GetLastInstruction(p, hp1) And
  463. (PPaiProp(hp1^.OptInfo)^.DirFlag = F_Set) Then
  464. PPaiProp(Pai(p)^.OptInfo)^.CanBeRemoved := True;
  465. A_XOR:
  466. Begin
  467. If (Pai386(p)^.oper[0].typ = top_reg) And
  468. (Pai386(p)^.oper[0].typ = top_reg) And
  469. (Pai386(p)^.oper[1].reg = Pai386(p)^.oper[1].reg) And
  470. GetLastInstruction(p, hp1) And
  471. (PPaiProp(hp1^.OptInfo)^.Regs[Reg32(Pai386(p)^.oper[1].reg)].typ = con_const) And
  472. (PPaiProp(hp1^.OptInfo)^.Regs[Reg32(Pai386(p)^.oper[1].reg)].StartMod = nil)
  473. Then PPaiProp(p^.OptInfo)^.CanBeRemoved := True
  474. End
  475. End
  476. End;
  477. End;
  478. GetNextInstruction(p, p);
  479. End;
  480. End;
  481. Procedure RemoveInstructs(AsmL: PAasmOutput; First, Last: Pai);
  482. {Removes the marked instructions and disposes the PPaiProps of the other
  483. instructions, restoring their line number}
  484. Var p, hp1: Pai;
  485. {$IfDef TP}
  486. TmpLine: Longint;
  487. {$EndIf TP}
  488. InstrCnt: Longint;
  489. Begin
  490. p := First;
  491. SkipHead(P);
  492. InstrCnt := 1;
  493. While (p <> Last) Do
  494. Begin
  495. {$ifndef noinstremove}
  496. If PPaiProp(p^.OptInfo)^.CanBeRemoved
  497. Then
  498. Begin
  499. {$IfDef TP}
  500. Dispose(PPaiProp(p^.OptInfo));
  501. {$EndIf}
  502. GetNextInstruction(p, hp1);
  503. AsmL^.Remove(p);
  504. Dispose(p, Done);
  505. p := hp1;
  506. Inc(InstrCnt);
  507. End
  508. Else
  509. {$endif noinstremove}
  510. Begin
  511. {$IfDef TP}
  512. Dispose(PPaiProp(p^.OptInfo));
  513. {$EndIf TP}
  514. p^.OptInfo := nil;
  515. GetNextInstruction(p, p);
  516. Inc(InstrCnt);
  517. End;
  518. End;
  519. {$IfNDef TP}
  520. FreeMem(PaiPropBlock, NrOfPaiObjs*(((SizeOf(TPaiProp)+3)div 4)*4))
  521. {$EndIf TP}
  522. End;
  523. Procedure CSE(AsmL: PAasmOutput; First, Last: Pai);
  524. Begin
  525. DoCSE(AsmL, First, Last);
  526. RemoveInstructs(AsmL, First, Last);
  527. End;
  528. End.
  529. {
  530. $Log$
  531. Revision 1.23 1999-08-04 00:22:58 florian
  532. * renamed i386asm and i386base to cpuasm and cpubase
  533. Revision 1.22 1999/06/03 15:45:08 jonas
  534. * sequences are now checked only once (previously, some long ones were
  535. checked once completely and then several times partially)
  536. Revision 1.21 1999/05/08 20:38:03 jonas
  537. * seperate OPTimizer INFO pointer field in tai object
  538. Revision 1.20 1999/05/01 13:24:19 peter
  539. * merged nasm compiler
  540. * old asm moved to oldasm/
  541. Revision 1.2 1999/03/29 16:05:45 peter
  542. * optimizer working for ag386bin
  543. Revision 1.1 1999/03/26 00:01:09 peter
  544. * first things for optimizer (compiles but cycle crashes)
  545. Revision 1.19 1999/02/26 00:48:17 peter
  546. * assembler writers fixed for ag386bin
  547. Revision 1.18 1998/12/29 18:48:22 jonas
  548. + optimize pascal code surrounding assembler blocks
  549. Revision 1.17 1998/12/17 16:37:39 jonas
  550. + extra checks in RegsEquivalent so some more optimizations can be done (which
  551. where disabled by the second fix from revision 1.22)
  552. Revision 1.16 1998/12/02 16:23:31 jonas
  553. * changed "if longintvar in set" to case or "if () or () .." statements
  554. * tree.pas: changed inlinenumber (and associated constructor/vars) to a byte
  555. Revision 1.15 1998/11/24 19:47:24 jonas
  556. * fixed problems posiible with 3 operand instructions
  557. Revision 1.14 1998/11/09 19:40:48 jonas
  558. * fixed comments from last commit (apparently there's still a 255 char limit :( )
  559. Revision 1.13 1998/11/09 19:33:39 jonas
  560. * changed specific bugfix (which was actually wrong implemented, but
  561. did the right thing in most cases nevertheless) to general bugfix
  562. * fixed bug that caused
  563. mov (ebp), edx mov (ebp), edx
  564. mov (edx), edx mov (edx), edx
  565. ... being changed to ...
  566. mov (ebp), edx mov edx, eax
  567. mov (eax), eax
  568. but this disabled another small correct optimization...
  569. Revision 1.12 1998/10/20 09:32:54 peter
  570. * removed some unused vars
  571. Revision 1.11 1998/10/07 16:24:52 jonas
  572. * changed state to WState (WriteState), added RState for future use in
  573. instruction scheduling
  574. Revision 1.10 1998/10/02 17:29:23 jonas
  575. * much better interregister CSE
  576. Revision 1.9 1998/10/01 20:21:49 jonas
  577. * inter-register CSE, still requires some tweaks (peepholeoptpass2, better RegAlloc)
  578. Revision 1.8 1998/09/21 08:45:09 pierre
  579. + added vmt_offset in tobjectdef.write for fututre use
  580. (first steps to have objects without vmt if no virtual !!)
  581. + added fpu_used field for tabstractprocdef :
  582. sets this level to 2 if the functions return with value in FPU
  583. (is then set to correct value at parsing of implementation)
  584. THIS MIGHT refuse some code with FPU expression too complex
  585. that were accepted before and even in some cases
  586. that don't overflow in fact
  587. ( like if f : float; is a forward that finally in implementation
  588. only uses one fpu register !!)
  589. Nevertheless I think that it will improve security on
  590. FPU operations !!
  591. * most other changes only for UseBrowser code
  592. (added symtable references for record and objects)
  593. local switch for refs to args and local of each function
  594. (static symtable still missing)
  595. UseBrowser still not stable and probably broken by
  596. the definition hash array !!
  597. Revision 1.7 1998/09/20 17:12:35 jonas
  598. * small fix for uncertain optimizations & more cleaning up
  599. Revision 1.5 1998/09/16 17:59:59 jonas
  600. * optimizer now completely dependant on GetNext/GetLast instruction, works again with -dRegAlloc
  601. Revision 1.4 1998/08/06 19:40:27 jonas
  602. * removed $ before and after Log in comment
  603. Revision 1.3 1998/08/05 16:00:12 florian
  604. * some fixes for ansi strings
  605. * log to Log changed
  606. }