aoptda.pas 6.9 KB

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