* patch by J. Gareth Moreton: Some cleaning up of OptPass2JMP and OptPass2MOV, resolves #36553

git-svn-id: trunk@43919 -
This commit is contained in:
florian 2020-01-12 10:33:21 +00:00
parent 124c64152d
commit 2b70c64d09

View File

@ -3386,30 +3386,10 @@ unit aoptx86;
{ OptPass2MOV will now exit but will be called again if OptPass1MOV
returned True and the instruction is still a MOV, thus checking
the optimisations below }
else
{ Since OptPass2JMP returned false, no optimisations were done to
the jump. Additionally, a label will definitely follow the jump
(although it may have become dead), so skip ahead as far as
possible }
begin
while (p <> hp1) do
begin
{ Nothing changed between the MOV and the JMP, so
don't bother with "UpdateUsedRegsAndOptimize" }
UpdateUsedRegs(p);
p := tai(p.Next);
end;
{ Use "UpdateUsedRegsAndOptimize" here though, because the
label might now be dead and can be stripped out }
p := tai(UpdateUsedRegsAndOptimize(hp1).Next);
{ If p is a label, then Result will be False and program flow
will move onto the next list entry in "PeepHoleOptPass2" }
if (p = BlockEnd) or not (p.typ in [ait_align, ait_label]) then
Result := True;
end;
{ If OptPass2JMP returned False, no optimisations were done to
the jump and there are no further optimisations that can be done
to the MOV instruction on this pass }
end
else if MatchOpType(taicpu(p),top_reg,top_reg) and
{$ifdef x86_64}
@ -4027,7 +4007,8 @@ unit aoptx86;
function TX86AsmOptimizer.OptPass2Jmp(var p : tai) : boolean;
var
hp1, hp2 : tai;
hp1, hp2, hp3: tai;
OperIdx: Integer;
begin
result:=false;
if (taicpu(p).oper[0]^.typ=top_ref) and (taicpu(p).oper[0]^.ref^.refaddr=addr_full) and (taicpu(p).oper[0]^.ref^.base=NR_NO) and
@ -4077,7 +4058,27 @@ unit aoptx86;
if Assigned(hp2) and MatchInstruction(hp2, A_RET, [S_NO]) then
begin
{ Duplicate the MOV instruction }
asml.InsertBefore(hp1.getcopy, p);
hp3:=tai(hp1.getcopy);
asml.InsertBefore(hp3, p);
{ Make sure the compiler knows about any final registers written here }
for OperIdx := 0 to 1 do
with taicpu(hp3).oper[OperIdx]^ do
begin
case typ of
top_ref:
begin
if (ref^.base <> NR_NO) and (ref^.base <> NR_RIP) then
AllocRegBetween(ref^.base, hp3, tai(p.Next), UsedRegs);
if (ref^.index <> NR_NO) and (ref^.index <> NR_RIP) then
AllocRegBetween(ref^.index, hp3, tai(p.Next), UsedRegs);
end;
top_reg:
AllocRegBetween(reg, hp3, tai(p.Next), UsedRegs);
else
;
end;
end;
{ Now change the jump into a RET instruction }
ConvertJumpToRET(p, hp2);
@ -4085,7 +4086,7 @@ unit aoptx86;
end;
end;
else
{ Do nothing };
;
end;
end;
end;