2
0

aoptda.pas 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  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. { How many instructions are between the current instruction and the }
  30. { last one that modified the register }
  31. InstrSinceLastMod: TInstrSinceLastMod;
  32. { gathers the information regarding the contents of every register }
  33. { at the end of every instruction }
  34. Procedure DoDFA;
  35. { handles the processor dependent dataflow analizing }
  36. Procedure CpuDFA(p: PInstr); Virtual; Abstract;
  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. {
  50. Var
  51. CurProp: TPaiProp;
  52. UsedRegs: TUsedRegs;
  53. p, hp, NewBlockStart : tai;
  54. TmpReg: TRegister;
  55. }
  56. Begin
  57. (*!!!!!!!!!!
  58. p := BlockStart;
  59. UsedRegs.Create;
  60. UsedRegs.Update(p);
  61. NewBlockStart := SkipHead(p);
  62. { done implicitely by the constructor
  63. FillChar(InstrSinceLastMod, SizeOf(InstrSinceLastMod), 0); }
  64. While (P <> BlockEnd) Do
  65. Begin
  66. CurProp:=TPaiProp.Create;
  67. If (p <> NewBlockStart) Then
  68. Begin
  69. GetLastInstruction(p, hp);
  70. CurProp.Regs := TPaiProp(hp.OptInfo).Regs;
  71. { !!!!!!!!!!!! }
  72. {$ifdef x86}
  73. CurProp.CondRegs.Flags :=
  74. TPaiProp(hp.OptInfo).CondRegs.Flags;
  75. {$endif}
  76. End;
  77. CurProp.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs);
  78. UsedRegs.Update(tai(p.Next));
  79. TPaiProp(p.OptInfo) := CurProp;
  80. For TmpReg := LoGPReg To HiGPReg Do
  81. Inc(InstrSinceLastMod[TmpReg]);
  82. Case p^.typ Of
  83. ait_label:
  84. If (Pai_label(p)^.l^.is_used) Then
  85. CurProp^.DestroyAllRegs(InstrSinceLastMod);
  86. ait_stab, ait_force_line, ait_function_name:;
  87. ait_instruction:
  88. if not(PInstr(p)^.is_jmp) then
  89. begin
  90. If IsLoadMemReg(p) Then
  91. Begin
  92. CurProp^.ReadRef(PInstr(p)^.oper[LoadSrc].ref);
  93. TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
  94. If RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^) And
  95. (CurProp^.GetRegContentType(TmpReg) = Con_Ref) Then
  96. Begin
  97. { a load based on the value this register already }
  98. { contained }
  99. With CurProp^.Regs[TmpReg] Do
  100. Begin
  101. CurProp^.IncWState(TmpReg);
  102. {also store how many instructions are part of the }
  103. { sequence in the first instruction's PPaiProp, so }
  104. { it can be easily accessed from within }
  105. { CheckSequence }
  106. Inc(NrOfMods, InstrSinceLastMod[TmpReg]);
  107. PPaiProp(Pai(StartMod)^.OptInfo)^.Regs[TmpReg].NrOfMods := NrOfMods;
  108. InstrSinceLastMod[TmpReg] := 0
  109. End
  110. End
  111. Else
  112. Begin
  113. { load of a register with a completely new value }
  114. CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
  115. If Not(RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^)) Then
  116. With CurProp^.Regs[TmpReg] Do
  117. Begin
  118. Typ := Con_Ref;
  119. StartMod := p;
  120. NrOfMods := 1;
  121. End
  122. End;
  123. {$ifdef StateDebug}
  124. hp := new(pai_asm_comment,init(strpnew(std_reg2str[TmpReg]+': '+tostr(CurProp^.Regs[TmpReg].WState))));
  125. InsertLLItem(AsmL, p, p^.next, hp);
  126. {$endif StateDebug}
  127. End
  128. Else if IsLoadConstReg(p) Then
  129. Begin
  130. TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
  131. With CurProp^.Regs[TmpReg] Do
  132. Begin
  133. CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
  134. typ := Con_Const;
  135. StartMod := Pointer(PInstr(p)^.oper[LoadSrc].val);
  136. End
  137. End
  138. Else CpuDFA(Pinstr(p));
  139. End;
  140. Else CurProp^.DestroyAllRegs(InstrSinceLastMod);
  141. End;
  142. { Inc(InstrCnt);}
  143. GetNextInstruction(p, p);
  144. End;
  145. *)
  146. End;
  147. End.