* patch by J. Gareth Moreton: cleanup TX86AsmOptimizer.OptPass1MOV after DeepMov changes, first part of #36670

git-svn-id: trunk@44164 -
This commit is contained in:
florian 2020-02-13 20:20:10 +00:00
parent fd4fb5fa19
commit 3a5eb0ec59

View File

@ -2074,25 +2074,7 @@ unit aoptx86;
with %treg is not used after }
case taicpu(p).oper[0]^.typ Of
top_reg:
begin
{ change
mov %reg, %treg
mov %treg, y
to
mov %reg, y
}
if taicpu(hp1).oper[1]^.typ=top_reg then
AllocRegBetween(taicpu(hp1).oper[1]^.reg,p,hp1,usedregs);
taicpu(p).loadOper(1,taicpu(hp1).oper[1]^);
DebugMsg(SPeepholeOptimization + 'MovMov2Mov 2 done',p);
asml.remove(hp1);
hp1.free;
Result:=true;
Exit;
end;
{ top_reg is covered by DeepMOVOpt }
top_const:
begin
{ change
@ -2135,43 +2117,26 @@ unit aoptx86;
Exit;
end;
else
{ Do nothing };
;
end
else
{ %treg is used afterwards }
case taicpu(p).oper[0]^.typ of
top_const:
if
(
not (cs_opt_size in current_settings.optimizerswitches) or
(taicpu(hp1).opsize = S_B)
) and
(
(taicpu(hp1).oper[1]^.typ = top_reg) or
((taicpu(p).oper[0]^.val >= low(longint)) and (taicpu(p).oper[0]^.val <= high(longint)))
) then
begin
DebugMsg(SPeepholeOptimization + debug_operstr(taicpu(hp1).oper[0]^) + ' = $' + debug_tostr(taicpu(p).oper[0]^.val) + '; changed to minimise pipeline stall (MovMov2Mov 6b)',hp1);
taicpu(hp1).loadconst(0, taicpu(p).oper[0]^.val);
end;
top_reg:
begin
DebugMsg(SPeepholeOptimization + debug_operstr(taicpu(hp1).oper[0]^) + ' = ' + debug_regname(taicpu(p).oper[0]^.reg) + '; changed to minimise pipeline stall (MovMov2Mov 6c)',hp1);
AllocRegBetween(taicpu(p).oper[0]^.reg, p, hp1, UsedRegs);
if MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) then
begin
DebugMsg(SPeepholeOptimization + 'Mov2Nop 2 done',hp1);
asml.remove(hp1);
hp1.free;
Result := True;
Exit;
end;
taicpu(hp1).loadreg(0, taicpu(p).oper[0]^.reg);
end;
else
{ Do nothing };
end;
{ %treg is used afterwards, but all eventualities
other than the first MOV instruction being a constant
are covered by DeepMOVOpt, so only check for that }
if (taicpu(p).oper[0]^.typ = top_const) and
(
{ For MOV operations, a size saving is only made if the register/const is byte-sized }
not (cs_opt_size in current_settings.optimizerswitches) or
(taicpu(hp1).opsize = S_B)
) and
(
(taicpu(hp1).oper[1]^.typ = top_reg) or
((taicpu(p).oper[0]^.val >= low(longint)) and (taicpu(p).oper[0]^.val <= high(longint)))
) then
begin
DebugMsg(SPeepholeOptimization + debug_operstr(taicpu(hp1).oper[0]^) + ' = $' + debug_tostr(taicpu(p).oper[0]^.val) + '; changed to minimise pipeline stall (MovMov2Mov 6b)',hp1);
taicpu(hp1).loadconst(0, taicpu(p).oper[0]^.val);
end;
end;
if (taicpu(hp1).oper[0]^.typ = taicpu(p).oper[1]^.typ) and
(taicpu(hp1).oper[1]^.typ = taicpu(p).oper[0]^.typ) then
@ -2517,79 +2482,7 @@ unit aoptx86;
Internalerror(2019103001);
end;
end;
{ Change
mov %reg1, %reg2
xxx %reg2, ???
to
mov %reg1, %reg2
xxx %reg1, ???
to avoid a write/read penalty
}
if MatchOpType(taicpu(p),top_reg,top_reg) and
((MatchInstruction(hp1,A_OR,A_AND,A_TEST,[]) and
MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[0]^) and
MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[1]^)) or
(MatchInstruction(hp1,A_CMP,[]) and
MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[1]^) and
MatchOpType(taicpu(hp1),top_const,top_reg)
)
) then
{ we have
mov %reg1, %reg2
test/or/and %reg2, %reg2
}
begin
TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next));
{ reg1 will be used after the first instruction,
so update the allocation info }
AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,usedregs);
if GetNextInstruction(hp1, hp2) and
(hp2.typ = ait_instruction) and
taicpu(hp2).is_jmp and
not(RegUsedAfterInstruction(taicpu(hp1).oper[1]^.reg, hp1, TmpUsedRegs)) then
{ change
mov %reg1, %reg2
test/or/and %reg2, %reg2
jxx
to
test %reg1, %reg1
jxx
}
begin
if taicpu(hp1).opcode<>A_CMP then
taicpu(hp1).loadoper(0,taicpu(p).oper[0]^);
taicpu(hp1).loadoper(1,taicpu(p).oper[0]^);
DebugMsg(SPeepholeOptimization + 'MovTest/Cmp/Or/AndJxx2Test/Cmp/Or/AndJxx done',p);
RemoveCurrentP(p);
Exit;
end
else
{ change
mov %reg1, %reg2
test/or/and %reg2, %reg2
to
mov %reg1, %reg2
test/or/and %reg1, %reg1
}
begin
if taicpu(hp1).opcode<>A_CMP then
taicpu(hp1).loadoper(0,taicpu(p).oper[0]^);
taicpu(hp1).loadoper(1,taicpu(p).oper[0]^);
DebugMsg(SPeepholeOptimization + 'MovTest/Cmp/Or/AndJxx2MovTest/Cmp/Or/AndJxx done',p);
end;
end;
{ leave out the mov from "mov reg, x(%frame_pointer); leave/ret" (with
x >= RetOffset) as it doesn't do anything (it writes either to a
parameter or to the temporary storage room for the function