|
@@ -2902,7 +2902,7 @@ unit aoptx86;
|
|
|
|
|
|
function TX86AsmOptimizer.FuncMov2Func(var p: tai; const hp1: tai): Boolean;
|
|
|
var
|
|
|
- hp2: tai;
|
|
|
+ hp2, hp_regalloc: tai;
|
|
|
p_SourceReg, p_TargetReg: TRegister;
|
|
|
|
|
|
begin
|
|
@@ -2962,15 +2962,32 @@ unit aoptx86;
|
|
|
else
|
|
|
begin
|
|
|
DebugMsg(SPeepholeOptimization + 'Removed MOV and changed destination on previous instruction to optimise register usage (FuncMov2Func)', p);
|
|
|
- taicpu(hp2).oper[taicpu(hp2).ops-1]^.reg := p_TargetReg;
|
|
|
+
|
|
|
+ { if %reg2 (p_SourceReg) is allocated before func., remove it completely }
|
|
|
+ hp_regalloc := FindRegAllocBackward(p_SourceReg, hp2);
|
|
|
+ if Assigned(hp_regalloc) then
|
|
|
+ begin
|
|
|
+ Asml.Remove(hp_regalloc);
|
|
|
+
|
|
|
+ if Assigned(FindRegDealloc(p_SourceReg, p)) then
|
|
|
+ begin
|
|
|
+ ExcludeRegFromUsedRegs(p_SourceReg, UsedRegs);
|
|
|
+ hp_regalloc.Free;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ { If the register is not explicitly deallocated, it's
|
|
|
+ being reused, so move the allocation to after func. }
|
|
|
+ AsmL.InsertAfter(hp_regalloc, hp2);
|
|
|
+ end;
|
|
|
|
|
|
if not RegInInstruction(p_TargetReg, hp2) then
|
|
|
begin
|
|
|
- { Since we're allocating from an earlier point, we
|
|
|
- need to remove the register from the tracking }
|
|
|
- ExcludeRegFromUsedRegs(p_TargetReg, TmpUsedRegs);
|
|
|
+ TransferUsedRegs(TmpUsedRegs);
|
|
|
AllocRegBetween(p_TargetReg, hp2, p, TmpUsedRegs);
|
|
|
end;
|
|
|
+
|
|
|
+ { Actually make the changes }
|
|
|
+ taicpu(hp2).oper[taicpu(hp2).ops-1]^.reg := p_TargetReg;
|
|
|
RemoveCurrentp(p, hp1);
|
|
|
|
|
|
{ If the Func was another MOV instruction, we might get
|