From 2b70c64d09d8d58476034e1cee01b30d96c19e3b Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 12 Jan 2020 10:33:21 +0000 Subject: [PATCH] * patch by J. Gareth Moreton: Some cleaning up of OptPass2JMP and OptPass2MOV, resolves #36553 git-svn-id: trunk@43919 - --- compiler/x86/aoptx86.pas | 53 ++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/compiler/x86/aoptx86.pas b/compiler/x86/aoptx86.pas index c7cb2d9a1d..f4028f21d0 100644 --- a/compiler/x86/aoptx86.pas +++ b/compiler/x86/aoptx86.pas @@ -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;