mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-29 23:40:14 +02:00
* inter-register CSE, still requires some tweaks (peepholeoptpass2, better RegAlloc)
This commit is contained in:
parent
68bc49c014
commit
965c651dcc
@ -31,58 +31,110 @@ Procedure CSE(AsmL: PAasmOutput; First, Last: Pai);
|
|||||||
|
|
||||||
Implementation
|
Implementation
|
||||||
|
|
||||||
Uses CObjects, verbose
|
Uses CObjects, verbose, hcodegen, globals
|
||||||
{$ifdef i386}
|
{$ifdef i386}
|
||||||
,i386, DAOpt386
|
,i386, DAOpt386
|
||||||
{$endif i386}
|
{$endif i386}
|
||||||
;
|
;
|
||||||
|
|
||||||
Function CheckSequence(p: Pai; Reg: TRegister; Var Found: Longint): Boolean;
|
Function PaiInSequence(P: Pai; Const Seq: TContent): Boolean;
|
||||||
|
Var P1: Pai;
|
||||||
|
Counter: Byte;
|
||||||
|
TmpResult: Boolean;
|
||||||
|
Begin
|
||||||
|
TmpResult := False;
|
||||||
|
P1 := Seq.StartMod;
|
||||||
|
Counter := 1;
|
||||||
|
While Not(TmpResult) And
|
||||||
|
(Counter <= Seq.NrOfMods) Do
|
||||||
|
Begin
|
||||||
|
If (P = P1) Then TmpResult := True;
|
||||||
|
Inc(Counter);
|
||||||
|
p1 := Pai(p1^.Next);
|
||||||
|
End;
|
||||||
|
PaiInSequence := TmpResult;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CheckSequence(p: Pai; Reg: TRegister; Var Found: Longint; Var RegInfo: TRegInfo): Boolean;
|
||||||
{checks whether the current instruction sequence (starting with p) and the
|
{checks whether the current instruction sequence (starting with p) and the
|
||||||
one between StartMod and EndMod of Reg are the same. If so, the number of
|
one between StartMod and EndMod of Reg are the same. If so, the number of
|
||||||
instructions that match is stored in Found and true is returned, otherwise
|
instructions that match is stored in Found and true is returned, otherwise
|
||||||
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;
|
||||||
Counter: Byte;
|
PrevNonRemovablePai: Pai;
|
||||||
|
OrgRegInfo, HighRegInfo: TRegInfo;
|
||||||
|
HighFound, OrgRegFound: Byte;
|
||||||
|
RegCounter: TRegister;
|
||||||
|
OrgRegResult: Boolean;
|
||||||
|
TmpResult: Boolean;
|
||||||
|
OldNrOfMods: Byte;
|
||||||
Begin {CheckSequence}
|
Begin {CheckSequence}
|
||||||
Reg := Reg32(Reg);
|
Reg := Reg32(Reg);
|
||||||
Found := 0;
|
TmpResult := False;
|
||||||
hp3 := p;
|
HighFound := 0;
|
||||||
While GetLastInstruction(hp3, hp3) And
|
RegCounter := R_EAX;
|
||||||
PPAiProp(hp3^.fileinfo.line)^.CanBeRemoved Do;
|
GetLastInstruction(p, PrevNonRemovablePai);
|
||||||
hp2 := PPaiProp(hp3^.fileinfo.line)^.Regs[Reg].StartMod;
|
While (PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter].Typ <> Con_Ref) Or
|
||||||
EndMod := hp2;
|
{ the next check is because what a register contains is stored in the
|
||||||
If (PPaiProp(hp3^.fileinfo.line)^.Regs[Reg].NrOfMods = 1)
|
ppaiprop of the first instruction of the loading sequence. If it's left
|
||||||
Then Counter := 1
|
out,
|
||||||
Else
|
|
||||||
For Counter := 2 to PPaiProp(hp3^.fileinfo.line)^.Regs[Reg].NrOfMods Do
|
movl 8(%ebp), %eax movl 8(%ebp), %eax
|
||||||
GetNextInstruction(EndMod, EndMod);
|
movl 8(%ebp), %edx movl %eax, %edx
|
||||||
hp3 := p;
|
movl (%edx), %edx would be changed to
|
||||||
While (Found <> Counter) And
|
movl (%eax), %eax movl (%eax), %eax
|
||||||
InstructionsEqual(hp2, hp3) Do
|
cmpl (%edx), %eax cmpl (%edx), %eax}
|
||||||
Begin
|
|
||||||
GetNextInstruction(hp2, hp2);
|
((Regcounter <> Reg) And
|
||||||
GetNextInstruction(hp3, hp3);
|
PaiInSequence(p, PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter])) Do
|
||||||
Inc(Found)
|
Inc(RegCounter);
|
||||||
End;
|
{no need to check whether RegCounter becomes > R_EDI here, because at least
|
||||||
If (Found <> Counter)
|
PPaiProp(p^.fileinfo.line)^.Regs[Reg].Typ = Con_Ref}
|
||||||
Then
|
Repeat
|
||||||
Begin
|
FillChar(RegInfo, SizeOf(RegInfo), 0);
|
||||||
If ((Found+1) = Counter) And
|
RegInfo.RegsEncountered := [ProcInfo.FramePointer, R_ESP];
|
||||||
Assigned(hp2) And
|
RegInfo.SubstRegs[ProcInfo.FramePointer] := ProcInfo.FramePointer;
|
||||||
(Pai(hp2)^.typ = ait_instruction) And
|
RegInfo.SubstRegs[R_ESP] := R_ESP;
|
||||||
(Pai386(hp2)^._operator In [A_MOV, A_MOVZX]) And
|
Found := 0;
|
||||||
(Pai386(hp2)^.op1t = top_ref) And
|
hp2 := PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter].StartMod;
|
||||||
(Pai386(hp2)^.op2t = top_reg) And
|
{ EndMod := hp2;
|
||||||
Assigned(hp3) And
|
If (PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter].NrOfMods = 1)
|
||||||
(Pai(hp3)^.typ = ait_instruction) And
|
Then OldNrOfMods := 1
|
||||||
(Pai386(hp3)^._operator In [A_MOV, A_MOVZX]) And
|
Else
|
||||||
(Pai386(hp3)^.op1t = top_ref) And
|
For OldNrOfMods := 2 to PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter].NrOfMods Do
|
||||||
(Pai386(hp3)^.op2t = top_reg) And
|
GetNextInstruction(EndMod, EndMod);}
|
||||||
(Pai386(hp2)^._operator <> Pai386(hp3)^._operator) And
|
OldNrOfMods := PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter].NrOfMods;
|
||||||
RefsEqual(TReference(Pai386(hp2)^.op1^),TReference(Pai386(hp3)^.op1^))
|
hp3 := p;
|
||||||
Then
|
While (Found <> OldNrOfMods) And
|
||||||
|
{ old new }
|
||||||
|
InstructionsEquivalent(hp2, hp3, RegInfo) Do
|
||||||
|
Begin
|
||||||
|
GetNextInstruction(hp2, hp2);
|
||||||
|
GetNextInstruction(hp3, hp3);
|
||||||
|
Inc(Found)
|
||||||
|
End;
|
||||||
|
If (Found <> OldNrOfMods)
|
||||||
|
Then
|
||||||
|
Begin
|
||||||
|
(* If ((Found+1) = OldNrOfMods) And
|
||||||
|
Assigned(hp2) And
|
||||||
|
(Pai(hp2)^.typ = ait_instruction) And
|
||||||
|
(Pai386(hp2)^._operator In [A_MOV, A_MOVZX]) And
|
||||||
|
(Pai386(hp2)^.op1t = top_ref) And
|
||||||
|
(Pai386(hp2)^.op2t = top_reg) And
|
||||||
|
Assigned(hp3) And
|
||||||
|
(Pai(hp3)^.typ = ait_instruction) And
|
||||||
|
(Pai386(hp3)^._operator In [A_MOV, A_MOVZX]) And
|
||||||
|
(Pai386(hp3)^.op1t = top_ref) And
|
||||||
|
(Pai386(hp3)^.op2t = top_reg) And
|
||||||
|
(Pai386(hp2)^._operator <> Pai386(hp3)^._operator) And
|
||||||
|
{$IfDef RegInfo}
|
||||||
|
RefsEquivalent(TReference(Pai386(hp2)^.op1^),TReference(Pai386(hp3)^.op1^), RegInfo)
|
||||||
|
{$Else RegInfo}
|
||||||
|
RefsEqual(TReference(Pai386(hp2)^.op1^),TReference(Pai386(hp3)^.op1^))
|
||||||
|
{$EndIf RegInfo}
|
||||||
|
Then
|
||||||
|
|
||||||
{hack to be able to optimize
|
{hack to be able to optimize
|
||||||
mov (mem), reg
|
mov (mem), reg
|
||||||
@ -94,48 +146,59 @@ Begin {CheckSequence}
|
|||||||
mov (reg), reg
|
mov (reg), reg
|
||||||
movzx (reg), reg [*]}
|
movzx (reg), reg [*]}
|
||||||
|
|
||||||
If (Pai386(hp2)^._operator = A_MOV)
|
If (Pai386(hp2)^._operator = A_MOV)
|
||||||
Then
|
Then
|
||||||
Begin
|
Begin
|
||||||
If (Pai386(hp2)^.Size = S_B) And
|
If (Pai386(hp2)^.Size = S_B) And
|
||||||
(Reg8toReg32(TRegister(Pai386(hp2)^.op2)) =
|
{$IfDef RegInfo}
|
||||||
TRegister(Pai386(hp3)^.op2))
|
RegsEquivalent(Reg8toReg32(TRegister(Pai386(hp2)^.op2)),
|
||||||
Then
|
TRegister(Pai386(hp3)^.op2), RegInfo)
|
||||||
Begin
|
{$Else RegInfo}
|
||||||
Pai386(hp2)^._operator := A_MOVZX;
|
(Reg8toReg32(TRegister(Pai386(hp2)^.op2)) =
|
||||||
Pai386(hp2)^.op2 := Pai386(hp3)^.op2;
|
TRegister(Pai386(hp3)^.op2))
|
||||||
Pai386(hp2)^.Size := S_BL;
|
{$EndIf RegInfo}
|
||||||
Inc(Found);
|
Then
|
||||||
CheckSequence := True;
|
Begin
|
||||||
End
|
Pai386(hp2)^._operator := A_MOVZX;
|
||||||
Else
|
Pai386(hp2)^.op2 := Pai386(hp3)^.op2;
|
||||||
Begin
|
Pai386(hp2)^.Size := S_BL;
|
||||||
CheckSequence := False;
|
Inc(Found);
|
||||||
If (Found > 0) Then
|
TmpResult := True;
|
||||||
Found := PPaiProp(Pai(p)^.fileinfo.line)^.Regs[Reg].NrOfMods
|
End
|
||||||
End
|
Else
|
||||||
End
|
Begin
|
||||||
Else
|
TmpResult := False;
|
||||||
Begin
|
If (Found > 0) Then
|
||||||
If (Pai386(hp3)^.Size = S_B) And
|
Found := PPaiProp(Pai(p)^.fileinfo.line)^.Regs[Reg].NrOfMods
|
||||||
(Reg8toReg32(TRegister(Pai386(hp3)^.op2)) =
|
End
|
||||||
TRegister(Pai386(hp2)^.op2))
|
End
|
||||||
Then
|
Else
|
||||||
Begin
|
Begin
|
||||||
CheckSequence := True;
|
If (Pai386(hp3)^.Size = S_B) And
|
||||||
Inc(Found)
|
{$IfDef RegInfo}
|
||||||
End
|
RegsEquivalent(TRegister(Pai386(hp2)^.op2),
|
||||||
Else
|
Reg8toReg32(TRegister(Pai386(hp3)^.op2)),
|
||||||
Begin
|
RegInfo)
|
||||||
CheckSequence := False;
|
{$Else RegInfo}
|
||||||
If (Found > 0) Then
|
(Reg8toReg32(TRegister(Pai386(hp3)^.op2)) =
|
||||||
Found := PPaiProp(Pai(p)^.fileinfo.line)^.Regs[Reg].NrOfMods
|
TRegister(Pai386(hp2)^.op2))
|
||||||
End
|
{$EndIf RegInfo}
|
||||||
End
|
Then
|
||||||
Else
|
Begin
|
||||||
Begin
|
TmpResult := True;
|
||||||
CheckSequence := False;
|
Inc(Found)
|
||||||
If (found > 0) then
|
End
|
||||||
|
Else
|
||||||
|
Begin
|
||||||
|
TmpResult := False;
|
||||||
|
If (Found > 0) Then
|
||||||
|
Found := PPaiProp(Pai(p)^.fileinfo.line)^.Regs[Reg].NrOfMods
|
||||||
|
End
|
||||||
|
End
|
||||||
|
Else *)
|
||||||
|
Begin
|
||||||
|
TmpResult := False;
|
||||||
|
If (found > 0) then
|
||||||
{this is correct because we only need to turn off the CanBeRemoved flag
|
{this is correct because we only need to turn off the CanBeRemoved flag
|
||||||
when an instruction has already been processed by CheckSequence
|
when an instruction has already been processed by CheckSequence
|
||||||
(otherwise CanBeRemoved can't be true and thus can't have to be turned off).
|
(otherwise CanBeRemoved can't be true and thus can't have to be turned off).
|
||||||
@ -144,27 +207,68 @@ Begin {CheckSequence}
|
|||||||
and that it was equal (otherwise CheckSequence would have returned false
|
and that it was equal (otherwise CheckSequence would have returned false
|
||||||
and the instruction wouldn't have been removed). If this "If found > 0"
|
and the instruction wouldn't have been removed). If this "If found > 0"
|
||||||
check is left out, incorrect optimizations are performed.}
|
check is left out, incorrect optimizations are performed.}
|
||||||
Found := PPaiProp(Pai(p)^.fileinfo.line)^.Regs[Reg].NrOfMods
|
Found := PPaiProp(Pai(p)^.fileinfo.line)^.Regs[Reg].NrOfMods
|
||||||
End
|
End
|
||||||
End
|
End
|
||||||
Else CheckSequence := True;
|
Else TmpResult := True;
|
||||||
|
If TmpResult And
|
||||||
|
(Found > HighFound)
|
||||||
|
Then
|
||||||
|
Begin
|
||||||
|
HighFound := Found;
|
||||||
|
HighRegInfo := RegInfo;
|
||||||
|
End;
|
||||||
|
If (RegCounter = Reg) Then
|
||||||
|
Begin
|
||||||
|
OrgRegFound := Found;
|
||||||
|
OrgRegResult := TmpResult;
|
||||||
|
OrgRegInfo := RegInfo
|
||||||
|
End;
|
||||||
|
Repeat
|
||||||
|
Inc(RegCounter);
|
||||||
|
Until (RegCounter > R_EDI) or
|
||||||
|
((PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter].Typ = Con_Ref) And
|
||||||
|
((Regcounter = Reg) Or
|
||||||
|
Not(PaiInSequence(p, PPaiProp(PrevNonRemovablePai^.fileinfo.line)^.Regs[RegCounter]))));
|
||||||
|
Until (RegCounter > R_EDI);
|
||||||
|
If (HighFound > 0) And
|
||||||
|
(Not(OrgRegResult) Or
|
||||||
|
(HighFound > OrgRegFound))
|
||||||
|
Then
|
||||||
|
Begin
|
||||||
|
CheckSequence := True;
|
||||||
|
RegInfo := HighRegInfo;
|
||||||
|
Found := HighFound
|
||||||
|
End
|
||||||
|
Else
|
||||||
|
Begin
|
||||||
|
CheckSequence := OrgRegResult;
|
||||||
|
Found := OrgRegFound;
|
||||||
|
RegInfo := OrgRegInfo;
|
||||||
|
End;
|
||||||
End; {CheckSequence}
|
End; {CheckSequence}
|
||||||
|
|
||||||
Procedure DoCSE(First, Last: Pai);
|
Procedure DoCSE(AsmL: PAasmOutput; First, Last: Pai);
|
||||||
{marks the instructions that can be removed by RemoveInstructs. They're not
|
{marks the instructions that can be removed by RemoveInstructs. They're not
|
||||||
removed immediately because sometimes an instruction needs to be checked in
|
removed immediately because sometimes an instruction needs to be checked in
|
||||||
two different sequences}
|
two different sequences}
|
||||||
Var Cnt, Cnt2: Longint;
|
Var Cnt, Cnt2: Longint;
|
||||||
p, hp1, hp2: Pai;
|
p, hp1, hp2: Pai;
|
||||||
|
hp3, hp4: Pai;
|
||||||
|
{$ifdef csdebug}
|
||||||
|
hp5: pai;
|
||||||
|
{$endif csdebug}
|
||||||
|
RegInfo: TRegInfo;
|
||||||
|
RegCounter: TRegister;
|
||||||
|
TmpState: Word;
|
||||||
Begin
|
Begin
|
||||||
p := First;
|
p := First;
|
||||||
If (p^.typ in SkipInstr) Then
|
If (p^.typ in (SkipInstr+ait_marker)) Then
|
||||||
GetNextInstruction(p, p);
|
GetNextInstruction(p, p);
|
||||||
First := p;
|
First := p;
|
||||||
While Assigned(p) Do
|
While Assigned(p) Do
|
||||||
Begin
|
Begin
|
||||||
Case p^.typ Of
|
Case p^.typ Of
|
||||||
ait_label, ait_labeled_instruction:;
|
|
||||||
ait_instruction:
|
ait_instruction:
|
||||||
Begin
|
Begin
|
||||||
Case Pai386(p)^._operator Of
|
Case Pai386(p)^._operator Of
|
||||||
@ -183,11 +287,15 @@ Begin
|
|||||||
Begin {destination is always a register in this case}
|
Begin {destination is always a register in this case}
|
||||||
With PPaiProp(p^.fileinfo.line)^.Regs[Reg32(Tregister(Pai386(p)^.op2))] Do
|
With PPaiProp(p^.fileinfo.line)^.Regs[Reg32(Tregister(Pai386(p)^.op2))] Do
|
||||||
Begin
|
Begin
|
||||||
If GetLastInstruction(p, hp1) And
|
{ hp1 := p;
|
||||||
|
While GetLastInstruction(hp1, hp1) And
|
||||||
|
PPaiProp(hp1^.fileinfo.line)^.CanBeRemoved Do;}
|
||||||
|
GetLastInstruction(p, hp1);
|
||||||
|
If Assigned(hp1) And
|
||||||
(PPaiProp(hp1^.fileinfo.line)^.
|
(PPaiProp(hp1^.fileinfo.line)^.
|
||||||
Regs[Reg32(TRegister(Pai386(p)^.op2))].typ = con_ref) Then
|
Regs[Reg32(TRegister(Pai386(p)^.op2))].typ = con_ref) Then
|
||||||
{so we don't try to check a sequence when the register only contains a constant}
|
{so we don't try to check a sequence when the register only contains a constant}
|
||||||
If CheckSequence(p, TRegister(Pai386(p)^.op2), Cnt) And
|
If CheckSequence(p, TRegister(Pai386(p)^.op2), Cnt, RegInfo) And
|
||||||
(Cnt > 0)
|
(Cnt > 0)
|
||||||
Then
|
Then
|
||||||
Begin
|
Begin
|
||||||
@ -212,12 +320,152 @@ Begin
|
|||||||
While Cnt2 <= Cnt Do
|
While Cnt2 <= Cnt Do
|
||||||
Begin
|
Begin
|
||||||
If (hp1 = nil) And
|
If (hp1 = nil) And
|
||||||
Not(RegInInstruction(Tregister(Pai386(hp2)^.op2), p))
|
Not(RegInInstruction(Tregister(Pai386(hp2)^.op2), p) Or
|
||||||
|
RegInInstruction(Reg32(Tregister(Pai386(hp2)^.op2)), p))
|
||||||
Then hp1 := p;
|
Then hp1 := p;
|
||||||
|
{$ifndef noremove}
|
||||||
PPaiProp(p^.fileinfo.line)^.CanBeRemoved := True;
|
PPaiProp(p^.fileinfo.line)^.CanBeRemoved := True;
|
||||||
|
{$endif noremove}
|
||||||
Inc(Cnt2);
|
Inc(Cnt2);
|
||||||
GetNextInstruction(p, p);
|
GetNextInstruction(p, p);
|
||||||
End;
|
End;
|
||||||
|
hp3 := New(Pai_Marker,Init(NoPropInfoStart));
|
||||||
|
InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3);
|
||||||
|
{imagine the following code:
|
||||||
|
normal wrong optimized
|
||||||
|
movl 8(%ebp), %eax movl 8(%ebp), %eax
|
||||||
|
movl (%eax), %eax movl (%eax), %eax
|
||||||
|
cmpl 8(%ebp), %eax cmpl 8(%ebp), %eax
|
||||||
|
jne l1 jne l1
|
||||||
|
movl 8(%ebp), %eax
|
||||||
|
movl (%eax), %edi movl %eax, %edi
|
||||||
|
movl %edi, -4(%ebp) movl %edi, -4(%ebp)
|
||||||
|
movl 8(%ebp), %eax
|
||||||
|
pushl 70(%eax) pushl 70(%eax)
|
||||||
|
|
||||||
|
The error is that at the moment that the last instruction is executed,
|
||||||
|
%eax doesn't contain 8(%ebp) anymore. Solution: the contents of registers
|
||||||
|
that are completely removed from a sequence, have to be changed to their
|
||||||
|
contents from before the sequence.}
|
||||||
|
|
||||||
|
{hp4 is used to get the contents of the registers before the sequence}
|
||||||
|
GetLastInstruction(hp2, hp4);
|
||||||
|
{If some registers were different in the old and the new sequence, move
|
||||||
|
the contents of those old registers to the new ones}
|
||||||
|
{$IfDef CSDebug}
|
||||||
|
For RegCounter := R_EAX To R_EDI Do
|
||||||
|
If (RegCounter in RegInfo.RegsLoadedForRef) Then
|
||||||
|
Begin
|
||||||
|
hp5 := new(pai_asm_comment,init(strpnew('New: '+att_reg2str[RegCounter]+', Old: '+
|
||||||
|
att_reg2str[RegInfo.SubstRegs[RegCounter]])));
|
||||||
|
InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp5);
|
||||||
|
End;
|
||||||
|
{$EndIf CSDebug}
|
||||||
|
For RegCounter := R_EAX To R_EDI Do
|
||||||
|
Begin
|
||||||
|
If (RegInfo.SubstRegs[RegCounter] <> R_NO) Then
|
||||||
|
If Not(RegCounter In RegInfo.RegsLoadedForRef) And
|
||||||
|
{new reg old reg}
|
||||||
|
(RegInfo.SubstRegs[RegCounter] <> RegCounter) Then
|
||||||
|
|
||||||
|
Begin
|
||||||
|
hp3 := New(Pai386,Op_Reg_Reg(A_MOV, S_L,
|
||||||
|
{old reg new reg}
|
||||||
|
RegInfo.SubstRegs[RegCounter], RegCounter));
|
||||||
|
hp3^.fileinfo := hp2^.fileinfo;
|
||||||
|
hp3^.fileinfo.line := PPaiProp(hp2^.fileinfo.line)^.LineSave;
|
||||||
|
InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp3);
|
||||||
|
End
|
||||||
|
Else
|
||||||
|
If (RegCounter In RegInfo.RegsLoadedForRef) Then
|
||||||
|
{change the contents of this register to the its contents before the
|
||||||
|
sequence (for all instructions in and after the sequence, until the register
|
||||||
|
is reloaded)}
|
||||||
|
Begin
|
||||||
|
{load Cnt2 with the total number of instructions of this sequence}
|
||||||
|
Cnt2 := PPaiProp(hp4^.fileinfo.line)^.
|
||||||
|
Regs[RegInfo.SubstRegs[RegCounter]].NrOfMods;
|
||||||
|
{sometimes, a register can not be removed from a sequence, because it's
|
||||||
|
still used afterwards:
|
||||||
|
|
||||||
|
movl -8(%ebp), %eax movl -8(%ebp), %eax
|
||||||
|
movl 70(%eax), %eax movl 70(%eax), %eax
|
||||||
|
cmpl 74(%eax), %eax cmpl 74(%eax), %eax
|
||||||
|
jne l1 can't be changed to jne l1
|
||||||
|
movl -8(%ebp), %eax
|
||||||
|
movl 70(%eax), %edi movl %eax, %edi
|
||||||
|
boundl R_282, %edi boundl R_282, %edi
|
||||||
|
pushl 70(%eax) pushl 70(%eax)
|
||||||
|
|
||||||
|
because eax now contains the wrong value when 70(%eax) is pushed}
|
||||||
|
|
||||||
|
hp3 := hp2;
|
||||||
|
For Cnt := 1 to Pred(Cnt2) Do
|
||||||
|
GetNextInstruction(hp3, hp3);
|
||||||
|
TmpState := PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter].State;
|
||||||
|
GetNextInstruction(hp3, hp3);
|
||||||
|
If (TmpState <> PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter].State) Or
|
||||||
|
Not(RegCounter in PPaiProp(hp3^.fileinfo.line)^.UsedRegs) Then
|
||||||
|
Begin
|
||||||
|
{$ifdef csdebug}
|
||||||
|
Writeln('Cnt2: ',Cnt2);
|
||||||
|
hp5 := new(pai_asm_comment,init(strpnew('starting here...')));
|
||||||
|
InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp5);
|
||||||
|
{$endif csdebug}
|
||||||
|
hp3 := hp2;
|
||||||
|
{first change the contents of the register inside the sequence}
|
||||||
|
For Cnt := 1 to Cnt2 Do
|
||||||
|
Begin
|
||||||
|
{save the state of the last pai object of the sequence for later use}
|
||||||
|
TmpState := PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter].State;
|
||||||
|
{$ifdef csdebug}
|
||||||
|
hp5 := new(pai_asm_comment,init(strpnew('State for '+att_reg2str[Regcounter]+': '
|
||||||
|
+tostr(tmpstate))));
|
||||||
|
InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
|
||||||
|
{$endif csdebug}
|
||||||
|
PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter] :=
|
||||||
|
PPaiProp(hp4^.fileinfo.line)^.Regs[RegCounter];
|
||||||
|
GetNextInstruction(hp3, hp3);
|
||||||
|
End;
|
||||||
|
{here, hp3 = p = Pai object right after the sequence, TmpState = state of
|
||||||
|
RegCounter at the last Pai object of the sequence}
|
||||||
|
GetLastInstruction(hp3, hp3);
|
||||||
|
While GetNextInstruction(hp3, hp3) And
|
||||||
|
(PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter].State
|
||||||
|
= TmpState) Do
|
||||||
|
{$ifdef csdebug}
|
||||||
|
begin
|
||||||
|
hp5 := new(pai_asm_comment,init(strpnew('State for '+att_reg2str[Regcounter]+': '+
|
||||||
|
tostr(PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter].State))));
|
||||||
|
InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
|
||||||
|
{$endif csdebug}
|
||||||
|
PPaiProp(hp3^.fileinfo.line)^.Regs[RegCounter] :=
|
||||||
|
PPaiProp(hp4^.fileinfo.line)^.Regs[RegCounter];
|
||||||
|
{$ifdef csdebug}
|
||||||
|
end;
|
||||||
|
{$endif csdebug}
|
||||||
|
End
|
||||||
|
Else
|
||||||
|
Begin
|
||||||
|
{$ifdef csdebug}
|
||||||
|
Writeln('Got there for ',att_Reg2Str[RegCounter]);
|
||||||
|
{$endif csdebug}
|
||||||
|
hp3 := hp2;
|
||||||
|
For Cnt := 1 to Cnt2 Do
|
||||||
|
Begin
|
||||||
|
If RegModifiedByInstruction(RegCounter, hp3)
|
||||||
|
Then PPaiProp(hp3^.fileinfo.line)^.CanBeRemoved := False;
|
||||||
|
GetNextInstruction(hp3, hp3);
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
{$ifdef csdebug}
|
||||||
|
hp5 := new(pai_asm_comment,init(strpnew('stopping here...')));
|
||||||
|
InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
|
||||||
|
{$endif csdebug}
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
hp3 := New(Pai_Marker,Init(NoPropInfoEnd));
|
||||||
|
InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3);
|
||||||
If hp1 <> nil Then p := hp1;
|
If hp1 <> nil Then p := hp1;
|
||||||
Continue;
|
Continue;
|
||||||
End
|
End
|
||||||
@ -229,7 +477,8 @@ Begin
|
|||||||
Cnt2 := 1;
|
Cnt2 := 1;
|
||||||
While Cnt2 <= Cnt Do
|
While Cnt2 <= Cnt Do
|
||||||
Begin
|
Begin
|
||||||
If RegInInstruction(Tregister(Pai386(hp2)^.op2), p)
|
If RegInInstruction(Tregister(Pai386(hp2)^.op2), p) Or
|
||||||
|
RegInInstruction(Reg32(Tregister(Pai386(hp2)^.op2)), p)
|
||||||
Then PPaiProp(p^.fileinfo.line)^.CanBeRemoved := False;
|
Then PPaiProp(p^.fileinfo.line)^.CanBeRemoved := False;
|
||||||
Inc(Cnt2);
|
Inc(Cnt2);
|
||||||
GetNextInstruction(p, p);
|
GetNextInstruction(p, p);
|
||||||
@ -284,34 +533,38 @@ Var p, hp1: Pai;
|
|||||||
InstrCnt: Longint;
|
InstrCnt: Longint;
|
||||||
Begin
|
Begin
|
||||||
p := First;
|
p := First;
|
||||||
If (p^.typ in SkipInstr) Then
|
If (p^.typ in (SkipInstr + ait_marker)) Then
|
||||||
GetNextInstruction(p, p);
|
GetNextInstruction(p, p);
|
||||||
InstrCnt := 1;
|
InstrCnt := 1;
|
||||||
While Assigned(p) Do
|
While Assigned(p) Do
|
||||||
If PPaiProp(p^.fileinfo.line)^.CanBeRemoved
|
Begin
|
||||||
Then
|
{$ifndef noinstremove}
|
||||||
Begin
|
If PPaiProp(p^.fileinfo.line)^.CanBeRemoved
|
||||||
|
Then
|
||||||
|
Begin
|
||||||
{$IfDef TP}
|
{$IfDef TP}
|
||||||
Dispose(PPaiProp(p^.fileinfo.line));
|
Dispose(PPaiProp(p^.fileinfo.line));
|
||||||
{$EndIf}
|
{$EndIf}
|
||||||
GetNextInstruction(p, hp1);
|
GetNextInstruction(p, hp1);
|
||||||
AsmL^.Remove(p);
|
AsmL^.Remove(p);
|
||||||
Dispose(p, Done);
|
Dispose(p, Done);
|
||||||
p := hp1;
|
p := hp1;
|
||||||
Inc(InstrCnt)
|
Inc(InstrCnt);
|
||||||
End
|
End
|
||||||
Else
|
Else
|
||||||
Begin
|
{$endif noinstremove}
|
||||||
|
Begin
|
||||||
{$IfDef TP}
|
{$IfDef TP}
|
||||||
TmpLine := PPaiProp(p^.fileinfo.line)^.linesave;
|
TmpLine := PPaiProp(p^.fileinfo.line)^.linesave;
|
||||||
Dispose(PPaiProp(p^.fileinfo.line));
|
Dispose(PPaiProp(p^.fileinfo.line));
|
||||||
p^.fileinfo.line := TmpLine;
|
p^.fileinfo.line := TmpLine;
|
||||||
{$Else TP}
|
{$Else TP}
|
||||||
p^.fileinfo.line := PPaiProp(p^.fileinfo.line)^.linesave;
|
p^.fileinfo.line := PPaiProp(p^.fileinfo.line)^.linesave;
|
||||||
{$EndIf TP}
|
{$EndIf TP}
|
||||||
GetNextInstruction(p, p);
|
GetNextInstruction(p, p);
|
||||||
Inc(InstrCnt)
|
Inc(InstrCnt);
|
||||||
End;
|
End;
|
||||||
|
End;
|
||||||
{$IfNDef TP}
|
{$IfNDef TP}
|
||||||
FreeMem(PaiPropBlock, NrOfPaiObjs*(((SizeOf(TPaiProp)+3)div 4)*4))
|
FreeMem(PaiPropBlock, NrOfPaiObjs*(((SizeOf(TPaiProp)+3)div 4)*4))
|
||||||
{$EndIf TP}
|
{$EndIf TP}
|
||||||
@ -319,7 +572,7 @@ End;
|
|||||||
|
|
||||||
Procedure CSE(AsmL: PAasmOutput; First, Last: Pai);
|
Procedure CSE(AsmL: PAasmOutput; First, Last: Pai);
|
||||||
Begin
|
Begin
|
||||||
DoCSE(First, Last);
|
DoCSE(AsmL, First, Last);
|
||||||
RemoveInstructs(AsmL, First, Last);
|
RemoveInstructs(AsmL, First, Last);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
@ -327,7 +580,10 @@ End.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.8 1998-09-21 08:45:09 pierre
|
Revision 1.9 1998-10-01 20:21:49 jonas
|
||||||
|
* inter-register CSE, still requires some tweaks (peepholeoptpass2, better RegAlloc)
|
||||||
|
|
||||||
|
Revision 1.8 1998/09/21 08:45:09 pierre
|
||||||
+ added vmt_offset in tobjectdef.write for fututre use
|
+ added vmt_offset in tobjectdef.write for fututre use
|
||||||
(first steps to have objects without vmt if no virtual !!)
|
(first steps to have objects without vmt if no virtual !!)
|
||||||
+ added fpu_used field for tabstractprocdef :
|
+ added fpu_used field for tabstractprocdef :
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user