mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 06:49:23 +02:00
Bug fix to MovMov2Mov 6 optimisation exposed by 4012c3dbd4
(and miscellaneous code refactors)
This commit is contained in:
parent
7997f884b7
commit
342803532d
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user