mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-29 23:40:14 +02:00
* "add/sub const,%esp;sub $2,%esp" wasn't always optimized
This commit is contained in:
parent
13bffb711a
commit
aff06b2d4e
@ -47,7 +47,7 @@ Procedure PeepHoleOptPass1(Asml: PAasmOutput; BlockStart, BlockEnd: Pai);
|
||||
|
||||
Var
|
||||
l : longint;
|
||||
p ,hp1, hp2: pai;
|
||||
p ,hp1, hp2, hp3, hp4: pai;
|
||||
TmpBool1, TmpBool2: Boolean;
|
||||
|
||||
TmpRef: PReference;
|
||||
@ -97,6 +97,51 @@ Var
|
||||
End;
|
||||
End;
|
||||
|
||||
Function DoSubAddOpt(var p: Pai): Boolean;
|
||||
Begin
|
||||
DoSubAddOpt := False;
|
||||
If GetLastInstruction(p, hp1) And
|
||||
(hp1^.typ = ait_instruction) And
|
||||
(Pai386(hp1)^.opsize = Pai386(p)^.opsize) then
|
||||
Case Pai386(hp1)^.opcode Of
|
||||
A_DEC:
|
||||
If (Pai386(hp1)^.oper[0].typ = top_reg) And
|
||||
(Pai386(hp1)^.oper[0].reg = Pai386(p)^.oper[1].reg) Then
|
||||
Begin
|
||||
Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val+1);
|
||||
AsmL^.Remove(hp1);
|
||||
Dispose(hp1, Done)
|
||||
End;
|
||||
A_SUB:
|
||||
If (Pai386(hp1)^.oper[0].typ = top_const) And
|
||||
(Pai386(hp1)^.oper[1].typ = top_reg) And
|
||||
(Pai386(hp1)^.oper[1].reg = Pai386(p)^.oper[1].reg) Then
|
||||
Begin
|
||||
Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val+Pai386(hp1)^.oper[0].val);
|
||||
AsmL^.Remove(hp1);
|
||||
Dispose(hp1, Done)
|
||||
End;
|
||||
A_ADD:
|
||||
If (Pai386(hp1)^.oper[0].typ = top_const) And
|
||||
(Pai386(hp1)^.oper[1].typ = top_reg) And
|
||||
(Pai386(hp1)^.oper[1].reg = Pai386(p)^.oper[1].reg) Then
|
||||
Begin
|
||||
Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val-Pai386(hp1)^.oper[0].val);
|
||||
AsmL^.Remove(hp1);
|
||||
Dispose(hp1, Done);
|
||||
If (Pai386(p)^.oper[0].val = 0) Then
|
||||
Begin
|
||||
hp1 := Pai(p^.next);
|
||||
AsmL^.Remove(p);
|
||||
Dispose(p, Done);
|
||||
If Not GetLastInstruction(hp1, p) Then
|
||||
p := hp1;
|
||||
DoSubAddOpt := True;
|
||||
End
|
||||
End;
|
||||
End;
|
||||
End;
|
||||
|
||||
Begin
|
||||
P := BlockStart;
|
||||
UsedRegs := [];
|
||||
@ -113,7 +158,6 @@ Begin
|
||||
because it can never be executed}
|
||||
If (pai386(p)^.opcode = A_JMP) Then
|
||||
Begin
|
||||
hp1 := pai(p^.next);
|
||||
While GetNextInstruction(p, hp1) and
|
||||
((hp1^.typ <> ait_label) or
|
||||
{ skip unused labels, they're not referenced anywhere }
|
||||
@ -210,13 +254,50 @@ Begin
|
||||
A_CMP:
|
||||
Begin
|
||||
If (Pai386(p)^.oper[0].typ = top_const) And
|
||||
(Pai386(p)^.oper[1].typ = top_reg) And
|
||||
(Pai386(p)^.oper[1].typ in [top_reg,top_ref]) And
|
||||
(Pai386(p)^.oper[0].val = 0) Then
|
||||
{$ifdef foropt}
|
||||
If GetNextInstruction(p, hp1) And
|
||||
(hp1^.typ = ait_instruction) And
|
||||
(Pai386(hp1)^.is_jmp) and
|
||||
(pai386(hp1)^.opcode=A_Jcc) and
|
||||
(pai386(hp1)^.condition in [C_LE,C_BE]) and
|
||||
GetNextInstruction(hp1,hp2) and
|
||||
(hp2^.typ = ait_instruction) and
|
||||
(Pai386(hp2)^.opcode = A_DEC) And
|
||||
OpsEqual(Pai386(hp2)^.oper[0],Pai386(p)^.oper[1]) And
|
||||
GetNextInstruction(hp2, hp3) And
|
||||
(hp3^.typ = ait_instruction) and
|
||||
(Pai386(hp3)^.is_jmp) and
|
||||
(Pai386(hp3)^.opcode = A_JMP) And
|
||||
GetNextInstruction(hp3, hp4) And
|
||||
FindLabel(PAsmLabel(pai386(hp1)^.oper[0].sym),hp4)
|
||||
Then
|
||||
Begin
|
||||
Pai386(hp2)^.Opcode := A_SUB;
|
||||
Pai386(hp2)^.Loadoper(1,Pai386(hp2)^.oper[0]);
|
||||
Pai386(hp2)^.LoadConst(0,1);
|
||||
Pai386(hp2)^.ops:=2;
|
||||
Pai386(hp3)^.Opcode := A_Jcc;
|
||||
Case pai386(hp1)^.condition of
|
||||
C_LE: Pai386(hp3)^.condition := C_GE;
|
||||
C_BE: Pai386(hp3)^.condition := C_AE;
|
||||
End;
|
||||
AsmL^.Remove(p);
|
||||
AsmL^.Remove(hp1);
|
||||
Dispose(p, Done);
|
||||
Dispose(hp1, Done);
|
||||
p := hp2;
|
||||
continue;
|
||||
End
|
||||
Else
|
||||
{$endif foropt}
|
||||
{change "cmp $0, %reg" to "test %reg, %reg"}
|
||||
Begin
|
||||
Pai386(p)^.opcode := A_TEST;
|
||||
Pai386(p)^.loadreg(0,Pai386(p)^.oper[1].reg);
|
||||
End;
|
||||
If (Pai386(p)^.oper[1].typ = top_reg) Then
|
||||
Begin
|
||||
Pai386(p)^.opcode := A_TEST;
|
||||
Pai386(p)^.loadreg(0,Pai386(p)^.oper[1].reg);
|
||||
End;
|
||||
End;
|
||||
A_FLD:
|
||||
Begin
|
||||
@ -362,7 +443,8 @@ Begin
|
||||
(Not(GetNextInstruction(p, hp1)) Or
|
||||
{GetNextInstruction(p, hp1) And}
|
||||
Not((Pai(hp1)^.typ = ait_instruction) And
|
||||
((pai386(hp1)^.opcode=A_Jcc) and (pai386(hp1)^.condition in [C_O,C_NO]))))
|
||||
((pai386(hp1)^.opcode=A_Jcc) and
|
||||
(pai386(hp1)^.condition in [C_O,C_NO]))))
|
||||
Then
|
||||
Begin
|
||||
New(TmpRef);
|
||||
@ -1284,9 +1366,9 @@ Begin
|
||||
(Pai386(hp1)^.oper[1].ref^.base = R_ESP)))) do
|
||||
hp1 := Pai(hp1^.next);
|
||||
If Assigned(hp1) And
|
||||
(Pai(hp1)^.typ = ait_instruction) And
|
||||
(Pai386(hp1)^.opcode = A_PUSH) And
|
||||
(Pai386(hp1)^.opsize = S_W)
|
||||
(Pai(hp1)^.typ = ait_instruction) And
|
||||
(Pai386(hp1)^.opcode = A_PUSH) And
|
||||
(Pai386(hp1)^.opsize = S_W)
|
||||
Then
|
||||
Begin
|
||||
Pai386(hp1)^.changeopsize(S_L);
|
||||
@ -1297,53 +1379,10 @@ Begin
|
||||
Dispose(p, Done);
|
||||
p := hp1;
|
||||
Continue
|
||||
End
|
||||
Else
|
||||
If GetLastInstruction(p, hp1) And
|
||||
(Pai(hp1)^.typ = ait_instruction) And
|
||||
(Pai386(hp1)^.opcode = A_SUB) And
|
||||
(Pai386(hp1)^.oper[0].typ = top_const) And
|
||||
(Pai386(hp1)^.oper[1].typ = top_reg) And
|
||||
(Pai386(hp1)^.oper[1].reg = R_ESP)
|
||||
Then
|
||||
Begin
|
||||
Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val+Pai386(hp1)^.oper[0].val);
|
||||
AsmL^.Remove(hp1);
|
||||
Dispose(hp1, Done);
|
||||
End;
|
||||
End;
|
||||
If DoSubAddOpt(p) Then continue;
|
||||
End
|
||||
Else
|
||||
If GetLastInstruction(p, hp1) And
|
||||
(hp1^.typ = ait_instruction) And
|
||||
(Pai386(hp1)^.opsize = Pai386(p)^.opsize) then
|
||||
Case Pai386(hp1)^.opcode Of
|
||||
A_DEC:
|
||||
If (Pai386(hp1)^.oper[0].typ = top_reg) And
|
||||
(Pai386(hp1)^.oper[0].reg = Pai386(p)^.oper[1].reg) Then
|
||||
Begin
|
||||
Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val+1);
|
||||
AsmL^.Remove(hp1);
|
||||
Dispose(hp1, Done)
|
||||
End;
|
||||
A_SUB:
|
||||
If (Pai386(hp1)^.oper[0].typ = top_const) And
|
||||
(Pai386(hp1)^.oper[1].typ = top_reg) And
|
||||
(Pai386(hp1)^.oper[1].reg = Pai386(p)^.oper[1].reg) Then
|
||||
Begin
|
||||
Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val+Pai386(hp1)^.oper[0].val);
|
||||
AsmL^.Remove(hp1);
|
||||
Dispose(hp1, Done)
|
||||
End;
|
||||
A_ADD:
|
||||
If (Pai386(hp1)^.oper[0].typ = top_const) And
|
||||
(Pai386(hp1)^.oper[1].typ = top_reg) And
|
||||
(Pai386(hp1)^.oper[1].reg = Pai386(p)^.oper[1].reg) Then
|
||||
Begin
|
||||
Pai386(p)^.LoadConst(0,Pai386(p)^.oper[0].val-Pai386(hp1)^.oper[0].val);
|
||||
AsmL^.Remove(hp1);
|
||||
Dispose(hp1, Done)
|
||||
End;
|
||||
End
|
||||
Else If DoSubAddOpt(p) Then Continue
|
||||
End;
|
||||
A_TEST, A_OR:
|
||||
{removes the line marked with (x) from the sequence
|
||||
@ -1352,8 +1391,8 @@ Begin
|
||||
j(n)z _Label
|
||||
as the first instruction already adjusts the ZF}
|
||||
Begin
|
||||
If OpsEqual(Pai386(p)^.oper[0],Pai386(p)^.oper[1]) And
|
||||
GetLastInstruction(p, hp1) And
|
||||
If OpsEqual(Pai386(p)^.oper[0],Pai386(p)^.oper[1]) Then
|
||||
If GetLastInstruction(p, hp1) And
|
||||
(pai(hp1)^.typ = ait_instruction) Then
|
||||
Case Pai386(hp1)^.opcode Of
|
||||
A_ADD, A_SUB, A_OR, A_XOR, A_AND, A_SHL, A_SHR:
|
||||
@ -1391,7 +1430,10 @@ Begin
|
||||
continue
|
||||
End;
|
||||
End
|
||||
End;
|
||||
End
|
||||
Else
|
||||
|
||||
|
||||
End;
|
||||
End;
|
||||
end; { if is_jmp }
|
||||
@ -1524,7 +1566,10 @@ End.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.60 1999-08-04 00:23:16 florian
|
||||
Revision 1.61 1999-08-05 15:02:48 jonas
|
||||
* "add/sub const,%esp;sub $2,%esp" wasn't always optimized
|
||||
|
||||
Revision 1.60 1999/08/04 00:23:16 florian
|
||||
* renamed i386asm and i386base to cpuasm and cpubase
|
||||
|
||||
Revision 1.59 1999/08/03 17:13:28 jonas
|
||||
|
Loading…
Reference in New Issue
Block a user