aoptda.pas 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. {
  2. $Id$
  3. Copyright (c) 1999 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 TChange value into the corresponding register }
  35. Function TCh2Reg(Ch: TChange): 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. CurProp^.CondRegs.Flags :=
  65. PPaiProp(hp^.OptInfo)^.CondRegs.Flags;
  66. End;
  67. CurProp^.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs);
  68. UsedRegs.Update(Pai(p^.Next));
  69. PPaiProp(p^.OptInfo) := CurProp;
  70. For TmpReg := R_EAX To R_EDI Do
  71. Inc(InstrSinceLastMod[TmpReg]);
  72. Case p^.typ Of
  73. ait_label:
  74. If (Pai_label(p)^.l^.is_used) Then
  75. CurProp^.DestroyAllRegs(InstrSinceLastMod);
  76. {$ifdef GDB}
  77. ait_stabs, ait_stabn, ait_stab_function_name:;
  78. {$endif GDB}
  79. ait_instruction:
  80. if not(PInstr(p)^.is_jmp) then
  81. begin
  82. If IsLoadMemReg(p) Then
  83. Begin
  84. CurProp^.ReadRef(PInstr(p)^.oper[LoadSrc].ref);
  85. TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
  86. If RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^) And
  87. (CurProp^.GetRegContentType(TmpReg) = Con_Ref) Then
  88. Begin
  89. { a load based on the value this register already }
  90. { contained }
  91. With CurProp^.Regs[TmpReg] Do
  92. Begin
  93. CurProp^.IncWState(TmpReg);
  94. {also store how many instructions are part of the }
  95. { sequence in the first instruction's PPaiProp, so }
  96. { it can be easily accessed from within }
  97. { CheckSequence }
  98. Inc(NrOfMods, InstrSinceLastMod[TmpReg]);
  99. PPaiProp(Pai(StartMod)^.OptInfo)^.Regs[TmpReg].NrOfMods := NrOfMods;
  100. InstrSinceLastMod[TmpReg] := 0
  101. End
  102. End
  103. Else
  104. Begin
  105. { load of a register with a completely new value }
  106. CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
  107. If Not(RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^)) Then
  108. With CurProp^.Regs[TmpReg] Do
  109. Begin
  110. Typ := Con_Ref;
  111. StartMod := p;
  112. NrOfMods := 1;
  113. End
  114. End;
  115. {$ifdef StateDebug}
  116. hp := new(pai_asm_comment,init(strpnew(att_reg2str[TmpReg]+': '+tostr(CurProp^.Regs[TmpReg].WState))));
  117. InsertLLItem(AsmL, p, p^.next, hp);
  118. {$endif StateDebug}
  119. End
  120. Else if IsLoadConstReg(p) Then
  121. Begin
  122. TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
  123. With CurProp^.Regs[TmpReg] Do
  124. Begin
  125. CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
  126. typ := Con_Const;
  127. StartMod := Pointer(PInstr(p)^.oper[LoadSrc].val);
  128. End
  129. End
  130. Else CpuDFA(Pinstr(p));
  131. End;
  132. Else CurProp^.DestroyAllRegs(InstrSinceLastMod);
  133. End;
  134. { Inc(InstrCnt);}
  135. GetNextInstruction(p, p);
  136. End;
  137. End;
  138. Procedure TAoptDFA.CpuDFA(p: PInstr);
  139. Begin
  140. Abstract
  141. End;
  142. Function TAOptDFA.TCh2Reg(Ch: TChange): TRegister;
  143. Begin
  144. Abstract
  145. End;
  146. Function TAOptDFA.RegReadByInstr(Reg: TRegister; p: Pai): Boolean;
  147. Begin
  148. Abstract
  149. End;
  150. End.
  151. {
  152. $Log$
  153. Revision 1.4 1999-08-18 14:32:21 jonas
  154. + compilable!
  155. + dataflow analyzer finished
  156. + start of CSE units
  157. + aoptbase which contains a base object for all optimizer objects
  158. * some constants and type definitions moved around to avoid circular
  159. dependencies
  160. * moved some methods from base objects to specialized objects because
  161. they're not used anywhere else
  162. }