+ jump analyzing

This commit is contained in:
Jonas Maebe 1998-08-04 16:28:15 +00:00
parent 2c0d277164
commit 66feedde08

View File

@ -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 $
}