| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 | {    Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal    Development Team    This unit contains the data flow analyzer object of the assembler    optimizer.    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ****************************************************************************}Unit aoptda;{$i fpcdefs.inc}  Interface    uses      cpubase,cgbase,      aasmbase,aasmtai,aasmcpu,      aoptcpub, aoptbase;    Type      TAOptDFA = class        { uses the same constructor as TAoptCpu = constructor from TAoptObj }        { gathers the information regarding the contents of every register }        { at the end of every instruction                                  }        Procedure DoDFA;        { handles the processor dependent dataflow analizing               }        Procedure CpuDFA(p: PInstr); Virtual;        { How many instructions are between the current instruction and the }        { last one that modified the register                               }        InstrSinceLastMod: TInstrSinceLastMod;        { convert a TInsChange value into the corresponding register }        //!!!!!!!!!! Function TCh2Reg(Ch: TInsChange): TRegister; Virtual;        { returns whether the instruction P reads from register Reg }        Function RegReadByInstr(Reg: TRegister; p: tai): Boolean; Virtual;      End;  Implementation    uses      globals, aoptobj;    Procedure TAOptDFA.DoDFA;    { Analyzes the Data Flow of an assembler list. Analyses the reg contents     }    { for the instructions between blockstart and blockend. Returns the last pai }    { which has been processed                                                   }    Var        CurProp: TPaiProp;        UsedRegs: TUsedRegs;        p, hp, NewBlockStart : tai;        TmpReg: TRegister;    Begin    {!!!!!!!!!!      p := BlockStart;      UsedRegs.Create;      UsedRegs.Update(p);      NewBlockStart := SkipHead(p);      { done implicitely by the constructor      FillChar(InstrSinceLastMod, SizeOf(InstrSinceLastMod), 0); }      While (P <> BlockEnd) Do        Begin          CurProp:=TPaiProp.Create;          If (p <> NewBlockStart) Then            Begin              GetLastInstruction(p, hp);              CurProp.Regs := TPaiProp(hp.OptInfo).Regs;    { !!!!!!!!!!!! }    {$ifdef x86}              CurProp.CondRegs.Flags :=                TPaiProp(hp.OptInfo).CondRegs.Flags;    {$endif}            End;          CurProp.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs);          UsedRegs.Update(tai(p.Next));          TPaiProp(p.OptInfo) := CurProp;          For TmpReg := LoGPReg To HiGPReg Do            Inc(InstrSinceLastMod[TmpReg]);          Case p^.typ Of            ait_label:              If (Pai_label(p)^.l^.is_used) Then                CurProp^.DestroyAllRegs(InstrSinceLastMod);    {$ifdef GDB}            ait_stabs, ait_stabn, ait_stab_function_name:;    {$endif GDB}            ait_instruction:              if not(PInstr(p)^.is_jmp) then                begin                  If IsLoadMemReg(p) Then                    Begin                      CurProp^.ReadRef(PInstr(p)^.oper[LoadSrc].ref);                      TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);                      If RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^) And                         (CurProp^.GetRegContentType(TmpReg) = Con_Ref) Then                        Begin                          { a load based on the value this register already }                          { contained                                       }                          With CurProp^.Regs[TmpReg] Do                            Begin                              CurProp^.IncWState(TmpReg);                               {also store how many instructions are part of the  }                               { sequence in the first instruction's PPaiProp, so }                               { it can be easily accessed from within            }                               { CheckSequence                                    }                              Inc(NrOfMods, InstrSinceLastMod[TmpReg]);                              PPaiProp(Pai(StartMod)^.OptInfo)^.Regs[TmpReg].NrOfMods := NrOfMods;                              InstrSinceLastMod[TmpReg] := 0                            End                        End                      Else                        Begin                          { load of a register with a completely new value }                          CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);                          If Not(RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^)) Then                            With CurProp^.Regs[TmpReg] Do                              Begin                                Typ := Con_Ref;                                StartMod := p;                                NrOfMods := 1;                              End                        End;      {$ifdef StateDebug}                        hp := new(pai_asm_comment,init(strpnew(std_reg2str[TmpReg]+': '+tostr(CurProp^.Regs[TmpReg].WState))));                        InsertLLItem(AsmL, p, p^.next, hp);      {$endif StateDebug}                    End                  Else if IsLoadConstReg(p) Then                    Begin                      TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);                      With CurProp^.Regs[TmpReg] Do                        Begin                          CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);                          typ := Con_Const;                          StartMod := Pointer(PInstr(p)^.oper[LoadSrc].val);                        End                    End                  Else CpuDFA(Pinstr(p));                End;            Else CurProp^.DestroyAllRegs(InstrSinceLastMod);          End;    {      Inc(InstrCnt);}          GetNextInstruction(p, p);        End;    }    End;    Procedure TAoptDFA.CpuDFA(p: PInstr);    Begin      Abstract;    End;  {!!!!!!!    Function TAOptDFA.TCh2Reg(Ch: TInsChange): TRegister;    Begin      TCh2Reg:=R_NO;      Abstract;    End;  }    Function TAOptDFA.RegReadByInstr(Reg: TRegister; p: tai): Boolean;    Begin      RegReadByInstr:=false;      Abstract;    End;End.
 |