mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 11:29:27 +02:00
+ MovOpMov2MovOp optimization
git-svn-id: trunk@40359 -
This commit is contained in:
parent
c2e46dc8fc
commit
ac37a54d79
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user