* i386 does not use anymore its own assembler optimizer loops

git-svn-id: trunk@43464 -
This commit is contained in:
florian 2019-11-14 21:14:01 +00:00
parent 0ab0eefae0
commit 632f13c47a

View File

@ -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.