csopt386.pas 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  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.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: Byte;
  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. If GetLastInstruction (p, hp1) Then
  266. {so we don't try to check a sequence when p is the first instruction of the block}
  267. If CheckSequence(p, TRegister(Pai386(p)^.op2), Cnt, RegInfo) And
  268. (Cnt > 0)
  269. Then
  270. Begin
  271. hp1 := nil;
  272. {although it's perfectly ok to remove an instruction which doesn't contain
  273. the register that we've just checked (CheckSequence takes care of that),
  274. the sequence containing this other register should also be completely
  275. checked and removed, otherwise we may get situations like this:
  276. movl 12(%ebp), %edx movl 12(%ebp), %edx
  277. movl 16(%ebp), %eax movl 16(%ebp), %eax
  278. movl 8(%edx), %edx movl 8(%edx), %edx
  279. movl (%eax), eax movl (%eax), eax
  280. cmpl %eax, %edx cmpl %eax, %edx
  281. jnz l123 getting converted to jnz l123
  282. movl 12(%ebp), %edx movl 4(%eax), eax
  283. movl 16(%ebp), %eax
  284. movl 8(%edx), %edx
  285. movl 4(%eax), eax}
  286. hp2 := p;
  287. Cnt2 := 1;
  288. While Cnt2 <= Cnt Do
  289. Begin
  290. If (hp1 = nil) And
  291. Not(RegInInstruction(Tregister(Pai386(hp2)^.op2), p) Or
  292. RegInInstruction(Reg32(Tregister(Pai386(hp2)^.op2)), p))
  293. Then hp1 := p;
  294. {$ifndef noremove}
  295. PPaiProp(p^.fileinfo.line)^.CanBeRemoved := True;
  296. {$endif noremove}
  297. Inc(Cnt2);
  298. GetNextInstruction(p, p);
  299. End;
  300. hp3 := New(Pai_Marker,Init(NoPropInfoStart));
  301. InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3);
  302. {imagine the following code:
  303. normal wrong optimized
  304. movl 8(%ebp), %eax movl 8(%ebp), %eax
  305. movl (%eax), %eax movl (%eax), %eax
  306. cmpl 8(%ebp), %eax cmpl 8(%ebp), %eax
  307. jne l1 jne l1
  308. movl 8(%ebp), %eax
  309. movl (%eax), %edi movl %eax, %edi
  310. movl %edi, -4(%ebp) movl %edi, -4(%ebp)
  311. movl 8(%ebp), %eax
  312. pushl 70(%eax) pushl 70(%eax)
  313. The error is that at the moment that the last instruction is executed,
  314. %eax doesn't contain 8(%ebp) anymore. Solution: the contents of registers
  315. that are completely removed from a sequence, have to be changed to their
  316. contents from before the sequence.}
  317. {hp4 is used to get the contents of the registers before the sequence}
  318. GetLastInstruction(hp2, hp4);
  319. {If some registers were different in the old and the new sequence, move
  320. the contents of those old registers to the new ones}
  321. {$IfDef CSDebug}
  322. For RegCounter := R_EAX To R_EDI Do
  323. If (RegCounter in RegInfo.RegsLoadedForRef) Then
  324. Begin
  325. hp5 := new(pai_asm_comment,init(strpnew('New: '+att_reg2str[RegCounter]+', Old: '+
  326. att_reg2str[RegInfo.SubstRegs[RegCounter]])));
  327. InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp5);
  328. End;
  329. {$EndIf CSDebug}
  330. For RegCounter := R_EAX To R_EDI Do
  331. Begin
  332. If (RegInfo.SubstRegs[RegCounter] <> R_NO) Then
  333. If Not(RegCounter In RegInfo.RegsLoadedForRef) And
  334. {new reg old reg}
  335. (RegInfo.SubstRegs[RegCounter] <> RegCounter) Then
  336. Begin
  337. hp3 := New(Pai386,Op_Reg_Reg(A_MOV, S_L,
  338. {old reg new reg}
  339. RegInfo.SubstRegs[RegCounter], RegCounter));
  340. hp3^.fileinfo := hp2^.fileinfo;
  341. hp3^.fileinfo.line := PPaiProp(hp2^.fileinfo.line)^.LineSave;
  342. InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp3);
  343. End
  344. Else
  345. If (RegCounter In RegInfo.RegsLoadedForRef) Then
  346. {change the contents of this register to the its contents before the
  347. sequence (for all instructions in and after the sequence, until the register
  348. is reloaded)}
  349. Begin
  350. {load Cnt2 with the total number of instructions of this sequence}
  351. Cnt2 := PPaiProp(hp4^.fileinfo.line)^.
  352. Regs[RegInfo.SubstRegs[RegCounter]].NrOfMods;
  353. {sometimes, a register can not be removed from a sequence, because it's
  354. still used afterwards:
  355. movl -8(%ebp), %eax movl -8(%ebp), %eax
  356. movl 70(%eax), %eax movl 70(%eax), %eax
  357. cmpl 74(%eax), %eax cmpl 74(%eax), %eax
  358. jne l1 can't be changed to jne l1
  359. movl -8(%ebp), %eax
  360. movl 70(%eax), %edi movl %eax, %edi
  361. boundl R_282, %edi boundl R_282, %edi
  362. pushl 70(%eax) pushl 70(%eax)
  363. because eax now contains the wrong value when 70(%eax) is pushed}
  364. hp3 := hp2;
  365. For Cnt := 1 to Pred(Cnt2) Do
  366. GetNextInstruction(hp3, hp3);
  367. TmpState := PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter].WState;
  368. GetNextInstruction(hp3, hp3);
  369. If (TmpState <> PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter].WState) Or
  370. Not(RegCounter in PPaiProp(hp3^.fileinfo.line)^.UsedRegs) Then
  371. Begin
  372. {$ifdef csdebug}
  373. Writeln('Cnt2: ',Cnt2);
  374. hp5 := new(pai_asm_comment,init(strpnew('starting here...')));
  375. InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp5);
  376. {$endif csdebug}
  377. hp3 := hp2;
  378. {first change the contents of the register inside the sequence}
  379. For Cnt := 1 to Cnt2 Do
  380. Begin
  381. {save the WState of the last pai object of the sequence for later use}
  382. TmpState := PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter].WState;
  383. {$ifdef csdebug}
  384. hp5 := new(pai_asm_comment,init(strpnew('WState for '+att_reg2str[Regcounter]+': '
  385. +tostr(tmpstate))));
  386. InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
  387. {$endif csdebug}
  388. PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter] :=
  389. PPaiProp(hp4^.fileinfo.line)^.Regs[RegCounter];
  390. GetNextInstruction(hp3, hp3);
  391. End;
  392. {here, hp3 = p = Pai object right after the sequence, TmpState = WState of
  393. RegCounter at the last Pai object of the sequence}
  394. GetLastInstruction(hp3, hp3);
  395. While GetNextInstruction(hp3, hp3) And
  396. (PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter].WState
  397. = TmpState) Do
  398. {$ifdef csdebug}
  399. begin
  400. hp5 := new(pai_asm_comment,init(strpnew('WState for '+att_reg2str[Regcounter]+': '+
  401. tostr(PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter].WState))));
  402. InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
  403. {$endif csdebug}
  404. PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter] :=
  405. PPaiProp(hp4^.fileinfo.line)^.Regs[RegCounter];
  406. {$ifdef csdebug}
  407. end;
  408. {$endif csdebug}
  409. End
  410. Else
  411. Begin
  412. {$ifdef csdebug}
  413. Writeln('Got there for ',att_Reg2Str[RegCounter]);
  414. {$endif csdebug}
  415. hp3 := hp2;
  416. For Cnt := 1 to Cnt2 Do
  417. Begin
  418. If RegModifiedByInstruction(RegCounter, hp3)
  419. Then PPaiProp(hp3^.fileinfo.line)^.CanBeRemoved := False;
  420. GetNextInstruction(hp3, hp3);
  421. End;
  422. End;
  423. {$ifdef csdebug}
  424. hp5 := new(pai_asm_comment,init(strpnew('stopping here...')));
  425. InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
  426. {$endif csdebug}
  427. End;
  428. End;
  429. hp3 := New(Pai_Marker,Init(NoPropInfoEnd));
  430. InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3);
  431. If hp1 <> nil Then p := hp1;
  432. Continue;
  433. End
  434. Else
  435. If (Cnt > 0) And
  436. (PPaiProp(p^.fileinfo.line)^.
  437. Regs[Reg32(TRegister(Pai386(p)^.op2))].Typ = Con_Ref) And
  438. (PPaiProp(p^.fileinfo.line)^.CanBeRemoved) Then
  439. Begin
  440. hp2 := p;
  441. Cnt2 := 1;
  442. While Cnt2 <= Cnt Do
  443. Begin
  444. If RegInInstruction(Tregister(Pai386(hp2)^.op2), p) Or
  445. RegInInstruction(Reg32(Tregister(Pai386(hp2)^.op2)), p)
  446. Then PPaiProp(p^.fileinfo.line)^.CanBeRemoved := False;
  447. Inc(Cnt2);
  448. GetNextInstruction(p, p);
  449. End;
  450. Continue;
  451. End;
  452. End;
  453. End;
  454. Top_Const:
  455. Begin
  456. Case Pai386(p)^.op2t Of
  457. Top_Reg:
  458. Begin
  459. If GetLastInstruction(p, hp1) Then
  460. With PPaiProp(hp1^.fileinfo.line)^.Regs[Reg32(TRegister(Pai386(p)^.op2))] Do
  461. If (Typ = Con_Const) And
  462. (StartMod = Pai386(p)^.op1) Then
  463. PPaiProp(p^.fileinfo.line)^.CanBeRemoved := True;
  464. End;
  465. { Top_Ref:;}
  466. End;
  467. End;
  468. End;
  469. End;
  470. A_STD: If GetLastInstruction(p, hp1) And
  471. (PPaiProp(hp1^.fileinfo.line)^.DirFlag = F_Set) Then
  472. PPaiProp(Pai(p)^.fileinfo.line)^.CanBeRemoved := True;
  473. A_XOR:
  474. Begin
  475. If (Pai386(p)^.op1t = top_reg) And
  476. (Pai386(p)^.op2t = top_reg) And
  477. (Pai386(p)^.op1 = Pai386(p)^.op2) And
  478. GetLastInstruction(p, hp1) And
  479. (PPaiProp(hp1^.fileinfo.line)^.Regs[Reg32(Tregister(Pai386(p)^.op1))].typ = con_const) And
  480. (PPaiProp(hp1^.fileinfo.line)^.Regs[Reg32(Tregister(Pai386(p)^.op1))].StartMod = Pointer(0))
  481. Then PPaiProp(p^.fileinfo.line)^.CanBeRemoved := True
  482. End
  483. End
  484. End;
  485. End;
  486. GetNextInstruction(p, p);
  487. End;
  488. End;
  489. Procedure RemoveInstructs(AsmL: PAasmOutput; First, Last: Pai);
  490. {Removes the marked instructions and disposes the PPaiProps of the other
  491. instructions, restoring theirline number}
  492. Var p, hp1: Pai;
  493. {$IfDef TP}
  494. TmpLine: Longint;
  495. {$EndIf TP}
  496. InstrCnt: Longint;
  497. Begin
  498. p := First;
  499. If (p^.typ in (SkipInstr + [ait_marker])) Then
  500. GetNextInstruction(p, p);
  501. InstrCnt := 1;
  502. While Assigned(p) Do
  503. Begin
  504. {$ifndef noinstremove}
  505. If PPaiProp(p^.fileinfo.line)^.CanBeRemoved
  506. Then
  507. Begin
  508. {$IfDef TP}
  509. Dispose(PPaiProp(p^.fileinfo.line));
  510. {$EndIf}
  511. GetNextInstruction(p, hp1);
  512. AsmL^.Remove(p);
  513. Dispose(p, Done);
  514. p := hp1;
  515. Inc(InstrCnt);
  516. End
  517. Else
  518. {$endif noinstremove}
  519. Begin
  520. {$IfDef TP}
  521. TmpLine := PPaiProp(p^.fileinfo.line)^.linesave;
  522. Dispose(PPaiProp(p^.fileinfo.line));
  523. p^.fileinfo.line := TmpLine;
  524. {$Else TP}
  525. p^.fileinfo.line := PPaiProp(p^.fileinfo.line)^.linesave;
  526. {$EndIf TP}
  527. GetNextInstruction(p, p);
  528. Inc(InstrCnt);
  529. End;
  530. End;
  531. {$IfNDef TP}
  532. FreeMem(PaiPropBlock, NrOfPaiObjs*(((SizeOf(TPaiProp)+3)div 4)*4))
  533. {$EndIf TP}
  534. End;
  535. Procedure CSE(AsmL: PAasmOutput; First, Last: Pai);
  536. Begin
  537. DoCSE(AsmL, First, Last);
  538. RemoveInstructs(AsmL, First, Last);
  539. End;
  540. End.
  541. {
  542. $Log$
  543. Revision 1.11 1998-10-07 16:24:52 jonas
  544. * changed state to WState (WriteState), added RState for future use in
  545. instruction scheduling
  546. Revision 1.10 1998/10/02 17:29:23 jonas
  547. * much better interregister CSE
  548. Revision 1.9 1998/10/01 20:21:49 jonas
  549. * inter-register CSE, still requires some tweaks (peepholeoptpass2, better RegAlloc)
  550. Revision 1.8 1998/09/21 08:45:09 pierre
  551. + added vmt_offset in tobjectdef.write for fututre use
  552. (first steps to have objects without vmt if no virtual !!)
  553. + added fpu_used field for tabstractprocdef :
  554. sets this level to 2 if the functions return with value in FPU
  555. (is then set to correct value at parsing of implementation)
  556. THIS MIGHT refuse some code with FPU expression too complex
  557. that were accepted before and even in some cases
  558. that don't overflow in fact
  559. ( like if f : float; is a forward that finally in implementation
  560. only uses one fpu register !!)
  561. Nevertheless I think that it will improve security on
  562. FPU operations !!
  563. * most other changes only for UseBrowser code
  564. (added symtable references for record and objects)
  565. local switch for refs to args and local of each function
  566. (static symtable still missing)
  567. UseBrowser still not stable and probably broken by
  568. the definition hash array !!
  569. Revision 1.7 1998/09/20 17:12:35 jonas
  570. * small fix for uncertain optimizations & more cleaning up
  571. Revision 1.5 1998/09/16 17:59:59 jonas
  572. * optimizer now completely dependant on GetNext/GetLast instruction, works again with -dRegAlloc
  573. Revision 1.4 1998/08/06 19:40:27 jonas
  574. * removed $ before and after Log in comment
  575. Revision 1.3 1998/08/05 16:00:12 florian
  576. * some fixes for ansi strings
  577. * log to Log changed
  578. }