Rerun the peephole optimizer after removing the current instruction.

This lets the optimizer pickup on more possible optimizations.

git-svn-id: trunk@26606 -
This commit is contained in:
masta 2014-01-28 16:00:51 +00:00
parent 57ff589ec7
commit 9e0af11ad8

View File

@ -38,7 +38,7 @@ Type
function PeepHoleOptPass1Cpu(var p: tai): boolean; override; function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
procedure PeepHoleOptPass2;override; procedure PeepHoleOptPass2;override;
Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;override; Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;override;
procedure RemoveSuperfluousMove(const p: tai; movp: tai; const optimizer: string); function RemoveSuperfluousMove(const p: tai; movp: tai; const optimizer: string): boolean;
function RegUsedAfterInstruction(reg: Tregister; p: tai; function RegUsedAfterInstruction(reg: Tregister; p: tai;
var AllUsedRegs: TAllUsedRegs): Boolean; var AllUsedRegs: TAllUsedRegs): Boolean;
{ returns true if reg reaches it's end of life at p, this means it is either { returns true if reg reaches it's end of life at p, this means it is either
@ -152,8 +152,9 @@ Implementation
result := (oper.typ = top_reg) and (oper.reg = reg); result := (oper.typ = top_reg) and (oper.reg = reg);
end; end;
procedure RemoveRedundantMove(const cmpp: tai; movp: tai; asml: TAsmList); function RemoveRedundantMove(const cmpp: tai; movp: tai; asml: TAsmList):Boolean;
begin begin
Result:=false;
if (taicpu(movp).condition = C_EQ) and if (taicpu(movp).condition = C_EQ) and
(taicpu(cmpp).oper[0]^.reg = taicpu(movp).oper[0]^.reg) and (taicpu(cmpp).oper[0]^.reg = taicpu(movp).oper[0]^.reg) and
(taicpu(cmpp).oper[1]^.val = taicpu(movp).oper[1]^.val) then (taicpu(cmpp).oper[1]^.val = taicpu(movp).oper[1]^.val) then
@ -161,6 +162,7 @@ Implementation
asml.insertafter(tai_comment.Create(strpnew('Peephole CmpMovMov - Removed redundant moveq')), movp); asml.insertafter(tai_comment.Create(strpnew('Peephole CmpMovMov - Removed redundant moveq')), movp);
asml.remove(movp); asml.remove(movp);
movp.free; movp.free;
Result:=true;
end; end;
end; end;
@ -337,12 +339,13 @@ Implementation
end; end;
{$endif DEBUG_AOPTCPU} {$endif DEBUG_AOPTCPU}
procedure TCpuAsmOptimizer.RemoveSuperfluousMove(const p: tai; movp: tai; const optimizer: string); function TCpuAsmOptimizer.RemoveSuperfluousMove(const p: tai; movp: tai; const optimizer: string):boolean;
var var
alloc, alloc,
dealloc : tai_regalloc; dealloc : tai_regalloc;
hp1 : tai; hp1 : tai;
begin begin
Result:=false;
if MatchInstruction(movp, A_MOV, [taicpu(p).condition], [PF_None]) and if MatchInstruction(movp, A_MOV, [taicpu(p).condition], [PF_None]) and
(taicpu(movp).ops=2) and {We can't optimize if there is a shiftop} (taicpu(movp).ops=2) and {We can't optimize if there is a shiftop}
MatchOperand(taicpu(movp).oper[1]^, taicpu(p).oper[0]^.reg) and MatchOperand(taicpu(movp).oper[1]^, taicpu(p).oper[0]^.reg) and
@ -374,6 +377,7 @@ Implementation
if assigned(dealloc) then if assigned(dealloc) then
begin begin
DebugMsg('Peephole '+optimizer+' removed superfluous mov', movp); DebugMsg('Peephole '+optimizer+' removed superfluous mov', movp);
result:=true;
{ taicpu(p).oper[0]^.reg is not used anymore, try to find its allocation { taicpu(p).oper[0]^.reg is not used anymore, try to find its allocation
and remove it if possible } and remove it if possible }
@ -586,6 +590,7 @@ Implementation
asml.remove(hp1); asml.remove(hp1);
hp1.free; hp1.free;
Result:=true;
end end
else else
case taicpu(p).opcode of case taicpu(p).opcode of
@ -647,8 +652,9 @@ Implementation
taicpu(p).oppostfix:=PF_D; taicpu(p).oppostfix:=PF_D;
asml.remove(hp1); asml.remove(hp1);
hp1.free; hp1.free;
result:=true;
end; end;
LookForPostindexedPattern(taicpu(p)); Result:=LookForPostindexedPattern(taicpu(p)) or Result;
end; end;
A_LDR: A_LDR:
begin begin
@ -711,6 +717,7 @@ Implementation
taicpu(p).oppostfix:=PF_D; taicpu(p).oppostfix:=PF_D;
asml.remove(hp1); asml.remove(hp1);
hp1.free; hp1.free;
result:=true;
end; end;
end; end;
@ -738,8 +745,9 @@ Implementation
taicpu(p).oper[0]^.reg := taicpu(hp1).oper[0]^.reg; taicpu(p).oper[0]^.reg := taicpu(hp1).oper[0]^.reg;
asml.remove(hp1); asml.remove(hp1);
hp1.free; hp1.free;
result:=true;
end; end;
LookForPostindexedPattern(taicpu(p)); Result:=LookForPostindexedPattern(taicpu(p)) or Result;
{ Remove superfluous mov after ldr { Remove superfluous mov after ldr
changes changes
ldr reg1, ref ldr reg1, ref
@ -754,8 +762,10 @@ Implementation
* ldr+mov have the same conditions * ldr+mov have the same conditions
* mov does not set flags * mov does not set flags
} }
if (taicpu(p).oppostfix<>PF_D) and GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) then if (taicpu(p).oppostfix<>PF_D) and
RemoveSuperfluousMove(p, hp1, 'LdrMov2Ldr'); GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
RemoveSuperfluousMove(p, hp1, 'LdrMov2Ldr') then
Result:=true;
end; end;
A_MOV: A_MOV:
begin begin
@ -803,6 +813,7 @@ Implementation
p.free; p.free;
hp1.free; hp1.free;
p:=hp2; p:=hp2;
Result:=true;
end; end;
ReleaseUsedRegs(TmpUsedRegs); ReleaseUsedRegs(TmpUsedRegs);
end end
@ -1090,6 +1101,7 @@ Implementation
GetNextInstruction(hp2,hp1); GetNextInstruction(hp2,hp1);
asml.remove(hp2); asml.remove(hp2);
hp2.free; hp2.free;
result:=true;
if not assigned(hp1) then break; if not assigned(hp1) then break;
end end
{ {
@ -1109,6 +1121,7 @@ Implementation
p.free; p.free;
p:=hp1; p:=hp1;
GetNextInstruction(hp1,hp1); GetNextInstruction(hp1,hp1);
result:=true;
if not assigned(hp1) then if not assigned(hp1) then
break; break;
end; end;
@ -1162,6 +1175,7 @@ Implementation
asml.remove(p); asml.remove(p);
p.free; p.free;
p:=hp1; p:=hp1;
Result:=true;
end; end;
end; end;
end; end;
@ -1301,6 +1315,7 @@ Implementation
hp1.free; hp1.free;
p:=hp2; p:=hp2;
DebugMsg('Peephole FoldShiftProcess done', p); DebugMsg('Peephole FoldShiftProcess done', p);
Result:=true;
break; break;
end; end;
end; end;
@ -1372,14 +1387,16 @@ Implementation
asml.remove(p); asml.remove(p);
p.free; p.free;
p:=hp1; p:=hp1;
Result:=true;
end; end;
{ {
Often we see shifts and then a superfluous mov to another register Often we see shifts and then a superfluous mov to another register
In the future this might be handled in RedundantMovProcess when it uses RegisterTracking In the future this might be handled in RedundantMovProcess when it uses RegisterTracking
} }
if (taicpu(p).opcode = A_MOV) and if (taicpu(p).opcode = A_MOV) and
GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) then GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
RemoveSuperfluousMove(p, hp1, 'MovMov2Mov'); RemoveSuperfluousMove(p, hp1, 'MovMov2Mov') then
Result:=true;
end; end;
A_ADD, A_ADD,
A_ADC, A_ADC,
@ -1621,6 +1638,7 @@ Implementation
asml.remove(p); asml.remove(p);
p.free; p.free;
p:=hp1; p:=hp1;
result:=true;
break; break;
end; end;
end; end;
@ -1632,11 +1650,10 @@ Implementation
to to
add reg2, ... add reg2, ...
} }
if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) then if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
begin (taicpu(p).ops=3) and
if (taicpu(p).ops=3) then RemoveSuperfluousMove(p, hp1, 'DataMov2Data') then
RemoveSuperfluousMove(p, hp1, 'DataMov2Data'); Result:=true;
end;
if MatchInstruction(p, [A_ADD,A_SUB], [C_None], [PF_None]) and if MatchInstruction(p, [A_ADD,A_SUB], [C_None], [PF_None]) and
LookForPreindexedPattern(taicpu(p)) then LookForPreindexedPattern(taicpu(p)) then
@ -1646,6 +1663,7 @@ Implementation
asml.remove(p); asml.remove(p);
p.free; p.free;
p:=hp1; p:=hp1;
Result:=true;
end; end;
end; end;
{$ifdef dummy} {$ifdef dummy}
@ -1795,11 +1813,9 @@ Implementation
p:=hp2; p:=hp2;
result:=true; result:=true;
end end
else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) then else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
begin RemoveSuperfluousMove(p, hp1, 'UxtbMov2Data') then
//if (taicpu(p).ops=3) then Result:=true;
RemoveSuperfluousMove(p, hp1, 'UxtbMov2Data');
end;
end; end;
A_UXTH: A_UXTH:
begin begin
@ -1883,11 +1899,9 @@ Implementation
p:=hp1; p:=hp1;
result:=true; result:=true;
end end
else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) then else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
begin RemoveSuperfluousMove(p, hp1, 'UxthMov2Data') then
//if (taicpu(p).ops=3) then Result:=true;
RemoveSuperfluousMove(p, hp1, 'UxthMov2Data');
end;
end; end;
A_CMP: A_CMP:
begin begin
@ -1908,8 +1922,8 @@ Implementation
MatchInstruction(hp2, A_MOV, [C_EQ, C_NE], [PF_NONE]) and MatchInstruction(hp2, A_MOV, [C_EQ, C_NE], [PF_NONE]) and
(taicpu(hp1).oper[1]^.typ = top_const) then (taicpu(hp1).oper[1]^.typ = top_const) then
begin begin
RemoveRedundantMove(p, hp1, asml); Result:=RemoveRedundantMove(p, hp1, asml) or Result;
RemoveRedundantMove(p, hp2, asml); Result:=RemoveRedundantMove(p, hp2, asml) or Result;
end; end;
end; end;
A_STM: A_STM: