mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 16:49:07 +02:00
* i386 does not use anymore its own assembler optimizer loops
git-svn-id: trunk@43464 -
This commit is contained in:
parent
0ab0eefae0
commit
632f13c47a
@ -35,10 +35,11 @@ unit aoptcpu;
|
|||||||
|
|
||||||
Type
|
Type
|
||||||
TCpuAsmOptimizer = class(TX86AsmOptimizer)
|
TCpuAsmOptimizer = class(TX86AsmOptimizer)
|
||||||
procedure Optimize; override;
|
function PrePeepHoleOptsCpu(var p: tai): boolean; override;
|
||||||
procedure PrePeepHoleOpts; override;
|
function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
|
||||||
procedure PeepHoleOptPass1; override;
|
function PeepHoleOptPass2Cpu(var p: tai): boolean; override;
|
||||||
procedure PeepHoleOptPass2; override;
|
function PostPeepHoleOptsCpu(var p : tai) : boolean; override;
|
||||||
|
|
||||||
procedure PostPeepHoleOpts; override;
|
procedure PostPeepHoleOpts; override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -82,28 +83,22 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TCPUAsmOptimizer.PrePeepHoleOpts;
|
function TCPUAsmOPtimizer.PrePeepHoleOptsCpu(var p: tai): boolean;
|
||||||
var
|
|
||||||
p: tai;
|
|
||||||
begin
|
begin
|
||||||
p := BlockStart;
|
Result:=False;
|
||||||
while (p <> BlockEnd) Do
|
case p.typ of
|
||||||
begin
|
ait_instruction:
|
||||||
case p.Typ Of
|
|
||||||
Ait_Instruction:
|
|
||||||
begin
|
begin
|
||||||
if InsContainsSegRef(taicpu(p)) then
|
if InsContainsSegRef(taicpu(p)) then
|
||||||
begin
|
begin
|
||||||
p := tai(p.next);
|
p := tai(p.next);
|
||||||
continue;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
case taicpu(p).opcode Of
|
case taicpu(p).opcode Of
|
||||||
A_IMUL:
|
A_IMUL:
|
||||||
if PrePeepholeOptIMUL(p) then
|
Result:=PrePeepholeOptIMUL(p);
|
||||||
Continue;
|
|
||||||
A_SAR,A_SHR:
|
A_SAR,A_SHR:
|
||||||
if PrePeepholeOptSxx(p) then
|
Result:=PrePeepholeOptSxx(p);
|
||||||
continue;
|
|
||||||
A_XOR:
|
A_XOR:
|
||||||
begin
|
begin
|
||||||
if (taicpu(p).oper[0]^.typ = top_reg) and
|
if (taicpu(p).oper[0]^.typ = top_reg) and
|
||||||
@ -114,6 +109,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
taicpu(p).opcode := A_MOV;
|
taicpu(p).opcode := A_MOV;
|
||||||
taicpu(p).loadConst(0,0);
|
taicpu(p).loadConst(0,0);
|
||||||
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
@ -123,13 +119,10 @@ begin
|
|||||||
else
|
else
|
||||||
;
|
;
|
||||||
end;
|
end;
|
||||||
p := tai(p.next)
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ First pass of peephole optimizations }
|
function TCPUAsmOPtimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
|
||||||
procedure TCPUAsmOPtimizer.PeepHoleOptPass1;
|
|
||||||
|
|
||||||
function WriteOk : Boolean;
|
function WriteOk : Boolean;
|
||||||
begin
|
begin
|
||||||
@ -138,7 +131,7 @@ function WriteOk : Boolean;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
p,hp1,hp2 : tai;
|
hp1,hp2 : tai;
|
||||||
hp3,hp4: tai;
|
hp3,hp4: tai;
|
||||||
v:aint;
|
v:aint;
|
||||||
|
|
||||||
@ -241,11 +234,7 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
p := BlockStart;
|
result:=False;
|
||||||
ClearUsedRegs;
|
|
||||||
while (p <> BlockEnd) Do
|
|
||||||
begin
|
|
||||||
UpDateUsedRegs(UsedRegs, tai(p.next));
|
|
||||||
case p.Typ Of
|
case p.Typ Of
|
||||||
ait_instruction:
|
ait_instruction:
|
||||||
begin
|
begin
|
||||||
@ -253,7 +242,8 @@ begin
|
|||||||
if InsContainsSegRef(taicpu(p)) then
|
if InsContainsSegRef(taicpu(p)) then
|
||||||
begin
|
begin
|
||||||
p:=tai(p.next);
|
p:=tai(p.next);
|
||||||
continue;
|
Result:=true;
|
||||||
|
exit;
|
||||||
end;
|
end;
|
||||||
{ Handle Jmp Optimizations }
|
{ Handle Jmp Optimizations }
|
||||||
if taicpu(p).is_jmp then
|
if taicpu(p).is_jmp then
|
||||||
@ -292,7 +282,8 @@ begin
|
|||||||
asml.remove(p);
|
asml.remove(p);
|
||||||
p.free;
|
p.free;
|
||||||
p:=hp2;
|
p:=hp2;
|
||||||
continue;
|
Result:=true;
|
||||||
|
exit;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
@ -321,7 +312,8 @@ begin
|
|||||||
begin
|
begin
|
||||||
GetFinalDestination(asml, taicpu(p),0);
|
GetFinalDestination(asml, taicpu(p),0);
|
||||||
p:=tai(p.next);
|
p:=tai(p.next);
|
||||||
continue;
|
Result:=true;
|
||||||
|
exit;
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -334,8 +326,7 @@ begin
|
|||||||
begin
|
begin
|
||||||
case taicpu(p).opcode Of
|
case taicpu(p).opcode Of
|
||||||
A_AND:
|
A_AND:
|
||||||
if OptPass1And(p) then
|
Result:=OptPass1And(p);
|
||||||
continue;
|
|
||||||
A_CMP:
|
A_CMP:
|
||||||
begin
|
begin
|
||||||
{ cmp register,$8000 neg register
|
{ cmp register,$8000 neg register
|
||||||
@ -366,7 +357,7 @@ begin
|
|||||||
Taicpu(hp1).condition:=C_O
|
Taicpu(hp1).condition:=C_O
|
||||||
else
|
else
|
||||||
Taicpu(hp1).condition:=C_NO;
|
Taicpu(hp1).condition:=C_NO;
|
||||||
continue;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
{
|
{
|
||||||
@@2: @@2:
|
@@2: @@2:
|
||||||
@ -412,34 +403,20 @@ begin
|
|||||||
p.free;
|
p.free;
|
||||||
hp1.free;
|
hp1.free;
|
||||||
p := hp2;
|
p := hp2;
|
||||||
continue;
|
Result:=true;
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
A_FLD:
|
A_FLD:
|
||||||
if OptPass1FLD(p) then
|
Result:=OptPass1FLD(p);
|
||||||
continue;
|
|
||||||
A_FSTP,A_FISTP:
|
A_FSTP,A_FISTP:
|
||||||
if OptPass1FSTP(p) then
|
Result:=OptPass1FSTP(p);
|
||||||
continue;
|
|
||||||
A_LEA:
|
A_LEA:
|
||||||
begin
|
Result:=OptPass1LEA(p);
|
||||||
if OptPass1LEA(p) then
|
|
||||||
continue;
|
|
||||||
end;
|
|
||||||
|
|
||||||
A_MOV:
|
A_MOV:
|
||||||
begin
|
Result:=OptPass1MOV(p);
|
||||||
If OptPass1MOV(p) then
|
|
||||||
Continue;
|
|
||||||
end;
|
|
||||||
|
|
||||||
A_MOVSX,
|
A_MOVSX,
|
||||||
A_MOVZX :
|
A_MOVZX :
|
||||||
begin
|
Result:=OptPass1Movx(p);
|
||||||
If OptPass1Movx(p) then
|
|
||||||
Continue
|
|
||||||
end;
|
|
||||||
|
|
||||||
(* should not be generated anymore by the current code generator
|
(* should not be generated anymore by the current code generator
|
||||||
A_POP:
|
A_POP:
|
||||||
begin
|
begin
|
||||||
@ -539,14 +516,13 @@ begin
|
|||||||
taicpu(p).loadConst(0,taicpu(p).oper[0]^.val shl 16 + word(taicpu(hp1).oper[0]^.val));
|
taicpu(p).loadConst(0,taicpu(p).oper[0]^.val shl 16 + word(taicpu(hp1).oper[0]^.val));
|
||||||
asml.remove(hp1);
|
asml.remove(hp1);
|
||||||
hp1.free;
|
hp1.free;
|
||||||
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
A_SHL, A_SAL:
|
A_SHL, A_SAL:
|
||||||
if OptPass1SHLSAL(p) then
|
Result:=OptPass1SHLSAL(p);
|
||||||
Continue;
|
|
||||||
A_SUB:
|
A_SUB:
|
||||||
if OptPass1Sub(p) then
|
Result:=OptPass1Sub(p);
|
||||||
continue;
|
|
||||||
A_MOVAPD,
|
A_MOVAPD,
|
||||||
A_MOVAPS,
|
A_MOVAPS,
|
||||||
A_MOVUPD,
|
A_MOVUPD,
|
||||||
@ -555,8 +531,7 @@ begin
|
|||||||
A_VMOVAPD,
|
A_VMOVAPD,
|
||||||
A_VMOVUPS,
|
A_VMOVUPS,
|
||||||
A_VMOVUPD:
|
A_VMOVUPD:
|
||||||
if OptPass1_V_MOVAP(p) then
|
Result:=OptPass1_V_MOVAP(p);
|
||||||
continue;
|
|
||||||
A_VDIVSD,
|
A_VDIVSD,
|
||||||
A_VDIVSS,
|
A_VDIVSS,
|
||||||
A_VSUBSD,
|
A_VSUBSD,
|
||||||
@ -571,25 +546,19 @@ begin
|
|||||||
A_VORPS,
|
A_VORPS,
|
||||||
A_VXORPD,
|
A_VXORPD,
|
||||||
A_VXORPS:
|
A_VXORPS:
|
||||||
if OptPass1VOP(p) then
|
Result:=OptPass1VOP(p);
|
||||||
continue;
|
|
||||||
A_MULSD,
|
A_MULSD,
|
||||||
A_MULSS,
|
A_MULSS,
|
||||||
A_ADDSD,
|
A_ADDSD,
|
||||||
A_ADDSS:
|
A_ADDSS:
|
||||||
if OptPass1OP(p) then
|
Result:=OptPass1OP(p);
|
||||||
continue;
|
|
||||||
A_VMOVSD,
|
A_VMOVSD,
|
||||||
A_VMOVSS,
|
A_VMOVSS,
|
||||||
A_MOVSD,
|
A_MOVSD,
|
||||||
A_MOVSS:
|
A_MOVSS:
|
||||||
if OptPass1MOVXX(p) then
|
Result:=OptPass1MOVXX(p);
|
||||||
continue;
|
|
||||||
A_SETcc:
|
A_SETcc:
|
||||||
begin
|
Result:=OptPass1SETcc(p);
|
||||||
if OptPass1SETcc(p) then
|
|
||||||
continue;
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
;
|
;
|
||||||
end;
|
end;
|
||||||
@ -598,50 +567,30 @@ begin
|
|||||||
else
|
else
|
||||||
;
|
;
|
||||||
end;
|
end;
|
||||||
updateUsedRegs(UsedRegs,p);
|
|
||||||
p:=tai(p.next);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TCPUAsmOptimizer.PeepHoleOptPass2;
|
function TCPUAsmOptimizer.PeepHoleOptPass2Cpu(var p: tai): boolean;
|
||||||
var
|
|
||||||
p : tai;
|
|
||||||
begin
|
begin
|
||||||
p := BlockStart;
|
Result:=false;
|
||||||
ClearUsedRegs;
|
|
||||||
while (p <> BlockEnd) Do
|
|
||||||
begin
|
|
||||||
UpdateUsedRegs(UsedRegs, tai(p.next));
|
|
||||||
case p.Typ Of
|
case p.Typ Of
|
||||||
Ait_Instruction:
|
Ait_Instruction:
|
||||||
begin
|
begin
|
||||||
if InsContainsSegRef(taicpu(p)) then
|
if InsContainsSegRef(taicpu(p)) then
|
||||||
begin
|
exit;
|
||||||
p := tai(p.next);
|
|
||||||
continue;
|
|
||||||
end;
|
|
||||||
case taicpu(p).opcode Of
|
case taicpu(p).opcode Of
|
||||||
A_Jcc:
|
A_Jcc:
|
||||||
if OptPass2Jcc(p) then
|
Result:=OptPass2Jcc(p);
|
||||||
continue;
|
|
||||||
A_Lea:
|
A_Lea:
|
||||||
if OptPass2Lea(p) then
|
Result:=OptPass2Lea(p);
|
||||||
continue;
|
|
||||||
A_FSTP,A_FISTP:
|
A_FSTP,A_FISTP:
|
||||||
if OptPass1FSTP(p) then
|
Result:=OptPass1FSTP(p);
|
||||||
continue;
|
|
||||||
A_IMUL:
|
A_IMUL:
|
||||||
if OptPass2Imul(p) then
|
Result:=OptPass2Imul(p);
|
||||||
continue;
|
|
||||||
A_JMP:
|
A_JMP:
|
||||||
if OptPass2Jmp(p) then
|
Result:=OptPass2Jmp(p);
|
||||||
continue;
|
|
||||||
A_MOV:
|
A_MOV:
|
||||||
begin
|
Result:=OptPass2MOV(p);
|
||||||
if OptPass2MOV(p) then
|
|
||||||
continue;
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
;
|
;
|
||||||
end;
|
end;
|
||||||
@ -649,41 +598,28 @@ begin
|
|||||||
else
|
else
|
||||||
;
|
;
|
||||||
end;
|
end;
|
||||||
p := tai(p.next)
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TCPUAsmOptimizer.PostPeepHoleOpts;
|
function TCPUAsmOptimizer.PostPeepHoleOptsCpu(var p : tai) : boolean;
|
||||||
var
|
var
|
||||||
p,hp1: tai;
|
hp1: tai;
|
||||||
begin
|
begin
|
||||||
p := BlockStart;
|
Result:=false;
|
||||||
ClearUsedRegs;
|
|
||||||
while (p <> BlockEnd) Do
|
|
||||||
begin
|
|
||||||
UpdateUsedRegs(UsedRegs, tai(p.next));
|
|
||||||
case p.Typ Of
|
case p.Typ Of
|
||||||
Ait_Instruction:
|
Ait_Instruction:
|
||||||
begin
|
begin
|
||||||
if InsContainsSegRef(taicpu(p)) then
|
if InsContainsSegRef(taicpu(p)) then
|
||||||
begin
|
Exit;
|
||||||
p := tai(p.next);
|
|
||||||
continue;
|
|
||||||
end;
|
|
||||||
case taicpu(p).opcode Of
|
case taicpu(p).opcode Of
|
||||||
A_CALL:
|
A_CALL:
|
||||||
if PostPeepHoleOptCall(p) then
|
Result:=PostPeepHoleOptCall(p);
|
||||||
Continue;
|
|
||||||
A_LEA:
|
A_LEA:
|
||||||
if PostPeepholeOptLea(p) then
|
Result:=PostPeepholeOptLea(p);
|
||||||
Continue;
|
|
||||||
A_CMP:
|
A_CMP:
|
||||||
if PostPeepholeOptCmp(p) then
|
Result:=PostPeepholeOptCmp(p);
|
||||||
Continue;
|
|
||||||
A_MOV:
|
A_MOV:
|
||||||
if PostPeepholeOptMov(p) then
|
Result:=PostPeepholeOptMov(p);
|
||||||
Continue;
|
|
||||||
A_MOVZX:
|
A_MOVZX:
|
||||||
{ if register vars are on, it's possible there is code like }
|
{ if register vars are on, it's possible there is code like }
|
||||||
{ "cmpl $3,%eax; movzbl 8(%ebp),%ebx; je .Lxxx" }
|
{ "cmpl $3,%eax; movzbl 8(%ebp),%ebx; je .Lxxx" }
|
||||||
@ -734,95 +670,24 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
A_TEST, A_OR:
|
A_TEST, A_OR:
|
||||||
|
Result:=PostPeepholeOptTestOr(p);
|
||||||
|
else
|
||||||
|
;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
else
|
||||||
|
;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TCpuAsmOptimizer.PostPeepHoleOpts;
|
||||||
begin
|
begin
|
||||||
if PostPeepholeOptTestOr(p) then
|
inherited;
|
||||||
Continue;
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
else
|
|
||||||
;
|
|
||||||
end;
|
|
||||||
p := tai(p.next)
|
|
||||||
end;
|
|
||||||
OptReferences;
|
OptReferences;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
Procedure TCpuAsmOptimizer.Optimize;
|
|
||||||
Var
|
|
||||||
HP: Tai;
|
|
||||||
pass: longint;
|
|
||||||
slowopt, changed, lastLoop: boolean;
|
|
||||||
Begin
|
|
||||||
slowopt := (cs_opt_level3 in current_settings.optimizerswitches);
|
|
||||||
pass := 0;
|
|
||||||
changed := false;
|
|
||||||
repeat
|
|
||||||
lastLoop :=
|
|
||||||
not(slowopt) or
|
|
||||||
(not changed and (pass > 2)) or
|
|
||||||
{ prevent endless loops }
|
|
||||||
(pass = 4);
|
|
||||||
changed := false;
|
|
||||||
{ Setup labeltable, always necessary }
|
|
||||||
blockstart := tai(asml.first);
|
|
||||||
pass_1;
|
|
||||||
{ Blockend now either contains an ait_marker with Kind = mark_AsmBlockStart, }
|
|
||||||
{ or nil }
|
|
||||||
While Assigned(BlockStart) Do
|
|
||||||
Begin
|
|
||||||
if (cs_opt_peephole in current_settings.optimizerswitches) then
|
|
||||||
begin
|
|
||||||
if (pass = 0) then
|
|
||||||
PrePeepHoleOpts;
|
|
||||||
{ Peephole optimizations }
|
|
||||||
PeepHoleOptPass1;
|
|
||||||
{ Only perform them twice in the first pass }
|
|
||||||
if pass = 0 then
|
|
||||||
PeepHoleOptPass1;
|
|
||||||
end;
|
|
||||||
{ More peephole optimizations }
|
|
||||||
if (cs_opt_peephole in current_settings.optimizerswitches) then
|
|
||||||
begin
|
|
||||||
PeepHoleOptPass2;
|
|
||||||
if lastLoop then
|
|
||||||
PostPeepHoleOpts;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ Continue where we left off, BlockEnd is either the start of an }
|
|
||||||
{ assembler block or nil }
|
|
||||||
BlockStart := BlockEnd;
|
|
||||||
While Assigned(BlockStart) And
|
|
||||||
(BlockStart.typ = ait_Marker) And
|
|
||||||
(Tai_Marker(BlockStart).Kind = mark_AsmBlockStart) Do
|
|
||||||
Begin
|
|
||||||
{ We stopped at an assembler block, so skip it }
|
|
||||||
Repeat
|
|
||||||
BlockStart := Tai(BlockStart.Next);
|
|
||||||
Until (BlockStart.Typ = Ait_Marker) And
|
|
||||||
(Tai_Marker(Blockstart).Kind = mark_AsmBlockEnd);
|
|
||||||
{ Blockstart now contains a Tai_marker(mark_AsmBlockEnd) }
|
|
||||||
If GetNextInstruction(BlockStart, HP) And
|
|
||||||
((HP.typ <> ait_Marker) Or
|
|
||||||
(Tai_Marker(HP).Kind <> mark_AsmBlockStart)) Then
|
|
||||||
{ There is no assembler block anymore after the current one, so }
|
|
||||||
{ optimize the next block of "normal" instructions }
|
|
||||||
pass_1
|
|
||||||
{ Otherwise, skip the next assembler block }
|
|
||||||
else
|
|
||||||
blockStart := hp;
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
inc(pass);
|
|
||||||
until lastLoop;
|
|
||||||
dfa.free;
|
|
||||||
|
|
||||||
End;
|
|
||||||
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
casmoptimizer:=TCpuAsmOptimizer;
|
casmoptimizer:=TCpuAsmOptimizer;
|
||||||
end.
|
end.
|
||||||
|
Loading…
Reference in New Issue
Block a user