Browse Source

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

git-svn-id: trunk@43919 -
florian 5 years ago
parent
commit
2b70c64d09
1 changed files with 27 additions and 26 deletions
  1. 27 26
      compiler/x86/aoptx86.pas

+ 27 - 26
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;