+ MovOpMov2MovOp optimization

git-svn-id: trunk@40359 -
This commit is contained in:
florian 2018-11-20 22:20:43 +00:00
parent c2e46dc8fc
commit ac37a54d79

View File

@ -1782,73 +1782,152 @@ unit aoptx86;
(hp1.typ = ait_instruction) and
GetNextInstruction(hp1, hp2) and
MatchInstruction(hp2,A_MOV,[]) and
OpsEqual(taicpu(hp2).oper[1]^, taicpu(p).oper[0]^) and
(taicpu(hp2).oper[0]^.typ=top_reg) and
(SuperRegistersEqual(taicpu(hp2).oper[0]^.reg,taicpu(p).oper[1]^.reg)) and
(IsFoldableArithOp(taicpu(hp1), taicpu(p).oper[1]^.reg) or
((taicpu(p).opsize=S_L) and (taicpu(hp1).opsize=S_Q) and (taicpu(hp2).opsize=S_L) and
IsFoldableArithOp(taicpu(hp1), newreg(R_INTREGISTER,getsupreg(taicpu(p).oper[1]^.reg),R_SUBQ)))
) then
{ change movsX/movzX reg/ref, reg2
add/sub/or/... reg3/$const, reg2
mov reg2 reg/ref
to add/sub/or/... reg3/$const, reg/ref }
begin
CopyUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next));
UpdateUsedRegs(TmpUsedRegs, tai(hp1.next));
If not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then
if OpsEqual(taicpu(hp2).oper[1]^, taicpu(p).oper[0]^) and
(taicpu(hp2).oper[0]^.typ=top_reg) then
{ change movsX/movzX reg/ref, reg2
add/sub/or/... reg3/$const, reg2
mov reg2 reg/ref
dealloc reg2
to
add/sub/or/... reg3/$const, reg/ref }
begin
{ by example:
movswl %si,%eax movswl %si,%eax p
decl %eax addl %edx,%eax hp1
movw %ax,%si movw %ax,%si hp2
->
movswl %si,%eax movswl %si,%eax p
decw %eax addw %edx,%eax hp1
movw %ax,%si movw %ax,%si hp2
}
DebugMsg(SPeepholeOptimization + 'MovOpMov2Op ('+
debug_op2str(taicpu(p).opcode)+debug_opsize2str(taicpu(p).opsize)+' '+
debug_op2str(taicpu(hp1).opcode)+debug_opsize2str(taicpu(hp1).opsize)+' '+
debug_op2str(taicpu(hp2).opcode)+debug_opsize2str(taicpu(hp2).opsize),p);
taicpu(hp1).changeopsize(taicpu(hp2).opsize);
{
->
movswl %si,%eax movswl %si,%eax p
decw %si addw %dx,%si hp1
movw %ax,%si movw %ax,%si hp2
}
case taicpu(hp1).ops of
1:
begin
taicpu(hp1).loadoper(0, taicpu(hp2).oper[1]^);
if taicpu(hp1).oper[0]^.typ=top_reg then
setsubreg(taicpu(hp1).oper[0]^.reg,getsubreg(taicpu(hp2).oper[0]^.reg));
CopyUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next));
UpdateUsedRegs(TmpUsedRegs, tai(hp1.next));
If not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then
begin
{ by example:
movswl %si,%eax movswl %si,%eax p
decl %eax addl %edx,%eax hp1
movw %ax,%si movw %ax,%si hp2
->
movswl %si,%eax movswl %si,%eax p
decw %eax addw %edx,%eax hp1
movw %ax,%si movw %ax,%si hp2
}
DebugMsg(SPeepholeOptimization + 'MovOpMov2Op ('+
debug_op2str(taicpu(p).opcode)+debug_opsize2str(taicpu(p).opsize)+' '+
debug_op2str(taicpu(hp1).opcode)+debug_opsize2str(taicpu(hp1).opsize)+' '+
debug_op2str(taicpu(hp2).opcode)+debug_opsize2str(taicpu(hp2).opsize),p);
taicpu(hp1).changeopsize(taicpu(hp2).opsize);
{
->
movswl %si,%eax movswl %si,%eax p
decw %si addw %dx,%si hp1
movw %ax,%si movw %ax,%si hp2
}
case taicpu(hp1).ops of
1:
begin
taicpu(hp1).loadoper(0, taicpu(hp2).oper[1]^);
if taicpu(hp1).oper[0]^.typ=top_reg then
setsubreg(taicpu(hp1).oper[0]^.reg,getsubreg(taicpu(hp2).oper[0]^.reg));
end;
2:
begin
taicpu(hp1).loadoper(1, taicpu(hp2).oper[1]^);
if (taicpu(hp1).oper[0]^.typ=top_reg) and
(taicpu(hp1).opcode<>A_SHL) and
(taicpu(hp1).opcode<>A_SHR) and
(taicpu(hp1).opcode<>A_SAR) then
setsubreg(taicpu(hp1).oper[0]^.reg,getsubreg(taicpu(hp2).oper[0]^.reg));
end;
else
internalerror(2008042701);
end;
2:
begin
taicpu(hp1).loadoper(1, taicpu(hp2).oper[1]^);
if (taicpu(hp1).oper[0]^.typ=top_reg) and
(taicpu(hp1).opcode<>A_SHL) and
(taicpu(hp1).opcode<>A_SHR) and
(taicpu(hp1).opcode<>A_SAR) then
setsubreg(taicpu(hp1).oper[0]^.reg,getsubreg(taicpu(hp2).oper[0]^.reg));
{
->
decw %si addw %dx,%si p
}
asml.remove(p);
asml.remove(hp2);
p.Free;
hp2.Free;
p := hp1;
end;
ReleaseUsedRegs(TmpUsedRegs);
end
else if MatchOpType(taicpu(hp2),top_reg,top_reg) and
not(SuperRegistersEqual(taicpu(hp1).oper[0]^.reg,taicpu(hp2).oper[1]^.reg))
{$ifdef i386}
{ byte registers of esi, edi, ebp, esp are not available on i386 }
and ((taicpu(hp2).opsize<>S_B) or not(getsupreg(taicpu(hp1).oper[0]^.reg) in [RS_ESI,RS_EDI,RS_EBP,RS_ESP]))
{$endif i386}
then
{ change movsX/movzX reg/ref, reg2
add/sub/or/... regX/$const, reg2
mov reg2, reg3
dealloc reg2
to
movsX/movzX reg/ref, reg3
add/sub/or/... reg3/$const, reg3
}
begin
CopyUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next));
UpdateUsedRegs(TmpUsedRegs, tai(hp1.next));
If not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then
begin
{ by example:
movswl %si,%eax movswl %si,%eax p
decl %eax addl %edx,%eax hp1
movw %ax,%si movw %ax,%si hp2
->
movswl %si,%eax movswl %si,%eax p
decw %eax addw %edx,%eax hp1
movw %ax,%si movw %ax,%si hp2
}
DebugMsg(SPeepholeOptimization + 'MovOpMov2MovOp ('+
debug_op2str(taicpu(p).opcode)+debug_opsize2str(taicpu(p).opsize)+' '+
debug_op2str(taicpu(hp1).opcode)+debug_opsize2str(taicpu(hp1).opsize)+' '+
debug_op2str(taicpu(hp2).opcode)+debug_opsize2str(taicpu(hp2).opsize),p);
taicpu(hp1).changeopsize(taicpu(hp2).opsize);
taicpu(p).changeopsize(taicpu(hp2).opsize);
if taicpu(p).oper[0]^.typ=top_reg then
setsubreg(taicpu(p).oper[0]^.reg,getsubreg(taicpu(hp2).oper[0]^.reg));
taicpu(p).loadoper(1, taicpu(hp2).oper[1]^);
AllocRegBetween(taicpu(p).oper[1]^.reg,p,hp1,usedregs);
{
->
movswl %si,%eax movswl %si,%eax p
decw %si addw %dx,%si hp1
movw %ax,%si movw %ax,%si hp2
}
case taicpu(hp1).ops of
1:
begin
taicpu(hp1).loadoper(0, taicpu(hp2).oper[1]^);
if taicpu(hp1).oper[0]^.typ=top_reg then
setsubreg(taicpu(hp1).oper[0]^.reg,getsubreg(taicpu(hp2).oper[0]^.reg));
end;
2:
begin
taicpu(hp1).loadoper(1, taicpu(hp2).oper[1]^);
if (taicpu(hp1).oper[0]^.typ=top_reg) and
(taicpu(hp1).opcode<>A_SHL) and
(taicpu(hp1).opcode<>A_SHR) and
(taicpu(hp1).opcode<>A_SAR) then
setsubreg(taicpu(hp1).oper[0]^.reg,getsubreg(taicpu(hp2).oper[0]^.reg));
end;
else
internalerror(2018111801);
end;
else
internalerror(2008042701);
end;
{
->
decw %si addw %dx,%si p
}
asml.remove(p);
asml.remove(hp2);
p.Free;
hp2.Free;
p := hp1;
{
->
decw %si addw %dx,%si p
}
asml.remove(hp2);
hp2.Free;
// p := hp1;
end;
ReleaseUsedRegs(TmpUsedRegs);
end;
ReleaseUsedRegs(TmpUsedRegs);
end
else if GetNextInstruction_p and