* x86: Refactoring register update code in "OptPass2ADD" and "OptPass2SUB"

This commit is contained in:
J. Gareth "Curious Kit" Moreton 2025-02-25 23:56:27 +00:00 committed by FPK
parent b2dd980329
commit f85aa24ad0

View File

@ -15564,6 +15564,7 @@ unit aoptx86;
NewRef: TReference; NewRef: TReference;
Distance: Cardinal; Distance: Cardinal;
TempTracking: TAllUsedRegs; TempTracking: TAllUsedRegs;
DoAddMov2Lea: Boolean;
{ This entire nested function is used in an if-statement below, but we { This entire nested function is used in an if-statement below, but we
want to avoid all the used reg transfers and GetNextInstruction calls want to avoid all the used reg transfers and GetNextInstruction calls
@ -15573,10 +15574,11 @@ unit aoptx86;
hp2: tai; hp2: tai;
begin begin
TransferUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
hp2 := p; if (cs_opt_level3 in current_settings.optimizerswitches) then
repeat UpdateUsedRegsBetween(TmpUsedRegs, p, hp1)
UpdateUsedRegs(TmpUsedRegs, tai(hp2.Next)); else
until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1); { p and hp1 will be adjacent }
UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
Result := not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs); Result := not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs);
end; end;
@ -15625,11 +15627,13 @@ unit aoptx86;
begin begin
{ Update the register tracking to the MOV instruction } { Update the register tracking to the MOV instruction }
CopyUsedRegs(TempTracking); CopyUsedRegs(TempTracking);
hp2 := p; if (cs_opt_level3 in current_settings.optimizerswitches) then
repeat UpdateUsedRegsBetween(UsedRegs, p, hp1)
UpdateUsedRegs(tai(hp2.Next)); else
until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1); { p and hp1 will be adjacent }
UpdateUsedRegs(UsedRegs, tai(p.Next));
hp2 := hp1;
{ if hp1 <> hp2 after the call, then hp1 got removed, so let { if hp1 <> hp2 after the call, then hp1 got removed, so let
OptPass2ADD get called again } OptPass2ADD get called again }
if OptPass2MOV(hp1) and (hp1 <> hp2) then if OptPass2MOV(hp1) and (hp1 <> hp2) then
@ -15750,18 +15754,22 @@ unit aoptx86;
) then ) then
begin begin
TransferUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
hp2 := p; if (cs_opt_level3 in current_settings.optimizerswitches) then
repeat UpdateUsedRegsBetween(TmpUsedRegs, p, hp1)
UpdateUsedRegs(TmpUsedRegs, tai(hp2.Next)); else
until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1); { p and hp1 will be adjacent }
UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
if ( if (
{ Don't do AddMov2LeaAdd under -Os, but do allow AddMov2Lea } SetAndTest(
not (cs_opt_size in current_settings.optimizerswitches) or
( (
not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) and not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) and
not RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs) not RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)
) ),
DoAddMov2Lea
) or
{ Don't do AddMov2LeaAdd under -Os, but do allow AddMov2Lea }
not (cs_opt_size in current_settings.optimizerswitches)
) then ) then
begin begin
{ Change the MOV instruction to a LEA instruction, and update the { Change the MOV instruction to a LEA instruction, and update the
@ -15775,8 +15783,18 @@ unit aoptx86;
taicpu(hp1).opcode := A_LEA; taicpu(hp1).opcode := A_LEA;
taicpu(hp1).loadref(0, NewRef); taicpu(hp1).loadref(0, NewRef);
if RegUsedAfterInstruction(NewRef.base, hp1, TmpUsedRegs) or if DoAddMov2Lea then
RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs) then begin
{ Since %reg1 or the flags aren't used afterwards, we can delete p completely }
DebugMsg(SPeepholeOptimization + 'AddMov2Lea', hp1);
if (cs_opt_level3 in current_settings.optimizerswitches) then
{ hp1 may not be the immediate next instruction under -O3 }
RemoveCurrentp(p)
else
RemoveCurrentp(p, hp1);
end
else
begin begin
hp2 := tai(hp1.Next); { for the benefit of AllocRegBetween } hp2 := tai(hp1.Next); { for the benefit of AllocRegBetween }
@ -15787,17 +15805,6 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization + 'AddMov2LeaAdd', p); DebugMsg(SPeepholeOptimization + 'AddMov2LeaAdd', p);
p := hp1; p := hp1;
end
else
begin
{ Since %reg1 or the flags aren't used afterwards, we can delete p completely }
DebugMsg(SPeepholeOptimization + 'AddMov2Lea', hp1);
if (cs_opt_level3 in current_settings.optimizerswitches) then
{ hp1 may not be the immediate next instruction under -O3 }
RemoveCurrentp(p)
else
RemoveCurrentp(p, hp1);
end; end;
Result := True; Result := True;
@ -15923,6 +15930,7 @@ unit aoptx86;
NewRef: TReference; NewRef: TReference;
Distance: Cardinal; Distance: Cardinal;
TempTracking: TAllUsedRegs; TempTracking: TAllUsedRegs;
DoSubMov2Lea: Boolean;
begin begin
Result := False; Result := False;
@ -15968,11 +15976,13 @@ unit aoptx86;
begin begin
{ Update the register tracking to the MOV instruction } { Update the register tracking to the MOV instruction }
CopyUsedRegs(TempTracking); CopyUsedRegs(TempTracking);
hp2 := p; if (cs_opt_level3 in current_settings.optimizerswitches) then
repeat UpdateUsedRegsBetween(UsedRegs, p, hp1)
UpdateUsedRegs(tai(hp2.Next)); else
until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1); { p and hp1 will be adjacent }
UpdateUsedRegs(UsedRegs, tai(p.Next));
hp2 := hp1;
{ if hp1 <> hp2 after the call, then hp1 got removed, so let { if hp1 <> hp2 after the call, then hp1 got removed, so let
OptPass2SUB get called again } OptPass2SUB get called again }
if OptPass2MOV(hp1) and (hp1 <> hp2) then if OptPass2MOV(hp1) and (hp1 <> hp2) then
@ -16023,18 +16033,22 @@ unit aoptx86;
) then ) then
begin begin
TransferUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
hp2 := p; if (cs_opt_level3 in current_settings.optimizerswitches) then
repeat UpdateUsedRegsBetween(TmpUsedRegs, p, hp1)
UpdateUsedRegs(TmpUsedRegs, tai(hp2.Next)); else
until not (cs_opt_level3 in current_settings.optimizerswitches) or not GetNextInstruction(hp2, hp2) or (hp2 = hp1); { p and hp1 will be adjacent }
UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
if ( if (
{ Don't do SubMov2LeaSub under -Os, but do allow SubMov2Lea } SetAndTest(
not (cs_opt_size in current_settings.optimizerswitches) or
( (
not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) and not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) and
not RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs) not RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)
) ),
DoSubMov2Lea
) or
{ Don't do SubMov2LeaSub under -Os, but do allow SubMov2Lea }
not (cs_opt_size in current_settings.optimizerswitches)
) then ) then
begin begin
{ Change the MOV instruction to a LEA instruction, and update the { Change the MOV instruction to a LEA instruction, and update the
@ -16047,10 +16061,18 @@ unit aoptx86;
taicpu(hp1).opcode := A_LEA; taicpu(hp1).opcode := A_LEA;
taicpu(hp1).loadref(0, NewRef); taicpu(hp1).loadref(0, NewRef);
TransferUsedRegs(TmpUsedRegs); if DoSubMov2Lea then
UpdateUsedRegs(TmpUsedRegs, tai(p.Next)); begin
if RegUsedAfterInstruction(NewRef.base, hp1, TmpUsedRegs) or { Since %reg1 or the flags aren't used afterwards, we can delete p completely }
RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs) then DebugMsg(SPeepholeOptimization + 'SubMov2Lea', hp1);
if (cs_opt_level3 in current_settings.optimizerswitches) then
{ hp1 may not be the immediate next instruction under -O3 }
RemoveCurrentp(p)
else
RemoveCurrentp(p, hp1);
end
else
begin begin
hp2 := tai(hp1.Next); { for the benefit of AllocRegBetween } hp2 := tai(hp1.Next); { for the benefit of AllocRegBetween }
@ -16061,17 +16083,6 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization + 'SubMov2LeaSub', p); DebugMsg(SPeepholeOptimization + 'SubMov2LeaSub', p);
p := hp1; p := hp1;
end
else
begin
{ Since %reg1 or the flags aren't used afterwards, we can delete p completely }
DebugMsg(SPeepholeOptimization + 'SubMov2Lea', hp1);
if (cs_opt_level3 in current_settings.optimizerswitches) then
{ hp1 may not be the immediate next instruction under -O3 }
RemoveCurrentp(p)
else
RemoveCurrentp(p, hp1);
end; end;
Result := True; Result := True;