csopt386.pas 26 KB

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