csopt386.pas 27 KB

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