aoptda.pas 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. {
  2. Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal
  3. Development Team
  4. This unit contains the data flow analyzer object of the assembler
  5. optimizer.
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. ****************************************************************************
  18. }
  19. Unit aoptda;
  20. {$i fpcdefs.inc}
  21. Interface
  22. uses
  23. cpubase,cgbase,
  24. aasmbase,aasmtai,aasmdata,aasmcpu,
  25. aoptcpub, aoptbase;
  26. Type
  27. TAOptDFA = class
  28. { uses the same constructor as TAoptCpu = constructor from TAoptObj }
  29. { gathers the information regarding the contents of every register }
  30. { at the end of every instruction }
  31. Procedure DoDFA;
  32. { handles the processor dependent dataflow analizing }
  33. Procedure CpuDFA(p: PInstr); Virtual; Abstract;
  34. { How many instructions are between the current instruction and the }
  35. { last one that modified the register }
  36. InstrSinceLastMod: TInstrSinceLastMod;
  37. { convert a TInsChange value into the corresponding register }
  38. //!!!!!!!!!! Function TCh2Reg(Ch: TInsChange): TRegister; Virtual;
  39. { returns whether the instruction P reads from register Reg }
  40. Function RegReadByInstr(Reg: TRegister; p: tai): Boolean; Virtual; Abstract;
  41. End;
  42. Implementation
  43. uses
  44. globals, aoptobj;
  45. Procedure TAOptDFA.DoDFA;
  46. { Analyzes the Data Flow of an assembler list. Analyses the reg contents }
  47. { for the instructions between blockstart and blockend. Returns the last pai }
  48. { which has been processed }
  49. Var
  50. CurProp: TPaiProp;
  51. UsedRegs: TUsedRegs;
  52. p, hp, NewBlockStart : tai;
  53. TmpReg: TRegister;
  54. Begin
  55. {!!!!!!!!!!
  56. p := BlockStart;
  57. UsedRegs.Create;
  58. UsedRegs.Update(p);
  59. NewBlockStart := SkipHead(p);
  60. { done implicitely by the constructor
  61. FillChar(InstrSinceLastMod, SizeOf(InstrSinceLastMod), 0); }
  62. While (P <> BlockEnd) Do
  63. Begin
  64. CurProp:=TPaiProp.Create;
  65. If (p <> NewBlockStart) Then
  66. Begin
  67. GetLastInstruction(p, hp);
  68. CurProp.Regs := TPaiProp(hp.OptInfo).Regs;
  69. { !!!!!!!!!!!! }
  70. {$ifdef x86}
  71. CurProp.CondRegs.Flags :=
  72. TPaiProp(hp.OptInfo).CondRegs.Flags;
  73. {$endif}
  74. End;
  75. CurProp.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs);
  76. UsedRegs.Update(tai(p.Next));
  77. TPaiProp(p.OptInfo) := CurProp;
  78. For TmpReg := LoGPReg To HiGPReg Do
  79. Inc(InstrSinceLastMod[TmpReg]);
  80. Case p^.typ Of
  81. ait_label:
  82. If (Pai_label(p)^.l^.is_used) Then
  83. CurProp^.DestroyAllRegs(InstrSinceLastMod);
  84. ait_stab, ait_force_line, ait_function_name:;
  85. ait_instruction:
  86. if not(PInstr(p)^.is_jmp) then
  87. begin
  88. If IsLoadMemReg(p) Then
  89. Begin
  90. CurProp^.ReadRef(PInstr(p)^.oper[LoadSrc].ref);
  91. TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
  92. If RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^) And
  93. (CurProp^.GetRegContentType(TmpReg) = Con_Ref) Then
  94. Begin
  95. { a load based on the value this register already }
  96. { contained }
  97. With CurProp^.Regs[TmpReg] Do
  98. Begin
  99. CurProp^.IncWState(TmpReg);
  100. {also store how many instructions are part of the }
  101. { sequence in the first instruction's PPaiProp, so }
  102. { it can be easily accessed from within }
  103. { CheckSequence }
  104. Inc(NrOfMods, InstrSinceLastMod[TmpReg]);
  105. PPaiProp(Pai(StartMod)^.OptInfo)^.Regs[TmpReg].NrOfMods := NrOfMods;
  106. InstrSinceLastMod[TmpReg] := 0
  107. End
  108. End
  109. Else
  110. Begin
  111. { load of a register with a completely new value }
  112. CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
  113. If Not(RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^)) Then
  114. With CurProp^.Regs[TmpReg] Do
  115. Begin
  116. Typ := Con_Ref;
  117. StartMod := p;
  118. NrOfMods := 1;
  119. End
  120. End;
  121. {$ifdef StateDebug}
  122. hp := new(pai_asm_comment,init(strpnew(std_reg2str[TmpReg]+': '+tostr(CurProp^.Regs[TmpReg].WState))));
  123. InsertLLItem(AsmL, p, p^.next, hp);
  124. {$endif StateDebug}
  125. End
  126. Else if IsLoadConstReg(p) Then
  127. Begin
  128. TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
  129. With CurProp^.Regs[TmpReg] Do
  130. Begin
  131. CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
  132. typ := Con_Const;
  133. StartMod := Pointer(PInstr(p)^.oper[LoadSrc].val);
  134. End
  135. End
  136. Else CpuDFA(Pinstr(p));
  137. End;
  138. Else CurProp^.DestroyAllRegs(InstrSinceLastMod);
  139. End;
  140. { Inc(InstrCnt);}
  141. GetNextInstruction(p, p);
  142. End;
  143. }
  144. End;
  145. End.