Bug fix to MovMov2Mov 6 optimisation exposed by 4012c3dbd4 (and miscellaneous code refactors)

This commit is contained in:
J. Gareth "Curious Kit" Moreton 2021-10-22 12:33:16 +01:00 committed by J. Gareth "Kit" Moreton
parent 7997f884b7
commit 342803532d

View File

@ -111,7 +111,7 @@ unit aoptx86;
{ Replaces all references to AOldReg in an instruction to ANewReg, { Replaces all references to AOldReg in an instruction to ANewReg,
except where the register is being written } except where the register is being written }
function ReplaceRegisterInInstruction(const p: taicpu; const AOldReg, ANewReg: TRegister): Boolean; class function ReplaceRegisterInInstruction(const p: taicpu; const AOldReg, ANewReg: TRegister): Boolean; static;
{ Returns true if the reference only refers to ESP or EBP (or their 64-bit equivalents), { Returns true if the reference only refers to ESP or EBP (or their 64-bit equivalents),
or writes to a global symbol } or writes to a global symbol }
@ -2198,7 +2198,7 @@ unit aoptx86;
{ Replaces all references to AOldReg in an instruction to ANewReg } { Replaces all references to AOldReg in an instruction to ANewReg }
function TX86AsmOptimizer.ReplaceRegisterInInstruction(const p: taicpu; const AOldReg, ANewReg: TRegister): Boolean; class function TX86AsmOptimizer.ReplaceRegisterInInstruction(const p: taicpu; const AOldReg, ANewReg: TRegister): Boolean;
const const
ReadFlag: array[0..3] of TInsChange = (Ch_Rop1, Ch_Rop2, Ch_Rop3, Ch_Rop4); ReadFlag: array[0..3] of TInsChange = (Ch_Rop1, Ch_Rop2, Ch_Rop3, Ch_Rop4);
var var
@ -3436,7 +3436,7 @@ unit aoptx86;
} }
CurrentReg := taicpu(p).oper[0]^.reg; { Saves on a handful of pointer dereferences } CurrentReg := taicpu(p).oper[0]^.reg; { Saves on a handful of pointer dereferences }
RegName1 := debug_regname(taicpu(hp2).oper[0]^.reg); RegName1 := debug_regname(taicpu(hp2).oper[0]^.reg);
if taicpu(hp2).oper[1]^.reg = CurrentReg then if MatchOperand(taicpu(hp2).oper[1]^, CurrentReg) then
begin begin
{ %reg = y - remove hp2 completely (doing it here instead of relying on { %reg = y - remove hp2 completely (doing it here instead of relying on
the "mov %reg,%reg" optimisation might cut down on a pass iteration) } the "mov %reg,%reg" optimisation might cut down on a pass iteration) }
@ -3468,22 +3468,27 @@ unit aoptx86;
begin begin
AllocRegBetween(CurrentReg, p, hp2, UsedRegs); AllocRegBetween(CurrentReg, p, hp2, UsedRegs);
taicpu(hp2).loadReg(0, CurrentReg); taicpu(hp2).loadReg(0, CurrentReg);
if TempRegUsed then
begin
{ Don't remove the first instruction if the temporary register is in use }
DebugMsg(SPeepholeOptimization + RegName1 + ' = ' + debug_regname(CurrentReg) + '; changed to minimise pipeline stall (MovMov2Mov 6a}',hp2);
{ No need to set Result to True. If there's another instruction later on DebugMsg(SPeepholeOptimization + RegName1 + ' = ' + debug_regname(CurrentReg) + '; changed to minimise pipeline stall (MovMov2Mov 6a}',hp2);
that can be optimised, it will be detected when the main Pass 1 loop
reaches what is now hp2 and passes it through OptPass1MOV. [Kit] }; { Check to see if the register also appears in the reference }
end if (taicpu(hp2).oper[1]^.typ = top_ref) then
else ReplaceRegisterInRef(taicpu(hp2).oper[1]^.ref^, ActiveReg, CurrentReg);
{ Don't remove the first instruction if the temporary register is in use }
if not TempRegUsed and
{ ReplaceRegisterInRef won't actually replace the register if it's a different size }
not RegInOp(ActiveReg, taicpu(hp2).oper[1]^) then
begin begin
DebugMsg(SPeepholeOptimization + 'MovMov2Mov 6 done',p); DebugMsg(SPeepholeOptimization + 'MovMov2Mov 6 done',p);
RemoveCurrentP(p, hp1); RemoveCurrentP(p, hp1);
Result:=true; Result:=true;
Exit; Exit;
end; end;
{ No need to set Result to True here. If there's another instruction later
on that can be optimised, it will be detected when the main Pass 1 loop
reaches what is now hp2 and passes it through OptPass1MOV. [Kit] }
end; end;
end; end;
top_const: top_const: