mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 20:26:00 +02:00
+ jump analyzing
This commit is contained in:
parent
2c0d277164
commit
66feedde08
@ -33,7 +33,6 @@ Uses AAsm, CObjects
|
|||||||
|
|
||||||
{*********************** Procedures and Functions ************************}
|
{*********************** Procedures and Functions ************************}
|
||||||
|
|
||||||
|
|
||||||
Procedure InsertLLItem(AsmL: PAasmOutput; prev, foll, new_one: PLinkedList_Item);
|
Procedure InsertLLItem(AsmL: PAasmOutput; prev, foll, new_one: PLinkedList_Item);
|
||||||
|
|
||||||
Function Reg32(Reg: TRegister): TRegister;
|
Function Reg32(Reg: TRegister): TRegister;
|
||||||
@ -48,8 +47,10 @@ Function GetLastInstruction(Current: Pai; Var Last: Pai): Boolean;
|
|||||||
|
|
||||||
Function RegsSameContent(p1, p2: Pai; Reg: TRegister): Boolean;
|
Function RegsSameContent(p1, p2: Pai; Reg: TRegister): Boolean;
|
||||||
Function InstructionsEqual(p1, p2: Pai): Boolean;
|
Function InstructionsEqual(p1, p2: Pai): Boolean;
|
||||||
|
|
||||||
Procedure DFAPass1(AsmL: PAasmOutput);
|
Procedure DFAPass1(AsmL: PAasmOutput);
|
||||||
Function DFAPass2(AsmL: PAasmOutput): Pai;
|
Function DFAPass2(AsmL: PAasmOutput): Pai;
|
||||||
|
Procedure ShutDownDFA;
|
||||||
|
|
||||||
Function FindLabel(L: PLabel; Var hp: Pai): Boolean;
|
Function FindLabel(L: PLabel; Var hp: Pai): Boolean;
|
||||||
{Procedure FindLoHiLabels(AsmL: PAasmOutput; Var LoLab, HiLab, LabDif: Longint);}
|
{Procedure FindLoHiLabels(AsmL: PAasmOutput; Var LoLab, HiLab, LabDif: Longint);}
|
||||||
@ -107,7 +108,7 @@ Type
|
|||||||
content of this register. If Typ = con_const, then
|
content of this register. If Typ = con_const, then
|
||||||
Longint(StartMod) = value of the constant)}
|
Longint(StartMod) = value of the constant)}
|
||||||
StartMod: Pointer;
|
StartMod: Pointer;
|
||||||
{starts at 0, gets increased everytime the register is modified}
|
{starts at 1, gets increased everytime the register is modified}
|
||||||
State: Word;
|
State: Word;
|
||||||
{how many instructions starting with StarMod does the block consist of}
|
{how many instructions starting with StarMod does the block consist of}
|
||||||
NrOfMods: Byte;
|
NrOfMods: Byte;
|
||||||
@ -138,29 +139,26 @@ Type
|
|||||||
CanBeRemoved: Boolean;
|
CanBeRemoved: Boolean;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
PPaiProp = ^TPaiProp;
|
PPaiProp = ^TPaiProp;
|
||||||
{$IfDef TP}
|
{$IfDef TP}
|
||||||
TPaiPropBlock = Array[1..(65520 div (((SizeOf(TPaiProp)+1)div 2)*2))] Of TPaiProp;
|
TPaiPropBlock = Array[1..(65520 div (((SizeOf(TPaiProp)+1)div 2)*2))] Of TPaiProp;
|
||||||
{$else}
|
{$else}
|
||||||
TPaiPropBlock = Array[1..250000] Of TPaiProp;
|
TPaiPropBlock = Array[1..250000] Of TPaiProp;
|
||||||
{$EndIf TP}
|
{$EndIf TP}
|
||||||
PPaiPropBlock = ^TPaiPropBlock;
|
PPaiPropBlock = ^TPaiPropBlock;
|
||||||
|
|
||||||
|
TInstrSinceLastMod = Array[R_EAX..R_EDI] Of Byte;
|
||||||
|
|
||||||
{$IfDef JmpAnal}
|
|
||||||
TLabelTableItem = Record
|
TLabelTableItem = Record
|
||||||
p: Pai;
|
PaiObj: Pai;
|
||||||
{$IfDef TP}
|
{$IfNDef TP}
|
||||||
RefsFound: Byte;
|
InstrNr: Longint;
|
||||||
{$Else TP}
|
|
||||||
RefsFound: Word;
|
RefsFound: Word;
|
||||||
|
JmpsProcessed: Word
|
||||||
{$EndIf TP}
|
{$EndIf TP}
|
||||||
AlreadyProcessed: Boolean;
|
|
||||||
End;
|
End;
|
||||||
{$Else JmpAnal}
|
|
||||||
TLabelTableItem = Pai;
|
|
||||||
{$Endif JmpAnal}
|
|
||||||
{$IfDef tp}
|
{$IfDef tp}
|
||||||
TLabelTable = Array[0..9000] Of TLabelTableItem;
|
TLabelTable = Array[0..10000] Of TLabelTableItem;
|
||||||
{$Else tp}
|
{$Else tp}
|
||||||
TLabelTable = Array[0..2500000] Of TLabelTableItem;
|
TLabelTable = Array[0..2500000] Of TLabelTableItem;
|
||||||
{$Endif tp}
|
{$Endif tp}
|
||||||
@ -171,7 +169,6 @@ Type
|
|||||||
|
|
||||||
{******************************* Variables *******************************}
|
{******************************* Variables *******************************}
|
||||||
|
|
||||||
|
|
||||||
Var
|
Var
|
||||||
{the amount of PaiObjects in the current assembler list}
|
{the amount of PaiObjects in the current assembler list}
|
||||||
NrOfPaiObjs,
|
NrOfPaiObjs,
|
||||||
@ -581,20 +578,20 @@ Const AsmInstr: Array[tasmop] Of TAsmInstrucProp = (
|
|||||||
Var
|
Var
|
||||||
{How many instructions are betwen the current instruction and the last one
|
{How many instructions are betwen the current instruction and the last one
|
||||||
that modified the register}
|
that modified the register}
|
||||||
NrOfInstrSinceLastMod: Array[R_EAX..R_EDI] Of Byte;
|
NrOfInstrSinceLastMod: TInstrSinceLastMod;
|
||||||
|
|
||||||
|
|
||||||
{************************ Create the Label table ************************}
|
{************************ Create the Label table ************************}
|
||||||
|
|
||||||
Procedure FindLoHiLabels(AsmL: PAasmOutput; Var LoLab, HiLab, LabDif: Longint);
|
Procedure FindLoHiLabels(AsmL: PAasmOutput; Var LowLabel, HighLabel, LabelDif: Longint);
|
||||||
{Walks through the paasmlist to find the lowest and highest label number;
|
{Walks through the paasmlist to find the lowest and highest label number;
|
||||||
Since 0.9.3: also removes unused labels}
|
Since 0.9.3: also removes unused labels}
|
||||||
Var LabelFound: Boolean;
|
Var LabelFound: Boolean;
|
||||||
P, hp1: Pai;
|
P, hp1: Pai;
|
||||||
Begin
|
Begin
|
||||||
LabelFound := False;
|
LabelFound := False;
|
||||||
LoLab := MaxLongint;
|
LowLabel := MaxLongint;
|
||||||
HiLab := 0;
|
HighLabel := 0;
|
||||||
P := Pai(AsmL^.first);
|
P := Pai(AsmL^.first);
|
||||||
While Assigned(p) Do
|
While Assigned(p) Do
|
||||||
Begin
|
Begin
|
||||||
@ -603,10 +600,10 @@ Begin
|
|||||||
Then
|
Then
|
||||||
Begin
|
Begin
|
||||||
LabelFound := True;
|
LabelFound := True;
|
||||||
If (Pai_Label(p)^.l^.nb < LoLab) Then
|
If (Pai_Label(p)^.l^.nb < LowLabel) Then
|
||||||
LoLab := Pai_Label(p)^.l^.nb;
|
LowLabel := Pai_Label(p)^.l^.nb;
|
||||||
If (Pai_Label(p)^.l^.nb > HiLab) Then
|
If (Pai_Label(p)^.l^.nb > HighLabel) Then
|
||||||
HiLab := Pai_Label(p)^.l^.nb;
|
HighLabel := Pai_Label(p)^.l^.nb;
|
||||||
End
|
End
|
||||||
Else
|
Else
|
||||||
Begin
|
Begin
|
||||||
@ -619,8 +616,8 @@ Begin
|
|||||||
p := pai(p^.next);
|
p := pai(p^.next);
|
||||||
End;
|
End;
|
||||||
If LabelFound
|
If LabelFound
|
||||||
Then LabDif := HiLab+1-LoLab
|
Then LabelDif := HighLabel+1-LowLabel
|
||||||
Else LabDif := 0;
|
Else LabelDif := 0;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Procedure BuildLabelTable(AsmL: PAasmOutput; Var LabelTable: PLabelTable; LowLabel: Longint; Var LabelDif: Longint);
|
Procedure BuildLabelTable(AsmL: PAasmOutput; Var LabelTable: PLabelTable; LowLabel: Longint; Var LabelDif: Longint);
|
||||||
@ -640,11 +637,7 @@ Begin
|
|||||||
While Assigned(p) Do
|
While Assigned(p) Do
|
||||||
Begin
|
Begin
|
||||||
If (Pai(p)^.typ = ait_label) Then
|
If (Pai(p)^.typ = ait_label) Then
|
||||||
{$IfDef JmpAnal}
|
LabelTable^[Pai_Label(p)^.l^.nb-LowLabel].PaiObj := p;
|
||||||
LabelTable^[Pai_Label(p)^.l^.nb-LowLabel].p := p;
|
|
||||||
{$Else JmpAnal}
|
|
||||||
LabelTable^[Pai_Label(p)^.l^.nb-LowLabel] := p;
|
|
||||||
{$EndIf JmpAnal}
|
|
||||||
p := pai(p^.next);
|
p := pai(p^.next);
|
||||||
End;
|
End;
|
||||||
{$IfDef TP}
|
{$IfDef TP}
|
||||||
@ -849,7 +842,16 @@ Begin
|
|||||||
Else InternalError($db)
|
Else InternalError($db)
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Procedure DestroyReg(p1: pai; Reg: TRegister);
|
Procedure IncState(Var S: Word);
|
||||||
|
{Increases the state by 1, wraps around at $ffff to 0 (so we won't get
|
||||||
|
overflow errors}
|
||||||
|
Begin
|
||||||
|
If (s <> $ffff)
|
||||||
|
Then Inc(s)
|
||||||
|
Else s := 0
|
||||||
|
End;
|
||||||
|
|
||||||
|
Procedure DestroyReg(p1: PPaiProp; Reg: TRegister);
|
||||||
{Destroys the contents of the register Reg in the PPaiProp of P}
|
{Destroys the contents of the register Reg in the PPaiProp of P}
|
||||||
Var TmpState: Longint;
|
Var TmpState: Longint;
|
||||||
Begin
|
Begin
|
||||||
@ -857,11 +859,13 @@ Begin
|
|||||||
NrOfInstrSinceLastMod[Reg] := 0;
|
NrOfInstrSinceLastMod[Reg] := 0;
|
||||||
If (Reg >= R_EAX) And (Reg <= R_EDI)
|
If (Reg >= R_EAX) And (Reg <= R_EDI)
|
||||||
Then
|
Then
|
||||||
Begin
|
With p1^.Regs[Reg] Do
|
||||||
TmpState := PPaiProp(p1^.fileinfo.line)^.Regs[Reg].State+1;
|
Begin
|
||||||
FillChar(PPaiProp(p1^.fileinfo.line)^.Regs[Reg], SizeOf(TContent), 0);
|
IncState(State);
|
||||||
PPaiProp(p1^.fileinfo.line)^.Regs[Reg].State := TmpState;
|
TmpState := State;
|
||||||
End;
|
FillChar(p1^.Regs[Reg], SizeOf(TContent), 0);
|
||||||
|
State := TmpState;
|
||||||
|
End;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function OpsEqual(typ: Longint; op1, op2: Pointer): Boolean;
|
Function OpsEqual(typ: Longint; op1, op2: Pointer): Boolean;
|
||||||
@ -926,7 +930,7 @@ If (Ref.base <> R_NO) Or
|
|||||||
(RefsEqual(TReference(Pai386(StartMod)^.op1^), Ref) Or
|
(RefsEqual(TReference(Pai386(StartMod)^.op1^), Ref) Or
|
||||||
(Not(cs_UncertainOpts in AktSwitches) And
|
(Not(cs_UncertainOpts in AktSwitches) And
|
||||||
(NrOfMods <> 1)))
|
(NrOfMods <> 1)))
|
||||||
Then DestroyReg(p, Counter)
|
Then DestroyReg(PPaiProp(p^.fileinfo.line), Counter)
|
||||||
End
|
End
|
||||||
Else
|
Else
|
||||||
{writing something to a pointer location}
|
{writing something to a pointer location}
|
||||||
@ -941,9 +945,9 @@ If (Ref.base <> R_NO) Or
|
|||||||
(Pai386(StartMod)^.op1t = top_ref) And
|
(Pai386(StartMod)^.op1t = top_ref) And
|
||||||
(PReference(Pai386(StartMod)^.op1)^.base = ProcInfo.FramePointer))))
|
(PReference(Pai386(StartMod)^.op1)^.base = ProcInfo.FramePointer))))
|
||||||
Then
|
Then
|
||||||
DestroyReg(p, Counter) {we don't know what memory location the reference points to,
|
{we don't know what memory location the reference points to, so we just
|
||||||
so we just destroy every register which contains a memory
|
destroy every register which contains a memory reference}
|
||||||
reference}
|
DestroyReg(PPaiProp(p^.FileInfo.Line), Counter)
|
||||||
End
|
End
|
||||||
Else {the ref is a var name or we just have a reference an absolute offset}
|
Else {the ref is a var name or we just have a reference an absolute offset}
|
||||||
Begin
|
Begin
|
||||||
@ -953,22 +957,22 @@ If (Ref.base <> R_NO) Or
|
|||||||
(Not(cs_UncertainOpts in AktSwitches) Or
|
(Not(cs_UncertainOpts in AktSwitches) Or
|
||||||
RefsEqual(Ref,
|
RefsEqual(Ref,
|
||||||
TReference(Pai386(PPaiProp(p^.fileinfo.line)^.Regs[Counter].StartMod)^.op1^))) Then
|
TReference(Pai386(PPaiProp(p^.fileinfo.line)^.Regs[Counter].StartMod)^.op1^))) Then
|
||||||
DestroyReg(p, Counter)
|
DestroyReg(PPaiProp(p^.fileinfo.line), Counter)
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Procedure DestroyAllRegs(p: Pai);
|
Procedure DestroyAllRegs(p: PPaiProp);
|
||||||
Var Counter: TRegister;
|
Var Counter: TRegister;
|
||||||
Begin {initializes/desrtoys all registers}
|
Begin {initializes/desrtoys all registers}
|
||||||
For Counter := R_EAX To R_EDI Do
|
For Counter := R_EAX To R_EDI Do
|
||||||
DestroyReg(p, Counter);
|
DestroyReg(p, Counter);
|
||||||
PPaiProp(p^.fileinfo.line)^.DirFlag := F_Unknown;
|
p^.DirFlag := F_Unknown;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Procedure Destroy(PaiObj: Pai; opt: Longint; Op: Pointer);
|
Procedure Destroy(PaiObj: Pai; opt: Longint; Op: Pointer);
|
||||||
Begin
|
Begin
|
||||||
Case opt Of
|
Case opt Of
|
||||||
top_reg: DestroyReg(PaiObj, TRegister(Op));
|
top_reg: DestroyReg(PPaiProp(PaiObj^.fileinfo.line), TRegister(Op));
|
||||||
top_ref: DestroyRefs(PaiObj, TReference(Op^), R_NO);
|
top_ref: DestroyRefs(PaiObj, TReference(Op^), R_NO);
|
||||||
top_symbol:;
|
top_symbol:;
|
||||||
End;
|
End;
|
||||||
@ -986,10 +990,10 @@ Function DoDFAPass2(First: Pai): Pai;
|
|||||||
contents for the instructions starting with p. Returns the last pai which has
|
contents for the instructions starting with p. Returns the last pai which has
|
||||||
been processed}
|
been processed}
|
||||||
Var
|
Var
|
||||||
TmpProp: PPaiProp;
|
CurProp: PPaiProp;
|
||||||
Cnt, InstrCnt: Longint;
|
Cnt, InstrCnt, TmpState: Longint;
|
||||||
InstrProp: TAsmInstrucProp;
|
InstrProp: TAsmInstrucProp;
|
||||||
p: Pai;
|
p, hp: Pai;
|
||||||
TmpRef: TReference;
|
TmpRef: TReference;
|
||||||
TmpReg: TRegister;
|
TmpReg: TRegister;
|
||||||
Begin
|
Begin
|
||||||
@ -999,24 +1003,217 @@ Begin
|
|||||||
While Assigned(p) Do
|
While Assigned(p) Do
|
||||||
Begin
|
Begin
|
||||||
DoDFAPass2 := p;
|
DoDFAPass2 := p;
|
||||||
If (InstrCnt <= NrOfPaiFast)
|
{$IfDef TP}
|
||||||
Then TmpProp := @PaiPropBlock^[InstrCnt]
|
If (InstrCnt <= NrOfPaiFast) Then
|
||||||
Else New(TmpProp);
|
{$EndIf TP}
|
||||||
|
CurProp := @PaiPropBlock^[InstrCnt]
|
||||||
|
{$IfDef TP}
|
||||||
|
Else New(CurProp)
|
||||||
|
{$EndIf TP}
|
||||||
|
;
|
||||||
If (p <> First)
|
If (p <> First)
|
||||||
Then TmpProp^ := PPaiProp(Pai(p^.previous)^.fileinfo.line)^
|
Then
|
||||||
Else FillChar(TmpProp^, SizeOf(TmpProp^), 0);
|
{$ifndef TP}
|
||||||
TmpProp^.linesave := p^.fileinfo.line;
|
Begin
|
||||||
PPaiProp(p^.fileinfo.line) := TmpProp;
|
If (p^.Typ <> ait_label) Then
|
||||||
|
{$endif TP}
|
||||||
|
Begin
|
||||||
|
CurProp^.Regs := PPaiProp(Pai(p^.previous)^.fileinfo.line)^.Regs;
|
||||||
|
CurProp^.DirFlag := PPaiProp(Pai(p^.previous)^.fileinfo.line)^.DirFlag
|
||||||
|
End
|
||||||
|
{$ifndef TP}
|
||||||
|
End
|
||||||
|
{$endif TP}
|
||||||
|
Else
|
||||||
|
Begin
|
||||||
|
FillChar(CurProp^, SizeOf(CurProp^), 0);
|
||||||
|
{ For TmpReg := R_EAX to R_EDI Do
|
||||||
|
CurProp^.Regs[TmpReg].State := 1;}
|
||||||
|
End;
|
||||||
|
CurProp^.CanBeRemoved := False;
|
||||||
|
{$IfDef TP}
|
||||||
|
CurProp^.linesave := p^.fileinfo.line;
|
||||||
|
PPaiProp(p^.fileinfo.line) := CurProp;
|
||||||
|
{$EndIf}
|
||||||
For TmpReg := R_EAX To R_EDI Do
|
For TmpReg := R_EAX To R_EDI Do
|
||||||
Inc(NrOfInstrSinceLastMod[TmpReg]);
|
Inc(NrOfInstrSinceLastMod[TmpReg]);
|
||||||
Case p^.typ Of
|
Case p^.typ Of
|
||||||
ait_label: DestroyAllRegs(p);
|
ait_label:
|
||||||
ait_labeled_instruction
|
{$Ifdef TP}
|
||||||
|
DestroyAllRegs(CurProp);
|
||||||
|
{$Else TP}
|
||||||
|
Begin
|
||||||
|
With LTable^[Pai_Label(p)^.l^.nb-LoLab] Do
|
||||||
|
{$IfDef AnalyzeLoops}
|
||||||
|
If (RefsFound = Pai_Label(p)^.l^.RefCount)
|
||||||
|
{$Else AnalyzeLoops}
|
||||||
|
If (JmpsProcessed = Pai_Label(p)^.l^.RefCount)
|
||||||
|
{$EndIf AnalyzeLoops}
|
||||||
|
Then
|
||||||
|
{all jumps to this label have been found}
|
||||||
|
{$IfDef AnalyzeLoops}
|
||||||
|
If (JmpsProcessed > 0)
|
||||||
|
Then
|
||||||
|
{$EndIf}
|
||||||
|
{we've processed at least one jump to this label}
|
||||||
|
Begin
|
||||||
|
If Not(GetLastInstruction(p, hp) And
|
||||||
|
(hp^.typ = ait_labeled_instruction) And
|
||||||
|
(Pai_Labeled(hp)^._operator = A_JMP))
|
||||||
|
Then
|
||||||
|
{previous instruction not a JMP -> the contents of the registers after the
|
||||||
|
previous intruction has been executed have to be taken into account as well}
|
||||||
|
For TmpReg := R_EAX to R_EDI Do
|
||||||
|
Begin
|
||||||
|
If (CurProp^.Regs[TmpReg].State <>
|
||||||
|
PPaiProp(Pai(p^.Previous)^.FileInfo.Line)^.Regs[TmpReg].State)
|
||||||
|
Then DestroyReg(CurProp, TmpReg)
|
||||||
|
End
|
||||||
|
End
|
||||||
|
{$IfDef AnalyzeLoops}
|
||||||
|
Else
|
||||||
|
{a label from a backward jump (e.g. a loop), no jump to this label has
|
||||||
|
already been processed}
|
||||||
|
If Not(GetLastInstruction(p, hp) And
|
||||||
|
(hp^.typ = ait_labeled_instruction) And
|
||||||
|
(Pai_Labeled(hp)^._operator = A_JMP))
|
||||||
|
Then
|
||||||
|
{previous instruction not a jmp, so keep all the registers' contents from the
|
||||||
|
previous instruction}
|
||||||
|
Begin
|
||||||
|
CurProp^.Regs := PPaiProp(Pai(p^.Previous)^.FileInfo.Line)^.Regs;
|
||||||
|
CurProp^.DirFlag := PPaiProp(Pai(p^.Previous)^.FileInfo.Line)^.DirFlag;
|
||||||
|
End
|
||||||
|
Else
|
||||||
|
{previous instruction a jmp and no jump to this label processed yet}
|
||||||
|
Begin
|
||||||
|
hp := p;
|
||||||
|
Cnt := InstrCnt;
|
||||||
|
{continue until we find a jump to the label or a label which has already
|
||||||
|
been processed}
|
||||||
|
While GetNextInstruction(hp, hp) And
|
||||||
|
Not((hp^.typ = ait_labeled_instruction) And
|
||||||
|
(Pai_Labeled(hp)^.lab^.nb = Pai_Label(p)^.l^.nb)) And
|
||||||
|
Not((hp^.typ = ait_label) And
|
||||||
|
(LTable^[Pai_Label(hp)^.l^.nb-LoLab].RefsFound
|
||||||
|
= Pai_Label(hp)^.l^.RefCount) And
|
||||||
|
(LTable^[Pai_Label(hp)^.l^.nb-LoLab].JmpsProcessed > 0)) Do
|
||||||
|
Inc(Cnt);
|
||||||
|
If (hp^.typ = ait_label)
|
||||||
|
Then
|
||||||
|
{there's a processed label after the current one}
|
||||||
|
Begin
|
||||||
|
CurProp^.Regs := PaiPropBlock^[Cnt].Regs;
|
||||||
|
CurProp^.DirFlag := PaiPropBlock^[Cnt].DirFlag;
|
||||||
|
End
|
||||||
|
Else
|
||||||
|
{there's no label anymore after the current one, or they haven't been
|
||||||
|
processed yet}
|
||||||
|
Begin
|
||||||
|
CurProp^.Regs := PPaiProp(Pai(p^.Previous)^.FileInfo.Line)^.Regs;
|
||||||
|
CurProp^.DirFlag := PPaiProp(Pai(p^.Previous)^.FileInfo.Line)^.DirFlag;
|
||||||
|
DestroyAllRegs(PPaiProp(Pai(p^.Previous)^.FileInfo.Line))
|
||||||
|
End
|
||||||
|
End
|
||||||
|
{$EndIf AnalyzeLoops}
|
||||||
|
Else
|
||||||
|
{not all references to this label have been found, so destroy all registers}
|
||||||
|
Begin
|
||||||
|
CurProp^.Regs := PPaiProp(Pai(p^.Previous)^.FileInfo.Line)^.Regs;
|
||||||
|
CurProp^.DirFlag := PPaiProp(Pai(p^.Previous)^.FileInfo.Line)^.DirFlag;
|
||||||
|
DestroyAllRegs(CurProp)
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
{$EndIf TP}
|
||||||
|
ait_labeled_instruction:
|
||||||
|
{$IfDef TP}
|
||||||
|
;
|
||||||
|
{$Else TP}
|
||||||
|
With LTable^[Pai_Labeled(p)^.lab^.nb-LoLab] Do
|
||||||
|
If (RefsFound = Pai_Labeled(p)^.lab^.RefCount) Then
|
||||||
|
Begin
|
||||||
|
If (InstrCnt < InstrNr)
|
||||||
|
Then
|
||||||
|
{forward jump}
|
||||||
|
If (JmpsProcessed = 0) Then
|
||||||
|
{no jump to this label has been processed yet}
|
||||||
|
Begin
|
||||||
|
PaiPropBlock^[InstrNr].Regs := CurProp^.Regs;
|
||||||
|
PaiPropBlock^[InstrNr].DirFlag := CurProp^.DirFlag;
|
||||||
|
Inc(JmpsProcessed);
|
||||||
|
End
|
||||||
|
Else
|
||||||
|
Begin
|
||||||
|
For TmpReg := R_EAX to R_EDI Do
|
||||||
|
If (PaiPropBlock^[InstrNr].Regs[TmpReg].State <>
|
||||||
|
CurProp^.Regs[TmpReg].State) Then
|
||||||
|
DestroyReg(@PaiPropBlock^[InstrNr], TmpReg);
|
||||||
|
Inc(JmpsProcessed);
|
||||||
|
End
|
||||||
|
{$ifdef AnalyzeLoops}
|
||||||
|
Else
|
||||||
|
{backward jump, a loop for example}
|
||||||
|
{ If (JmpsProcessed > 0) Or
|
||||||
|
Not(GetLastInstruction(PaiObj, hp) And
|
||||||
|
(hp^.typ = ait_labeled_instruction) And
|
||||||
|
(Pai_Labeled(hp)^._operator = A_JMP))
|
||||||
|
Then}
|
||||||
|
{instruction prior to label is not a jmp, or at least one jump to the label
|
||||||
|
has yet been processed}
|
||||||
|
Begin
|
||||||
|
Inc(JmpsProcessed);
|
||||||
|
For TmpReg := R_EAX to R_EDI Do
|
||||||
|
If (PaiPropBlock^[InstrNr].Regs[TmpReg].State <>
|
||||||
|
CurProp^.Regs[TmpReg].State)
|
||||||
|
Then
|
||||||
|
Begin
|
||||||
|
TmpState := PaiPropBlock^[InstrNr].Regs[TmpReg].State;
|
||||||
|
Cnt := InstrNr;
|
||||||
|
While (TmpState = PaiPropBlock^[Cnt].Regs[TmpReg].State) Do
|
||||||
|
Begin
|
||||||
|
DestroyReg(@PaiPropBlock^[Cnt], TmpReg);
|
||||||
|
Inc(Cnt);
|
||||||
|
End;
|
||||||
|
While (Cnt <= InstrCnt) Do
|
||||||
|
Begin
|
||||||
|
Inc(PaiPropBlock^[Cnt].Regs[TmpReg].State);
|
||||||
|
Inc(Cnt)
|
||||||
|
End
|
||||||
|
End;
|
||||||
|
End
|
||||||
|
{ Else
|
||||||
|
{instruction prior to label is a jmp and no jumps to the label have yet been
|
||||||
|
processed}
|
||||||
|
Begin
|
||||||
|
Inc(JmpsProcessed);
|
||||||
|
For TmpReg := R_EAX to R_EDI Do
|
||||||
|
Begin
|
||||||
|
TmpState := PaiPropBlock^[InstrNr].Regs[TmpReg].State;
|
||||||
|
Cnt := InstrNr;
|
||||||
|
While (TmpState = PaiPropBlock^[Cnt].Regs[TmpReg].State) Do
|
||||||
|
Begin
|
||||||
|
PaiPropBlock^[Cnt].Regs[TmpReg] := CurProp^.Regs[TmpReg];
|
||||||
|
Inc(Cnt);
|
||||||
|
End;
|
||||||
|
TmpState := PaiPropBlock^[InstrNr].Regs[TmpReg].State;
|
||||||
|
While (TmpState = PaiPropBlock^[Cnt].Regs[TmpReg].State) Do
|
||||||
|
Begin
|
||||||
|
DestroyReg(@PaiPropBlock^[Cnt], TmpReg);
|
||||||
|
Inc(Cnt);
|
||||||
|
End;
|
||||||
|
While (Cnt <= InstrCnt) Do
|
||||||
|
Begin
|
||||||
|
Inc(PaiPropBlock^[Cnt].Regs[TmpReg].State);
|
||||||
|
Inc(Cnt)
|
||||||
|
End
|
||||||
|
End
|
||||||
|
End}
|
||||||
|
{$endif AnalyzeLoops}
|
||||||
|
End;
|
||||||
|
{$EndIf TP}
|
||||||
{$ifdef GDB}
|
{$ifdef GDB}
|
||||||
, ait_stabs, ait_stabn,
|
ait_stabs, ait_stabn, ait_stab_function_name:;
|
||||||
ait_stab_function_name
|
|
||||||
{$endif GDB}
|
{$endif GDB}
|
||||||
:; {nothing changes}
|
|
||||||
{$ifdef regalloc}
|
{$ifdef regalloc}
|
||||||
ait_regalloc, ait_regdealloc:;
|
ait_regalloc, ait_regdealloc:;
|
||||||
{$endif regalloc}
|
{$endif regalloc}
|
||||||
@ -1031,11 +1228,11 @@ Begin
|
|||||||
Case Pai386(p)^.op2t Of
|
Case Pai386(p)^.op2t Of
|
||||||
Top_Reg:
|
Top_Reg:
|
||||||
Begin
|
Begin
|
||||||
DestroyReg(p, TRegister(Pai386(p)^.op2));
|
DestroyReg(CurProp, TRegister(Pai386(p)^.op2));
|
||||||
{ TmpProp^.Regs[TRegister(Pai386(p)^.op2)] :=
|
{ CurProp^.Regs[TRegister(Pai386(p)^.op2)] :=
|
||||||
TmpProp^.Regs[TRegister(Pai386(p)^.op1)];
|
CurProp^.Regs[TRegister(Pai386(p)^.op1)];
|
||||||
If (TmpProp^.Regs[TRegister(Pai386(p)^.op2)].ModReg = R_NO) Then
|
If (CurProp^.Regs[TRegister(Pai386(p)^.op2)].ModReg = R_NO) Then
|
||||||
TmpProp^.Regs[TRegister(Pai386(p)^.op2)].ModReg :=
|
CurProp^.Regs[TRegister(Pai386(p)^.op2)].ModReg :=
|
||||||
Tregister(Pai386(p)^.op1);}
|
Tregister(Pai386(p)^.op1);}
|
||||||
End;
|
End;
|
||||||
Top_Ref: DestroyRefs(p, TReference(Pai386(p)^.op2^), TRegister(Pai386(p)^.op1));
|
Top_Ref: DestroyRefs(p, TReference(Pai386(p)^.op2^), TRegister(Pai386(p)^.op1));
|
||||||
@ -1048,7 +1245,7 @@ Begin
|
|||||||
Begin
|
Begin
|
||||||
With PPaiProp(Pai(p)^.fileinfo.line)^.Regs[TmpReg] Do
|
With PPaiProp(Pai(p)^.fileinfo.line)^.Regs[TmpReg] Do
|
||||||
Begin
|
Begin
|
||||||
Inc(State);
|
IncState(State);
|
||||||
If (typ <> Con_Ref) Then
|
If (typ <> Con_Ref) Then
|
||||||
Begin
|
Begin
|
||||||
typ := Con_Ref;
|
typ := Con_Ref;
|
||||||
@ -1064,7 +1261,7 @@ Begin
|
|||||||
End
|
End
|
||||||
Else
|
Else
|
||||||
Begin
|
Begin
|
||||||
DestroyReg(p, TmpReg);
|
DestroyReg(CurProp, TmpReg);
|
||||||
With PPaiProp(Pai(p)^.fileinfo.line)^.Regs[TmpReg] Do
|
With PPaiProp(Pai(p)^.fileinfo.line)^.Regs[TmpReg] Do
|
||||||
Begin
|
Begin
|
||||||
Typ := Con_Ref;
|
Typ := Con_Ref;
|
||||||
@ -1079,11 +1276,11 @@ Begin
|
|||||||
Top_Reg:
|
Top_Reg:
|
||||||
Begin
|
Begin
|
||||||
TmpReg := Reg32(TRegister(Pai386(p)^.op2));
|
TmpReg := Reg32(TRegister(Pai386(p)^.op2));
|
||||||
With TmpProp^.Regs[TmpReg] Do
|
With CurProp^.Regs[TmpReg] Do
|
||||||
Begin
|
Begin
|
||||||
{it doesn't matter that the state is changed,
|
{it doesn't matter that the state is changed,
|
||||||
it isn't looked at when removing constant reloads}
|
it isn't looked at when removing constant reloads}
|
||||||
DestroyReg(p, TmpReg);
|
DestroyReg(CurProp, TmpReg);
|
||||||
typ := Con_Const;
|
typ := Con_Const;
|
||||||
StartMod := Pai386(p)^.op1;
|
StartMod := Pai386(p)^.op1;
|
||||||
End
|
End
|
||||||
@ -1100,16 +1297,16 @@ Begin
|
|||||||
If (Pai386(p)^.Op2t = top_none)
|
If (Pai386(p)^.Op2t = top_none)
|
||||||
Then
|
Then
|
||||||
Begin
|
Begin
|
||||||
DestroyReg(p, R_EAX);
|
DestroyReg(CurProp, R_EAX);
|
||||||
DestroyReg(p, R_EDX)
|
DestroyReg(CurProp, R_EDX)
|
||||||
End
|
End
|
||||||
Else
|
Else
|
||||||
Begin
|
Begin
|
||||||
If (Pai386(p)^.Op2t = top_reg) Then
|
If (Pai386(p)^.Op2t = top_reg) Then
|
||||||
DestroyReg(p, TRegister(Pai386(p)^.Op2));
|
DestroyReg(CurProp, TRegister(Pai386(p)^.Op2));
|
||||||
End
|
End
|
||||||
Else If (Pai386(p)^.Op3t = top_reg) Then
|
Else If (Pai386(p)^.Op3t = top_reg) Then
|
||||||
DestroyReg(p, TRegister(longint(twowords(Pai386(p)^.Op2).word2)));
|
DestroyReg(CurProp, TRegister(longint(twowords(Pai386(p)^.Op2).word2)));
|
||||||
End;
|
End;
|
||||||
A_XOR:
|
A_XOR:
|
||||||
Begin
|
Begin
|
||||||
@ -1118,9 +1315,9 @@ Begin
|
|||||||
(Pai386(p)^.op1 = Pai386(p)^.op2)
|
(Pai386(p)^.op1 = Pai386(p)^.op2)
|
||||||
Then
|
Then
|
||||||
Begin
|
Begin
|
||||||
DestroyReg(p, Tregister(Pai386(p)^.op1));
|
DestroyReg(CurProp, Tregister(Pai386(p)^.op1));
|
||||||
TmpProp^.Regs[Reg32(Tregister(Pai386(p)^.op1))].typ := Con_Const;
|
CurProp^.Regs[Reg32(Tregister(Pai386(p)^.op1))].typ := Con_Const;
|
||||||
TmpProp^.Regs[Reg32(Tregister(Pai386(p)^.op1))].StartMod := Pointer(0)
|
CurProp^.Regs[Reg32(Tregister(Pai386(p)^.op1))].StartMod := Pointer(0)
|
||||||
End
|
End
|
||||||
Else Destroy(p, Pai386(p)^.op2t, Pai386(p)^.op2);
|
Else Destroy(p, Pai386(p)^.op2t, Pai386(p)^.op2);
|
||||||
End
|
End
|
||||||
@ -1131,7 +1328,7 @@ Begin
|
|||||||
For Cnt := 1 To InstrProp.NCh Do
|
For Cnt := 1 To InstrProp.NCh Do
|
||||||
Case InstrProp.Ch[Cnt] Of
|
Case InstrProp.Ch[Cnt] Of
|
||||||
C_None:;
|
C_None:;
|
||||||
C_EAX..C_EDI: DestroyReg(p, TCh2Reg(InstrProp.Ch[Cnt]));
|
C_EAX..C_EDI: DestroyReg(CurProp, TCh2Reg(InstrProp.Ch[Cnt]));
|
||||||
C_CDirFlag: PPaiProp(Pai(p)^.fileinfo.line)^.DirFlag := F_NotSet;
|
C_CDirFlag: PPaiProp(Pai(p)^.fileinfo.line)^.DirFlag := F_NotSet;
|
||||||
C_SDirFlag: PPaiProp(Pai(p)^.fileinfo.line)^.DirFlag := F_Set;
|
C_SDirFlag: PPaiProp(Pai(p)^.fileinfo.line)^.DirFlag := F_Set;
|
||||||
C_Op1: Destroy(p, Pai386(p)^.op1t, Pai386(p)^.op1);
|
C_Op1: Destroy(p, Pai386(p)^.op1t, Pai386(p)^.op1);
|
||||||
@ -1147,14 +1344,14 @@ Begin
|
|||||||
End
|
End
|
||||||
Else
|
Else
|
||||||
Begin
|
Begin
|
||||||
DestroyAllRegs(p);
|
DestroyAllRegs(CurProp);
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
End
|
End
|
||||||
Else
|
Else
|
||||||
Begin
|
Begin
|
||||||
DestroyAllRegs(p);
|
DestroyAllRegs(CurProp);
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
Inc(InstrCnt);
|
Inc(InstrCnt);
|
||||||
@ -1167,11 +1364,35 @@ Function InitDFAPass2(AsmL: PAasmOutput): Boolean;
|
|||||||
TP, returns False if not enough memory is available for the optimizer in all
|
TP, returns False if not enough memory is available for the optimizer in all
|
||||||
cases}
|
cases}
|
||||||
Var p: Pai;
|
Var p: Pai;
|
||||||
|
Count: Longint;
|
||||||
|
TmpStr: String;
|
||||||
Begin
|
Begin
|
||||||
P := Pai(AsmL^.First);
|
P := Pai(AsmL^.First);
|
||||||
NrOfPaiObjs := 1;
|
NrOfPaiObjs := 1;
|
||||||
While (P <> Pai(AsmL^.last)) Do
|
While (P <> Pai(AsmL^.last)) Do
|
||||||
Begin
|
Begin
|
||||||
|
{$IfNDef TP}
|
||||||
|
Case P^.Typ Of
|
||||||
|
ait_labeled_instruction:
|
||||||
|
begin
|
||||||
|
If (Pai_Labeled(P)^.lab^.nb >= LoLab) And
|
||||||
|
(Pai_Labeled(P)^.lab^.nb <= HiLab) Then
|
||||||
|
Inc(LTable^[Pai_Labeled(P)^.lab^.nb-LoLab].RefsFound);
|
||||||
|
end;
|
||||||
|
ait_label:
|
||||||
|
Begin
|
||||||
|
LTable^[Pai_Label(P)^.l^.nb-LoLab].InstrNr := NrOfPaiObjs
|
||||||
|
End;
|
||||||
|
{ ait_instruction:
|
||||||
|
Begin
|
||||||
|
If (Pai386(p)^._operator = A_PUSH) And
|
||||||
|
(Pai386(p)^.op1t = top_symbol) And
|
||||||
|
(PCSymbol(Pai386(p)^.op1)^.offset = 0) Then
|
||||||
|
Begin
|
||||||
|
TmpStr := StrPas(PCSymbol(Pai386(p)^.op1)^.symbol);
|
||||||
|
If}
|
||||||
|
End;
|
||||||
|
{$EndIf TP}
|
||||||
Inc(NrOfPaiObjs);
|
Inc(NrOfPaiObjs);
|
||||||
P := Pai(P^.next)
|
P := Pai(P^.next)
|
||||||
End;
|
End;
|
||||||
@ -1195,6 +1416,13 @@ Begin
|
|||||||
InitDFAPass2 := True;
|
InitDFAPass2 := True;
|
||||||
GetMem(PaiPropBlock, NrOfPaiObjs*(((SizeOf(TPaiProp)+3)div 4)*4));
|
GetMem(PaiPropBlock, NrOfPaiObjs*(((SizeOf(TPaiProp)+3)div 4)*4));
|
||||||
NrOfPaiFast := NrOfPaiObjs;
|
NrOfPaiFast := NrOfPaiObjs;
|
||||||
|
p := Pai(AsmL^.First);
|
||||||
|
For Count := 1 To NrOfPaiObjs Do
|
||||||
|
Begin
|
||||||
|
PaiPropBlock^[Count].LineSave := p^.fileinfo.line;
|
||||||
|
PPaiProp(p^.fileinfo.line) := @PaiPropBlock^[Count];
|
||||||
|
p := Pai(p^.next);
|
||||||
|
End;
|
||||||
{$EndIf TP}
|
{$EndIf TP}
|
||||||
End;
|
End;
|
||||||
|
|
||||||
@ -1205,4 +1433,14 @@ Begin
|
|||||||
Else DFAPass2 := Nil;
|
Else DFAPass2 := Nil;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
Procedure ShutDownDFA;
|
||||||
|
Begin
|
||||||
|
If LabDif <> 0 Then
|
||||||
|
FreeMem(LTable, LabDif*SizeOf(TLabelTableItem));
|
||||||
|
End;
|
||||||
|
|
||||||
End.
|
End.
|
||||||
|
|
||||||
|
{
|
||||||
|
$log $
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user