mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-21 09:49:28 +02:00
* small fix for uncertain optimizations & more cleaning up
This commit is contained in:
parent
0e770798da
commit
fccf4109e0
@ -44,108 +44,30 @@ Function CheckSequence(p: Pai; Reg: TRegister; Var Found: Longint): Boolean;
|
|||||||
Found holds the number of instructions between StartMod and EndMod and false
|
Found holds the number of instructions between StartMod and EndMod and false
|
||||||
is returned}
|
is returned}
|
||||||
Var hp2, hp3, EndMod: Pai;
|
Var hp2, hp3, EndMod: Pai;
|
||||||
TmpResult: Boolean;
|
|
||||||
RegsNotYetChecked: Set Of TRegister;
|
|
||||||
Counter: Byte;
|
Counter: Byte;
|
||||||
|
|
||||||
Function NoChangedRegInRef(oldp, newp: Pai): Boolean;
|
|
||||||
Var TmpP: Pai;
|
|
||||||
{checks if the first operator of newp is a reference and in that case checks
|
|
||||||
whether that reference includes regs that have been changed since oldp. This
|
|
||||||
to avoid wrong optimizations like
|
|
||||||
|
|
||||||
movl 8(%epb), %eax movl 8(%epb), %eax
|
|
||||||
movl 12(%epb), %edx movl 12(%epb), %edx
|
|
||||||
movl (%eax,%edx,1), %edi movl (%eax,%edx,1), %edi
|
|
||||||
pushl %edi being converted to pushl %edi
|
|
||||||
movl 8(%epb), %eax movl 16(%ebp), %edx
|
|
||||||
movl 16(%epb), %edx pushl %edi
|
|
||||||
movl (%eax,%edx,1), %edi
|
|
||||||
pushl %edi
|
|
||||||
|
|
||||||
because first is checked whether %eax isn't changed (it isn't) and
|
|
||||||
consequently all instructions containg %eax are removed}
|
|
||||||
Begin
|
|
||||||
TmpResult := True;
|
|
||||||
If (Pai(NewP)^.typ = ait_instruction) Then
|
|
||||||
Case Pai386(NewP)^.op1t Of
|
|
||||||
Top_Reg:
|
|
||||||
If (Reg32(TRegister(Pai386(NewP)^.op1)) in RegsNotYetChecked) Then
|
|
||||||
Begin
|
|
||||||
RegsNotYetChecked := RegsNotYetChecked - [Reg32(TRegister(Pai386(NewP)^.op1))];
|
|
||||||
TmpP := NewP;
|
|
||||||
While GetLastInstruction(TmpP, TmpP) And
|
|
||||||
PPaiProp(TmpP^.fileinfo.Line)^.CanBeRemoved Do;
|
|
||||||
TmpResult := Assigned(TmpP) And
|
|
||||||
RegsSameContent(oldp, TmpP, Reg32(TRegister(Pai386(Newp)^.op1)))
|
|
||||||
End;
|
|
||||||
Top_Ref:
|
|
||||||
With TReference(Pai386(NewP)^.op1^) Do
|
|
||||||
Begin
|
|
||||||
If (Base in RegsNotYetChecked) And
|
|
||||||
(Base <> R_NO) Then
|
|
||||||
Begin
|
|
||||||
RegsNotYetChecked := RegsNotYetChecked - [Base];
|
|
||||||
TmpP := NewP;
|
|
||||||
While GetLastInstruction(TmpP, TmpP) And
|
|
||||||
PPaiProp(TmpP^.fileinfo.Line)^.CanBeRemoved Do;
|
|
||||||
TmpResult := Assigned(TmpP) And
|
|
||||||
RegsSameContent(oldp, TmpP, Base)
|
|
||||||
End;
|
|
||||||
If TmpResult And
|
|
||||||
(Index <> R_NO) And
|
|
||||||
(Index in RegsNotYetChecked) Then
|
|
||||||
Begin
|
|
||||||
RegsNotYetChecked := RegsNotYetChecked - [Index];
|
|
||||||
TmpP := NewP;
|
|
||||||
While GetLastInstruction(TmpP, TmpP) And
|
|
||||||
PPaiProp(TmpP^.fileinfo.Line)^.CanBeRemoved Do;
|
|
||||||
TmpResult := Assigned(TmpP) And
|
|
||||||
RegsSameContent(oldp, TmpP, Index);
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
NoChangedRegInRef := TmpResult;
|
|
||||||
End;
|
|
||||||
|
|
||||||
Begin {CheckSequence}
|
Begin {CheckSequence}
|
||||||
Reg := Reg32(Reg);
|
Reg := Reg32(Reg);
|
||||||
Found := 0;
|
Found := 0;
|
||||||
GetLastInstruction(p, hp3);
|
hp3 := p;
|
||||||
|
While GetLastInstruction(hp3, hp3) And
|
||||||
|
PPAiProp(hp3^.fileinfo.line)^.CanBeRemoved Do;
|
||||||
hp2 := PPaiProp(hp3^.fileinfo.line)^.Regs[Reg].StartMod;
|
hp2 := PPaiProp(hp3^.fileinfo.line)^.Regs[Reg].StartMod;
|
||||||
EndMod := PPaiProp(hp3^.fileinfo.line)^.Regs[Reg].StartMod;
|
EndMod := hp2;
|
||||||
If (PPaiProp(hp3^.fileinfo.line)^.Regs[Reg].NrOfMods = 1)
|
If (PPaiProp(hp3^.fileinfo.line)^.Regs[Reg].NrOfMods = 1)
|
||||||
Then Counter := 1
|
Then Counter := 1
|
||||||
Else
|
Else
|
||||||
For Counter := 2 to PPaiProp(hp3^.fileinfo.line)^.Regs[Reg].NrOfMods Do
|
For Counter := 2 to PPaiProp(hp3^.fileinfo.line)^.Regs[Reg].NrOfMods Do
|
||||||
GetNextInstruction(EndMod, EndMod);
|
GetNextInstruction(EndMod, EndMod);
|
||||||
hp3 := p;
|
hp3 := p;
|
||||||
RegsNotYetChecked := [R_EAX..R_EDI];
|
|
||||||
While (Found <> Counter) And
|
While (Found <> Counter) And
|
||||||
InstructionsEqual(hp2, hp3) And
|
InstructionsEqual(hp2, hp3) Do
|
||||||
NoChangedRegInRef(EndMod, hp3) Do
|
|
||||||
Begin
|
Begin
|
||||||
If (hp2^.typ = ait_instruction) And
|
|
||||||
(Pai386(hp2)^._operator in [a_mov, a_movsx, a_movzx]) And
|
|
||||||
(Pai386(hp2)^.op2t = top_reg)
|
|
||||||
Then RegsNotYetChecked := RegsNotYetChecked -
|
|
||||||
[Reg32(TRegister(Pai386(hp2)^.op2))];
|
|
||||||
GetNextInstruction(hp2, hp2);
|
GetNextInstruction(hp2, hp2);
|
||||||
GetNextInstruction(hp3, hp3);
|
GetNextInstruction(hp3, hp3);
|
||||||
Inc(Found)
|
Inc(Found)
|
||||||
End;
|
End;
|
||||||
If (Found <> Counter)
|
If (Found <> Counter)
|
||||||
Then
|
Then
|
||||||
{hack to be able to optimize
|
|
||||||
mov (mem), reg
|
|
||||||
mov (reg), reg
|
|
||||||
mov (reg), reg [*]
|
|
||||||
test reg, reg and the oposite (where the marked instructions are
|
|
||||||
jne l1 switched)
|
|
||||||
mov (mem), reg
|
|
||||||
mov (reg), reg
|
|
||||||
movzx (reg), reg [*]}
|
|
||||||
|
|
||||||
Begin
|
Begin
|
||||||
If ((Found+1) = Counter) And
|
If ((Found+1) = Counter) And
|
||||||
Assigned(hp2) And
|
Assigned(hp2) And
|
||||||
@ -159,9 +81,19 @@ Begin {CheckSequence}
|
|||||||
(Pai386(hp3)^.op1t = top_ref) And
|
(Pai386(hp3)^.op1t = top_ref) And
|
||||||
(Pai386(hp3)^.op2t = top_reg) And
|
(Pai386(hp3)^.op2t = top_reg) And
|
||||||
(Pai386(hp2)^._operator <> Pai386(hp3)^._operator) And
|
(Pai386(hp2)^._operator <> Pai386(hp3)^._operator) And
|
||||||
RefsEqual(TReference(Pai386(hp2)^.op1^),TReference(Pai386(hp3)^.op1^)) And
|
RefsEqual(TReference(Pai386(hp2)^.op1^),TReference(Pai386(hp3)^.op1^))
|
||||||
NoChangedRegInRef(EndMod, hp3)
|
|
||||||
Then
|
Then
|
||||||
|
|
||||||
|
{hack to be able to optimize
|
||||||
|
mov (mem), reg
|
||||||
|
mov (reg), reg
|
||||||
|
mov (reg), reg [*]
|
||||||
|
test reg, reg and the oposite (where the marked instructions are
|
||||||
|
jne l1 switched)
|
||||||
|
mov (mem), reg
|
||||||
|
mov (reg), reg
|
||||||
|
movzx (reg), reg [*]}
|
||||||
|
|
||||||
If (Pai386(hp2)^._operator = A_MOV)
|
If (Pai386(hp2)^._operator = A_MOV)
|
||||||
Then
|
Then
|
||||||
Begin
|
Begin
|
||||||
@ -392,8 +324,8 @@ End.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.6 1998-09-17 21:54:21 jonas
|
Revision 1.7 1998-09-20 17:12:35 jonas
|
||||||
* big error (with little consequences) corrected in NoChangedRegInRef
|
* small fix for uncertain optimizations & more cleaning up
|
||||||
|
|
||||||
Revision 1.5 1998/09/16 17:59:59 jonas
|
Revision 1.5 1998/09/16 17:59:59 jonas
|
||||||
* optimizer now completely dependant on GetNext/GetLast instruction, works again with -dRegAlloc
|
* optimizer now completely dependant on GetNext/GetLast instruction, works again with -dRegAlloc
|
||||||
|
@ -59,7 +59,6 @@ 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);}
|
||||||
|
|
||||||
|
|
||||||
{******************************* Constants *******************************}
|
{******************************* Constants *******************************}
|
||||||
|
|
||||||
Const
|
Const
|
||||||
@ -71,9 +70,7 @@ Const
|
|||||||
{$ifdef GDB}
|
{$ifdef GDB}
|
||||||
,ait_stabs, ait_stabn, ait_stab_function_name
|
,ait_stabs, ait_stabn, ait_stab_function_name
|
||||||
{$endif GDB}
|
{$endif GDB}
|
||||||
{$ifdef regalloc}
|
|
||||||
,ait_regalloc, ait_regdealloc
|
,ait_regalloc, ait_regdealloc
|
||||||
{$endif regalloc}
|
|
||||||
];
|
];
|
||||||
|
|
||||||
{the maximum number of things (registers, memory, ...) a single instruction
|
{the maximum number of things (registers, memory, ...) a single instruction
|
||||||
@ -90,6 +87,14 @@ Const
|
|||||||
|
|
||||||
Type
|
Type
|
||||||
|
|
||||||
|
TRegArray = Array[R_EAX..R_EDI] of TRegister;
|
||||||
|
TRegSet = Set of TRegister;
|
||||||
|
TRegInfo = Record
|
||||||
|
RegsEncountered: TRegSet;
|
||||||
|
SubstRegs: TRegArray;
|
||||||
|
End;
|
||||||
|
|
||||||
|
|
||||||
{What an instruction can change}
|
{What an instruction can change}
|
||||||
TChange = (C_None,
|
TChange = (C_None,
|
||||||
C_REAX, C_RECX, C_REDX, C_REBX, C_RESP, C_REBP, C_RESI, C_REDI,
|
C_REAX, C_RECX, C_REDX, C_REBX, C_RESP, C_REBP, C_RESI, C_REDI,
|
||||||
@ -190,7 +195,10 @@ Var
|
|||||||
|
|
||||||
Implementation
|
Implementation
|
||||||
|
|
||||||
Uses globals, systems, strings, verbose, hcodegen;
|
Uses globals, systems, strings, verbose, hcodegen,
|
||||||
|
{$ifdef i386}
|
||||||
|
cgi386;
|
||||||
|
{$endif i386}
|
||||||
|
|
||||||
Const AsmInstr: Array[tasmop] Of TAsmInstrucProp = (
|
Const AsmInstr: Array[tasmop] Of TAsmInstrucProp = (
|
||||||
{MOV} (Ch: (C_Op2, C_None, C_None)),
|
{MOV} (Ch: (C_Op2, C_None, C_None)),
|
||||||
@ -588,7 +596,7 @@ Procedure FindLoHiLabels(AsmL: PAasmOutput; Var LowLabel, HighLabel, LabelDif: L
|
|||||||
{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;
|
||||||
LowLabel := MaxLongint;
|
LowLabel := MaxLongint;
|
||||||
@ -714,6 +722,35 @@ End;
|
|||||||
|
|
||||||
{********************* Compare parts of Pai objects *********************}
|
{********************* Compare parts of Pai objects *********************}
|
||||||
|
|
||||||
|
Function RegsEquivalent(Reg1, Reg2: TRegister; Var RegInfo: TRegInfo): Boolean;
|
||||||
|
Begin
|
||||||
|
With RegInfo Do
|
||||||
|
If Not(Reg1 in RegsEncountered) Then
|
||||||
|
Begin
|
||||||
|
RegsEncountered := RegsEncountered + [Reg1];
|
||||||
|
SubstRegs[Reg1] := Reg2;
|
||||||
|
RegsEquivalent := True
|
||||||
|
End
|
||||||
|
Else RegsEquivalent := Reg1 = SubstRegs[Reg2];
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function RefsEquivalent(Const R1, R2: TReference; var RegInfo: TRegInfo): Boolean;
|
||||||
|
Begin
|
||||||
|
If R1.IsIntValue
|
||||||
|
Then RefsEquivalent := R2.IsIntValue and (R1.Offset = R2.Offset)
|
||||||
|
Else If (R1.Offset = R2.Offset) And
|
||||||
|
RegsEquivalent(R1.Base, R2.Base, RegInfo) And
|
||||||
|
RegsEquivalent(R1.Index, R2.Index, RegInfo) And
|
||||||
|
(R1.Segment = R2.Segment) And (R1.ScaleFactor = R2.ScaleFactor)
|
||||||
|
Then
|
||||||
|
Begin
|
||||||
|
If Assigned(R1.Symbol)
|
||||||
|
Then RefsEquivalent := Assigned(R2.Symbol) And (R1.Symbol^=R2.Symbol^)
|
||||||
|
Else RefsEquivalent := Not(Assigned(R2.Symbol));
|
||||||
|
End
|
||||||
|
Else RefsEquivalent := False;
|
||||||
|
End;
|
||||||
|
|
||||||
Function RefsEqual(Const R1, R2: TReference): Boolean;
|
Function RefsEqual(Const R1, R2: TReference): Boolean;
|
||||||
Begin
|
Begin
|
||||||
If R1.IsIntValue
|
If R1.IsIntValue
|
||||||
@ -738,6 +775,14 @@ Begin
|
|||||||
Else IsGP32reg := False
|
Else IsGP32reg := False
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
Function SubstRegInRef(Reg: TRegister; Const Ref: TReference; var RegInfo: TRegInfo): Boolean;
|
||||||
|
Begin
|
||||||
|
Reg := Reg32(Reg);
|
||||||
|
With RegInfo Do
|
||||||
|
SubstRegInRef := RegsEquivalent(Reg, SubstRegs[Ref.Base], RegInfo) And
|
||||||
|
RegsEquivalent(Reg, SubstRegs[Ref.Base], RegInfo);
|
||||||
|
End;
|
||||||
|
|
||||||
Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
|
Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
|
||||||
Begin {checks whether Ref contains a reference to Reg}
|
Begin {checks whether Ref contains a reference to Reg}
|
||||||
Reg := Reg32(Reg);
|
Reg := Reg32(Reg);
|
||||||
@ -863,14 +908,58 @@ Begin
|
|||||||
Else s := 0
|
Else s := 0
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
Function RegInSequence(Reg: TRegister; Const Content: TContent): Boolean;
|
||||||
|
{checks the whole sequence of Content (so StartMod and and the next NrOfMods
|
||||||
|
Pai objects) to see whether Reg is used somewhere, without it being loaded
|
||||||
|
with something else first}
|
||||||
|
Var p: Pai;
|
||||||
|
Counter: Byte;
|
||||||
|
TmpResult: Boolean;
|
||||||
|
RegsChecked: TRegSet;
|
||||||
|
Begin
|
||||||
|
RegsChecked := [];
|
||||||
|
p := Content.StartMod;
|
||||||
|
TmpResult := False;
|
||||||
|
Counter := 1;
|
||||||
|
While Not(TmpResult) And
|
||||||
|
(Counter <= Content.NrOfMods) Do
|
||||||
|
Begin
|
||||||
|
If (p^.typ = ait_instruction) and
|
||||||
|
(Pai386(p)^._operator in [A_MOV, A_MOVZX, A_MOVSX])
|
||||||
|
Then
|
||||||
|
If (Pai386(p)^.op1t = top_ref)
|
||||||
|
Then
|
||||||
|
With TReference(Pai386(p)^.op1^) Do
|
||||||
|
If (Base = ProcInfo.FramePointer) And
|
||||||
|
(Index = R_NO)
|
||||||
|
Then RegsChecked := RegsChecked + [Reg32(TRegister(Pai386(p)^.op2))]
|
||||||
|
Else
|
||||||
|
Begin
|
||||||
|
If (Base = Reg) And
|
||||||
|
Not(Base In RegsChecked)
|
||||||
|
Then TmpResult := True;
|
||||||
|
If Not(TmpResult) And
|
||||||
|
(Index = Reg) And
|
||||||
|
Not(Index In RegsChecked)
|
||||||
|
Then TmpResult := True;
|
||||||
|
End;
|
||||||
|
Inc(Counter);
|
||||||
|
GetNextInstruction(p,p)
|
||||||
|
End;
|
||||||
|
RegInSequence := TmpResult
|
||||||
|
End;
|
||||||
|
|
||||||
Procedure DestroyReg(p1: PPaiProp; Reg: TRegister);
|
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 p1, as well as the
|
||||||
|
contents of registers are loaded with a memory location based on Reg}
|
||||||
Var TmpState: Longint;
|
Var TmpState: Longint;
|
||||||
|
Counter: TRegister;
|
||||||
Begin
|
Begin
|
||||||
Reg := Reg32(Reg);
|
Reg := Reg32(Reg);
|
||||||
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
|
With p1^.Regs[Reg] Do
|
||||||
Begin
|
Begin
|
||||||
IncState(State);
|
IncState(State);
|
||||||
@ -878,6 +967,18 @@ Begin
|
|||||||
FillChar(p1^.Regs[Reg], SizeOf(TContent), 0);
|
FillChar(p1^.Regs[Reg], SizeOf(TContent), 0);
|
||||||
State := TmpState;
|
State := TmpState;
|
||||||
End;
|
End;
|
||||||
|
For Counter := R_EAX to R_EDI Do
|
||||||
|
With p1^.Regs[Counter] Do
|
||||||
|
If (Typ = Con_Ref) And
|
||||||
|
RegInSequence(Reg, p1^.Regs[Counter])
|
||||||
|
Then
|
||||||
|
Begin
|
||||||
|
IncState(State);
|
||||||
|
TmpState := State;
|
||||||
|
FillChar(p1^.Regs[Counter], SizeOf(TContent), 0);
|
||||||
|
State := TmpState;
|
||||||
|
End;
|
||||||
|
End;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function OpsEqual(typ: Longint; op1, op2: Pointer): Boolean;
|
Function OpsEqual(typ: Longint; op1, op2: Pointer): Boolean;
|
||||||
@ -903,13 +1004,6 @@ Function InstructionsEqual(p1, p2: Pai): Boolean;
|
|||||||
Begin {checks whether two Pai386 instructions are equal}
|
Begin {checks whether two Pai386 instructions are equal}
|
||||||
InstructionsEqual :=
|
InstructionsEqual :=
|
||||||
Assigned(p1) And Assigned(p2) And
|
Assigned(p1) And Assigned(p2) And
|
||||||
{ $ifdef regalloc
|
|
||||||
((((Pai(p1)^.typ = ait_regalloc) And
|
|
||||||
(Pai(p2)^.typ = ait_regalloc)) Or
|
|
||||||
((Pai(p1)^.typ = ait_regdealloc) And
|
|
||||||
(Pai(p2)^.typ = ait_regdealloc))) And
|
|
||||||
(PaiRegAlloc(p1)^.reg = PaiRegAlloc(p2)^.reg)) Or
|
|
||||||
endif regalloc}
|
|
||||||
((Pai(p1)^.typ = ait_instruction) And
|
((Pai(p1)^.typ = ait_instruction) And
|
||||||
(Pai(p1)^.typ = ait_instruction) And
|
(Pai(p1)^.typ = ait_instruction) And
|
||||||
(Pai386(p1)^._operator = Pai386(p2)^._operator) And
|
(Pai386(p1)^._operator = Pai386(p2)^._operator) And
|
||||||
@ -919,6 +1013,43 @@ Begin {checks whether two Pai386 instructions are equal}
|
|||||||
OpsEqual(Pai386(p1)^.op2t, Pai386(p1)^.op2, Pai386(p2)^.op2))
|
OpsEqual(Pai386(p1)^.op2t, Pai386(p1)^.op2, Pai386(p2)^.op2))
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
Function RefInInstruction(Const Ref: TReference; p: Pai): Boolean;
|
||||||
|
{checks whehter Ref is used in P}
|
||||||
|
Var TmpResult: Boolean;
|
||||||
|
Begin
|
||||||
|
TmpResult := False;
|
||||||
|
If (p^.typ = ait_instruction) Then
|
||||||
|
Begin
|
||||||
|
If (Pai386(p)^.op1t = Top_Ref)
|
||||||
|
Then TmpResult := RefsEqual(Ref, TReference(Pai386(p)^.op1^));
|
||||||
|
If Not(TmpResult) And
|
||||||
|
(Pai386(p)^.op2t = Top_Ref)
|
||||||
|
Then TmpResult := RefsEqual(Ref, TReference(Pai386(p)^.op2^));
|
||||||
|
End;
|
||||||
|
RefInInstruction := TmpResult;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function RefInSequence(Const Ref: TReference; Content: TContent): Boolean;
|
||||||
|
{checks the whole sequence of Content (so StartMod and and the next NrOfMods
|
||||||
|
Pai objects) to see whether Ref is used somewhere}
|
||||||
|
Var p: Pai;
|
||||||
|
Counter: Byte;
|
||||||
|
TmpResult: Boolean;
|
||||||
|
Begin
|
||||||
|
p := Content.StartMod;
|
||||||
|
TmpResult := False;
|
||||||
|
Counter := 1;
|
||||||
|
While Not(TmpResult) And
|
||||||
|
(Counter <= Content.NrOfMods) Do
|
||||||
|
Begin
|
||||||
|
If (p^.typ = ait_instruction) And
|
||||||
|
RefInInstruction(Ref, p)
|
||||||
|
Then TmpResult := True;
|
||||||
|
Inc(Counter);
|
||||||
|
GetNextInstruction(p,p)
|
||||||
|
End;
|
||||||
|
RefInSequence := TmpResult
|
||||||
|
End;
|
||||||
|
|
||||||
Procedure DestroyRefs(p: pai; Const Ref: TReference; WhichReg: TRegister);
|
Procedure DestroyRefs(p: pai; Const Ref: TReference; WhichReg: TRegister);
|
||||||
{destroys all registers which possibly contain a reference to Ref, WhichReg
|
{destroys all registers which possibly contain a reference to Ref, WhichReg
|
||||||
@ -933,21 +1064,29 @@ Begin
|
|||||||
Then
|
Then
|
||||||
{write something to a parameter, a local or global variable, so
|
{write something to a parameter, a local or global variable, so
|
||||||
* with uncertzain optimizations on:
|
* with uncertzain optimizations on:
|
||||||
- destroy the contents of registers <> WhichReg whose StartMod is of
|
- destroy the contents of registers whose contents have somewhere a
|
||||||
the form "mov?? (Ref), %reg". WhichReg is destroyed if it's StartMod
|
"mov?? (Ref), %reg". WhichReg (this is the register whose contents
|
||||||
is of that form and NrOfMods > 1 (so if it is a pointer based on Ref)
|
are being written to memory) is not destroyed if it's StartMod is
|
||||||
* with uncertzain optimizations off:
|
of that form and NrOfMods = 1 (so if it holds ref, but is not a
|
||||||
|
pointer based on Ref)
|
||||||
|
* with uncertain optimizations off:
|
||||||
- also destroy registers that contain any pointer}
|
- also destroy registers that contain any pointer}
|
||||||
For Counter := R_EAX to R_EDI Do
|
For Counter := R_EAX to R_EDI Do
|
||||||
With PPaiProp(p^.fileinfo.line)^.Regs[Counter] Do
|
With PPaiProp(p^.fileinfo.line)^.Regs[Counter] Do
|
||||||
Begin
|
Begin
|
||||||
If (typ = Con_Ref) And
|
If (typ = Con_Ref) And
|
||||||
|
(Not(cs_UncertainOpts in aktglobalswitches) And
|
||||||
|
(NrOfMods <> 1)
|
||||||
|
) Or
|
||||||
|
(RefInSequence(Ref,PPaiProp(p^.fileinfo.line)^.Regs[Counter]) And
|
||||||
|
((Counter <> WhichReg) Or
|
||||||
|
((NrOfMods = 1) And
|
||||||
{StarMod is always of the type ait_instruction}
|
{StarMod is always of the type ait_instruction}
|
||||||
(Pai386(StartMod)^.op1t = top_ref) And
|
(Pai386(StartMod)^.op1t = top_ref) And
|
||||||
((RefsEqual(TReference(Pai386(StartMod)^.op1^), Ref) And
|
RefsEqual(TReference(Pai386(StartMod)^.op1^), Ref)
|
||||||
((Counter <> WhichReg) Or (NrOfMods <> 1))) Or
|
)
|
||||||
(Not(cs_UncertainOpts in aktglobalswitches) And
|
)
|
||||||
(NrOfMods <> 1)))
|
)
|
||||||
Then DestroyReg(PPaiProp(p^.fileinfo.line), Counter)
|
Then DestroyReg(PPaiProp(p^.fileinfo.line), Counter)
|
||||||
End
|
End
|
||||||
Else
|
Else
|
||||||
@ -999,7 +1138,11 @@ Begin
|
|||||||
BuildLabelTable(AsmL, LTable, LoLab, LabDif);
|
BuildLabelTable(AsmL, LTable, LoLab, LabDif);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function DoDFAPass2(First: Pai): Pai;
|
Function DoDFAPass2(
|
||||||
|
{$Ifdef StateDebug}
|
||||||
|
AsmL: PAasmOutput;
|
||||||
|
{$endif statedebug}
|
||||||
|
First: Pai): Pai;
|
||||||
{Analyzes the Data Flow of an assembler list. Starts creating the reg
|
{Analyzes the Data Flow of an assembler list. Starts creating the reg
|
||||||
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}
|
||||||
@ -1037,7 +1180,7 @@ Begin
|
|||||||
Begin
|
Begin
|
||||||
GetLastInstruction(p, hp);
|
GetLastInstruction(p, hp);
|
||||||
CurProp^.Regs := PPaiProp(hp^.fileinfo.line)^.Regs;
|
CurProp^.Regs := PPaiProp(hp^.fileinfo.line)^.Regs;
|
||||||
CurProp^.DirFlag := PPaiProp(hp^.fileinfo.line)^.DirFlag
|
CurProp^.DirFlag := PPaiProp(hp^.fileinfo.line)^.DirFlag;
|
||||||
End
|
End
|
||||||
{$ifdef JumpAnal}
|
{$ifdef JumpAnal}
|
||||||
End
|
End
|
||||||
@ -1237,9 +1380,7 @@ Begin
|
|||||||
{$ifdef GDB}
|
{$ifdef GDB}
|
||||||
ait_stabs, ait_stabn, ait_stab_function_name:;
|
ait_stabs, ait_stabn, ait_stab_function_name:;
|
||||||
{$endif GDB}
|
{$endif GDB}
|
||||||
{$ifdef regalloc}
|
|
||||||
ait_regalloc, ait_regdealloc:;
|
ait_regalloc, ait_regdealloc:;
|
||||||
{$endif regalloc}
|
|
||||||
ait_instruction:
|
ait_instruction:
|
||||||
Begin
|
Begin
|
||||||
InstrProp := AsmInstr[Pai386(p)^._operator];
|
InstrProp := AsmInstr[Pai386(p)^._operator];
|
||||||
@ -1263,17 +1404,17 @@ Begin
|
|||||||
Top_Ref:
|
Top_Ref:
|
||||||
Begin {destination is always a register in this case}
|
Begin {destination is always a register in this case}
|
||||||
TmpReg := Reg32(TRegister(Pai386(p)^.op2));
|
TmpReg := Reg32(TRegister(Pai386(p)^.op2));
|
||||||
If (RegInRef(TmpReg, TReference(Pai386(p)^.op1^)))
|
{$ifdef StateDebug}
|
||||||
|
hp := new(pai_asm_comment,init(strpnew(att_reg2str[TmpReg]+': '+tostr(CurProp^.Regs[TmpReg].State))));
|
||||||
|
InsertLLItem(AsmL, p, p^.next, hp);
|
||||||
|
{$endif SteDebug}
|
||||||
|
If RegInRef(TmpReg, TReference(Pai386(p)^.op1^)) And
|
||||||
|
(CurProp^.Regs[TmpReg].Typ = Con_Ref)
|
||||||
Then
|
Then
|
||||||
Begin
|
Begin
|
||||||
With CurProp^.Regs[TmpReg] Do
|
With CurProp^.Regs[TmpReg] Do
|
||||||
Begin
|
Begin
|
||||||
IncState(State);
|
IncState(State);
|
||||||
If (typ <> Con_Ref) Then
|
|
||||||
Begin
|
|
||||||
typ := Con_Ref;
|
|
||||||
StartMod := p;
|
|
||||||
End;
|
|
||||||
{also store how many instructions are part of the sequence in the first
|
{also store how many instructions are part of the sequence in the first
|
||||||
instructions PPaiProp, so it can be easily accessed from within
|
instructions PPaiProp, so it can be easily accessed from within
|
||||||
CheckSequence}
|
CheckSequence}
|
||||||
@ -1455,7 +1596,11 @@ End;
|
|||||||
Function DFAPass2(AsmL: PAasmOutPut): Pai;
|
Function DFAPass2(AsmL: PAasmOutPut): Pai;
|
||||||
Begin
|
Begin
|
||||||
If InitDFAPass2(AsmL)
|
If InitDFAPass2(AsmL)
|
||||||
Then DFAPass2 := DoDFAPass2(Pai(AsmL^.First))
|
Then DFAPass2 := DoDFAPass2(
|
||||||
|
{$ifdef statedebug}
|
||||||
|
asml,
|
||||||
|
{$endif statedbug}
|
||||||
|
Pai(AsmL^.First))
|
||||||
Else DFAPass2 := Nil;
|
Else DFAPass2 := Nil;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
@ -1469,9 +1614,8 @@ End.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.13 1998-09-17 09:42:36 peter
|
Revision 1.14 1998-09-20 17:12:36 jonas
|
||||||
+ pass_2 for cg386
|
* small fix for uncertain optimizations & more cleaning up
|
||||||
* Message() -> CGMessage() for pass_1/pass_2
|
|
||||||
|
|
||||||
Revision 1.12 1998/09/16 18:00:01 jonas
|
Revision 1.12 1998/09/16 18:00:01 jonas
|
||||||
* optimizer now completely dependant on GetNext/GetLast instruction, works again with -dRegAlloc
|
* optimizer now completely dependant on GetNext/GetLast instruction, works again with -dRegAlloc
|
||||||
|
Loading…
Reference in New Issue
Block a user