2
0
Эх сурвалжийг харах

* x86: Registers are now allocated properly during a FuncMov2Func
optimisation

J. Gareth "Curious Kit" Moreton 2 жил өмнө
parent
commit
3cae3e7e48
1 өөрчлөгдсөн 22 нэмэгдсэн , 5 устгасан
  1. 22 5
      compiler/x86/aoptx86.pas

+ 22 - 5
compiler/x86/aoptx86.pas

@@ -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