aoptda.pas 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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. Interface
  22. uses aasm, cpubase, aoptcpub, aoptbase, aoptcpu;
  23. Type
  24. TAOptDFA = Object(TAoptCpu)
  25. { uses the same constructor as TAoptCpu = constructor from TAoptObj }
  26. { gathers the information regarding the contents of every register }
  27. { at the end of every instruction }
  28. Procedure DoDFA;
  29. { handles the processor dependent dataflow analizing }
  30. Procedure CpuDFA(p: PInstr); Virtual;
  31. { How many instructions are between the current instruction and the }
  32. { last one that modified the register }
  33. InstrSinceLastMod: TInstrSinceLastMod;
  34. { convert a TInsChange value into the corresponding register }
  35. Function TCh2Reg(Ch: TInsChange): TRegister; Virtual;
  36. { returns whether the instruction P reads from register Reg }
  37. Function RegReadByInstr(Reg: TRegister; p: Pai): Boolean; Virtual;
  38. End;
  39. Implementation
  40. uses globals, aoptobj;
  41. Procedure TAOptDFA.DoDFA;
  42. { Analyzes the Data Flow of an assembler list. Analyses the reg contents }
  43. { for the instructions between blockstart and blockend. Returns the last pai }
  44. { which has been processed }
  45. Var
  46. CurProp: PPaiProp;
  47. UsedRegs: TUsedRegs;
  48. p, hp, NewBlockStart : Pai;
  49. TmpReg: TRegister;
  50. Begin
  51. p := BlockStart;
  52. UsedRegs.init;
  53. UsedRegs.Update(p);
  54. NewBlockStart := SkipHead(p);
  55. { done implicitely by the constructor
  56. FillChar(InstrSinceLastMod, SizeOf(InstrSinceLastMod), 0); }
  57. While (P <> BlockEnd) Do
  58. Begin
  59. CurProp := New(PPaiProp, init);
  60. If (p <> NewBlockStart) Then
  61. Begin
  62. GetLastInstruction(p, hp);
  63. CurProp^.Regs := PPaiProp(hp^.OptInfo)^.Regs;
  64. { !!!!!!!!!!!! }
  65. {$ifdef i386}
  66. CurProp^.CondRegs.Flags :=
  67. PPaiProp(hp^.OptInfo)^.CondRegs.Flags;
  68. {$endif}
  69. End;
  70. CurProp^.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs);
  71. UsedRegs.Update(Pai(p^.Next));
  72. PPaiProp(p^.OptInfo) := CurProp;
  73. For TmpReg := LoGPReg To HiGPReg Do
  74. Inc(InstrSinceLastMod[TmpReg]);
  75. Case p^.typ Of
  76. ait_label:
  77. If (Pai_label(p)^.l^.is_used) Then
  78. CurProp^.DestroyAllRegs(InstrSinceLastMod);
  79. {$ifdef GDB}
  80. ait_stabs, ait_stabn, ait_stab_function_name:;
  81. {$endif GDB}
  82. ait_instruction:
  83. if not(PInstr(p)^.is_jmp) then
  84. begin
  85. If IsLoadMemReg(p) Then
  86. Begin
  87. CurProp^.ReadRef(PInstr(p)^.oper[LoadSrc].ref);
  88. TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
  89. If RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^) And
  90. (CurProp^.GetRegContentType(TmpReg) = Con_Ref) Then
  91. Begin
  92. { a load based on the value this register already }
  93. { contained }
  94. With CurProp^.Regs[TmpReg] Do
  95. Begin
  96. CurProp^.IncWState(TmpReg);
  97. {also store how many instructions are part of the }
  98. { sequence in the first instruction's PPaiProp, so }
  99. { it can be easily accessed from within }
  100. { CheckSequence }
  101. Inc(NrOfMods, InstrSinceLastMod[TmpReg]);
  102. PPaiProp(Pai(StartMod)^.OptInfo)^.Regs[TmpReg].NrOfMods := NrOfMods;
  103. InstrSinceLastMod[TmpReg] := 0
  104. End
  105. End
  106. Else
  107. Begin
  108. { load of a register with a completely new value }
  109. CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
  110. If Not(RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^)) Then
  111. With CurProp^.Regs[TmpReg] Do
  112. Begin
  113. Typ := Con_Ref;
  114. StartMod := p;
  115. NrOfMods := 1;
  116. End
  117. End;
  118. {$ifdef StateDebug}
  119. hp := new(pai_asm_comment,init(strpnew(std_reg2str[TmpReg]+': '+tostr(CurProp^.Regs[TmpReg].WState))));
  120. InsertLLItem(AsmL, p, p^.next, hp);
  121. {$endif StateDebug}
  122. End
  123. Else if IsLoadConstReg(p) Then
  124. Begin
  125. TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
  126. With CurProp^.Regs[TmpReg] Do
  127. Begin
  128. CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
  129. typ := Con_Const;
  130. StartMod := Pointer(PInstr(p)^.oper[LoadSrc].val);
  131. End
  132. End
  133. Else CpuDFA(Pinstr(p));
  134. End;
  135. Else CurProp^.DestroyAllRegs(InstrSinceLastMod);
  136. End;
  137. { Inc(InstrCnt);}
  138. GetNextInstruction(p, p);
  139. End;
  140. End;
  141. Procedure TAoptDFA.CpuDFA(p: PInstr);
  142. Begin
  143. Abstract;
  144. End;
  145. Function TAOptDFA.TCh2Reg(Ch: TInsChange): TRegister;
  146. Begin
  147. TCh2Reg:=R_NO;
  148. Abstract;
  149. End;
  150. Function TAOptDFA.RegReadByInstr(Reg: TRegister; p: Pai): Boolean;
  151. Begin
  152. RegReadByInstr:=false;
  153. Abstract;
  154. End;
  155. End.
  156. {
  157. $Log$
  158. Revision 1.6 2002-05-18 13:34:05 peter
  159. * readded missing revisions
  160. Revision 1.5 2002/05/16 19:46:35 carl
  161. + defines.inc -> fpcdefs.inc to avoid conflicts if compiling by hand
  162. + try to fix temp allocation (still in ifdef)
  163. + generic constructor calls
  164. + start of tassembler / tmodulebase class cleanup
  165. Revision 1.3 2002/04/15 18:55:40 carl
  166. + change reg2str array use
  167. Revision 1.2 2002/04/14 16:49:30 carl
  168. + att_reg2str -> gas_reg2str
  169. }