Browse Source

* patch by J. Gareth Moreton: refactor RemoveCurrentP

git-svn-id: trunk@45142 -
florian 5 years ago
parent
commit
a084c8829f
4 changed files with 57 additions and 40 deletions
  1. 12 0
      compiler/aoptobj.pas
  2. 1 4
      compiler/arm/aoptcpu.pas
  3. 25 7
      compiler/avr/aoptcpu.pas
  4. 19 29
      compiler/x86/aoptx86.pas

+ 12 - 0
compiler/aoptobj.pas

@@ -341,6 +341,9 @@ Unit AoptObj;
         { removes p from asml, updates registers and replaces it by a valid value, if this is the case true is returned }
         { removes p from asml, updates registers and replaces it by a valid value, if this is the case true is returned }
         function RemoveCurrentP(var p : tai): boolean;
         function RemoveCurrentP(var p : tai): boolean;
 
 
+        { removes p from asml, updates registers and replaces p with hp1 (if the next instruction was known beforehand) }
+        procedure RemoveCurrentP(var p: tai; const hp1: tai); inline;
+
        { traces sucessive jumps to their final destination and sets it, e.g.
        { traces sucessive jumps to their final destination and sets it, e.g.
          je l1                je l3
          je l1                je l3
          <code>               <code>
          <code>               <code>
@@ -1498,6 +1501,15 @@ Unit AoptObj;
       end;
       end;
 
 
 
 
+    procedure TAOptObj.RemoveCurrentP(var p: tai; const hp1: tai); inline;
+      begin
+        UpdateUsedRegs(tai(p.Next));
+        AsmL.Remove(p);
+        p.Free;
+        p := hp1;
+      end;
+
+
     function FindLiveLabel(hp: tai; var l: tasmlabel): Boolean;
     function FindLiveLabel(hp: tai; var l: tasmlabel): Boolean;
       var
       var
         next: tai;
         next: tai;

+ 1 - 4
compiler/arm/aoptcpu.pas

@@ -1518,9 +1518,7 @@ Implementation
                             DebugMsg('Peephole AndStrb2Strb done', p);
                             DebugMsg('Peephole AndStrb2Strb done', p);
                             taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg);
                             taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg);
                             AllocRegBetween(taicpu(p).oper[1]^.reg,p,hp1,UsedRegs);
                             AllocRegBetween(taicpu(p).oper[1]^.reg,p,hp1,UsedRegs);
-                            GetNextInstruction(p, hp1);
                             RemoveCurrentP(p);
                             RemoveCurrentP(p);
-                            p:=hp1;
                             result:=true;
                             result:=true;
                           end
                           end
                         {
                         {
@@ -1792,8 +1790,7 @@ Implementation
                             AllocRegBetween(taicpu(hp1).oper[3]^.reg,p,hp1,UsedRegs);
                             AllocRegBetween(taicpu(hp1).oper[3]^.reg,p,hp1,UsedRegs);
 
 
                             taicpu(hp1).ops:=4;
                             taicpu(hp1).ops:=4;
-                            RemoveCurrentP(p);
-                            p:=hp1;
+                            RemoveCurrentP(p, hp1); // <-- Is this actually safe? hp1 is not necessarily the next instruction. [Kit]
                           end;
                           end;
 
 
                         result:=true;
                         result:=true;

+ 25 - 7
compiler/avr/aoptcpu.pas

@@ -679,7 +679,8 @@ Implementation
                     begin
                     begin
                       DebugMsg('Peephole AddAdc2Add performed', p);
                       DebugMsg('Peephole AddAdc2Add performed', p);
 
 
-                      result:=RemoveCurrentP(p);
+                      RemoveCurrentP(p, hp1);
+                      Result := True;
                     end;
                     end;
                   end;
                   end;
                 A_SUB:
                 A_SUB:
@@ -692,7 +693,8 @@ Implementation
 
 
                       taicpu(hp1).opcode:=A_SUB;
                       taicpu(hp1).opcode:=A_SUB;
 
 
-                      result:=RemoveCurrentP(p);
+                      RemoveCurrentP(p, hp1);
+                      Result := True;
                     end;
                     end;
                   end;
                   end;
                 A_CLR:
                 A_CLR:
@@ -795,9 +797,23 @@ Implementation
 
 
                            taicpu(hp3).loadreg(1, taicpu(p).oper[0]^.reg);
                            taicpu(hp3).loadreg(1, taicpu(p).oper[0]^.reg);
 
 
-                           RemoveCurrentP(p);
-                           RemoveCurrentP(p);
-                           result:=RemoveCurrentP(p);
+                           { We're removing 3 concurrent instructions.  Remove hp1
+                             and hp2 manually instead of calling RemoveCurrentP
+                             as this means we won't be calling UpdateUsedRegs 3 times }
+                           asml.Remove(hp1);
+                           hp1.Free;
+
+                           asml.Remove(hp2);
+                           hp2.Free;
+
+                           { By removing p last, we've guaranteed that p.Next is
+                             valid (storing it prior to removing the instructions
+                             may result in a dangling pointer if hp1 immediately
+                             follows p), and because hp1, hp2 and hp3 came from
+                             sequential calls to GetNextInstruction, it is
+                             guaranteed that UpdateUsedRegs will stop at hp3. [Kit] }
+                           RemoveCurrentP(p, hp3);
+                           Result := True;
                          end
                          end
                        else
                        else
                          begin
                          begin
@@ -883,7 +899,8 @@ Implementation
                           not(MatchInstruction(hp1,[A_CALL,A_RCALL])) then
                           not(MatchInstruction(hp1,[A_CALL,A_RCALL])) then
                           begin
                           begin
                             DebugMsg('Peephole Mov2Nop performed', p);
                             DebugMsg('Peephole Mov2Nop performed', p);
-                            result:=RemoveCurrentP(p);
+                            RemoveCurrentP(p, hp1);
+                            Result := True;
                             exit;
                             exit;
                           end;
                           end;
                       end;
                       end;
@@ -1092,7 +1109,8 @@ Implementation
                         begin
                         begin
                           DebugMsg('Peephole MovMov2Mov performed', p);
                           DebugMsg('Peephole MovMov2Mov performed', p);
 
 
-                          result:=RemoveCurrentP(p);
+                          RemoveCurrentP(p,hp1);
+                          Result := True;
 
 
                           GetNextInstruction(hp1,hp1);
                           GetNextInstruction(hp1,hp1);
                           if not assigned(hp1) then
                           if not assigned(hp1) then

+ 19 - 29
compiler/x86/aoptx86.pas

@@ -1085,10 +1085,8 @@ unit aoptx86;
             if (taicpu(p).ops = 2) then
             if (taicpu(p).ops = 2) then
              { remove "imul $1, reg" }
              { remove "imul $1, reg" }
               begin
               begin
-                hp1 := tai(p.Next);
                 DebugMsg(SPeepholeOptimization + 'Imul2Nop done',p);
                 DebugMsg(SPeepholeOptimization + 'Imul2Nop done',p);
-                RemoveCurrentP(p);
-                result:=true;
+                Result := RemoveCurrentP(p);
               end
               end
             else
             else
              { change "imul $1, reg1, reg2" to "mov reg1, reg2" }
              { change "imul $1, reg1, reg2" to "mov reg1, reg2" }
@@ -1138,7 +1136,7 @@ unit aoptx86;
                   AsmL.InsertAfter(hp1,p);
                   AsmL.InsertAfter(hp1,p);
                   DebugMsg(SPeepholeOptimization + 'Imul2LeaShl done',p);
                   DebugMsg(SPeepholeOptimization + 'Imul2LeaShl done',p);
                   taicpu(hp1).fileinfo:=taicpu(p).fileinfo;
                   taicpu(hp1).fileinfo:=taicpu(p).fileinfo;
-                  RemoveCurrentP(p);
+                  RemoveCurrentP(p, hp1);
                   if ShiftValue>0 then
                   if ShiftValue>0 then
                     AsmL.InsertAfter(taicpu.op_const_reg(A_SHL, opsize, ShiftValue, taicpu(hp1).oper[1]^.reg),hp1);
                     AsmL.InsertAfter(taicpu.op_const_reg(A_SHL, opsize, ShiftValue, taicpu(hp1).oper[1]^.reg),hp1);
               end;
               end;
@@ -1395,9 +1393,7 @@ unit aoptx86;
               <nop> }
               <nop> }
             if MatchOperand(taicpu(p).oper[0]^,taicpu(p).oper[1]^) then
             if MatchOperand(taicpu(p).oper[0]^,taicpu(p).oper[1]^) then
               begin
               begin
-                GetNextInstruction(p,hp1);
                 RemoveCurrentP(p);
                 RemoveCurrentP(p);
-                p:=hp1;
                 result:=true;
                 result:=true;
                 exit;
                 exit;
               end
               end
@@ -1539,10 +1535,9 @@ unit aoptx86;
                     if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then
                     if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then
                       begin
                       begin
                         taicpu(hp1).loadoper(2,taicpu(p).oper[0]^);
                         taicpu(hp1).loadoper(2,taicpu(p).oper[0]^);
-                        RemoveCurrentP(p);
+                        RemoveCurrentP(p, hp1); // <-- Is this actually safe? hp1 is not necessarily the next instruction. [Kit]
                         asml.Remove(hp2);
                         asml.Remove(hp2);
                         hp2.Free;
                         hp2.Free;
-                        p:=hp1;
                       end;
                       end;
                   end
                   end
                 else if (hp1.typ = ait_instruction) and
                 else if (hp1.typ = ait_instruction) and
@@ -1578,11 +1573,11 @@ unit aoptx86;
                         { we cannot eliminate the first move if
                         { we cannot eliminate the first move if
                           the operations uses the same register for source and dest }
                           the operations uses the same register for source and dest }
                         if not(OpsEqual(taicpu(hp1).oper[1]^,taicpu(hp1).oper[0]^)) then
                         if not(OpsEqual(taicpu(hp1).oper[1]^,taicpu(hp1).oper[0]^)) then
-                          RemoveCurrentP(p);
+                          RemoveCurrentP(p, nil);
+                        p:=hp1;
                         taicpu(hp1).loadoper(1, taicpu(hp2).oper[1]^);
                         taicpu(hp1).loadoper(1, taicpu(hp2).oper[1]^);
                         asml.remove(hp2);
                         asml.remove(hp2);
                         hp2.Free;
                         hp2.Free;
-                        p:=hp1;
                         result:=true;
                         result:=true;
                       end;
                       end;
                   end;
                   end;
@@ -1843,8 +1838,7 @@ unit aoptx86;
           begin
           begin
             DebugMsg(SPeepholeOptimization + 'Mov2Nop 1 done',p);
             DebugMsg(SPeepholeOptimization + 'Mov2Nop 1 done',p);
             { take care of the register (de)allocs following p }
             { take care of the register (de)allocs following p }
-            RemoveCurrentP(p);
-            p:=hp1;
+            RemoveCurrentP(p, hp1);
             Result:=true;
             Result:=true;
             exit;
             exit;
           end;
           end;
@@ -2072,7 +2066,7 @@ unit aoptx86;
                           begin
                           begin
                             DebugMsg(SPeepholeOptimization + 'MovMovXX2MovXX 1 done',p);
                             DebugMsg(SPeepholeOptimization + 'MovMovXX2MovXX 1 done',p);
                             taicpu(hp1).loadref(0,taicpu(p).oper[0]^.ref^);
                             taicpu(hp1).loadref(0,taicpu(p).oper[0]^.ref^);
-                            RemoveCurrentP(p);
+                            RemoveCurrentP(p, hp1);
                             Result:=True;
                             Result:=True;
                             Exit;
                             Exit;
                           end;
                           end;
@@ -2088,8 +2082,7 @@ unit aoptx86;
               else
               else
                 begin
                 begin
                   DebugMsg(SPeepholeOptimization + 'Mov2Nop 5 done',p);
                   DebugMsg(SPeepholeOptimization + 'Mov2Nop 5 done',p);
-                  RemoveCurrentP(p);
-                  p:=hp1;
+                  RemoveCurrentP(p, hp1);
                   Result := True;
                   Result := True;
                   Exit;
                   Exit;
                 end;
                 end;
@@ -2567,8 +2560,7 @@ unit aoptx86;
 
 
                           { We can remove the original MOV too }
                           { We can remove the original MOV too }
                           DebugMsg(SPeepholeOptimization + 'MovMov2NopNop 6b done',p);
                           DebugMsg(SPeepholeOptimization + 'MovMov2NopNop 6b done',p);
-                          RemoveCurrentP(p);
-                          p:=hp1;
+                          RemoveCurrentP(p, hp1);
                           Result:=true;
                           Result:=true;
                           Exit;
                           Exit;
                         end;
                         end;
@@ -2589,8 +2581,7 @@ unit aoptx86;
                       else
                       else
                         begin
                         begin
                           DebugMsg(SPeepholeOptimization + 'MovMov2Mov 6 done',p);
                           DebugMsg(SPeepholeOptimization + 'MovMov2Mov 6 done',p);
-                          RemoveCurrentP(p);
-                          p:=hp1;
+                          RemoveCurrentP(p, hp1);
                           Result:=true;
                           Result:=true;
                           Exit;
                           Exit;
                         end;
                         end;
@@ -2625,8 +2616,7 @@ unit aoptx86;
                         else
                         else
                           begin
                           begin
                             DebugMsg(SPeepholeOptimization + 'MovMov2Mov 7 done',p);
                             DebugMsg(SPeepholeOptimization + 'MovMov2Mov 7 done',p);
-                            RemoveCurrentP(p);
-                            p:=hp1;
+                            RemoveCurrentP(p, hp1);
                             Result:=true;
                             Result:=true;
                             Exit;
                             Exit;
                           end;
                           end;
@@ -2786,7 +2776,7 @@ unit aoptx86;
                     }
                     }
                     asml.remove(hp2);
                     asml.remove(hp2);
                     hp2.Free;
                     hp2.Free;
-                    RemoveCurrentP(p);
+                    RemoveCurrentP(p, hp1);
                     Result:=True;
                     Result:=True;
                     Exit;
                     Exit;
                   end;
                   end;
@@ -3222,7 +3212,7 @@ unit aoptx86;
                             if not(taicpu(p).oper[0]^.ref^.scalefactor in [0,1]) then
                             if not(taicpu(p).oper[0]^.ref^.scalefactor in [0,1]) then
                               taicpu(hp1).oper[ref]^.ref^.scalefactor:=taicpu(p).oper[0]^.ref^.scalefactor;
                               taicpu(hp1).oper[ref]^.ref^.scalefactor:=taicpu(p).oper[0]^.ref^.scalefactor;
                             inc(taicpu(hp1).oper[ref]^.ref^.offset,taicpu(p).oper[0]^.ref^.offset);
                             inc(taicpu(hp1).oper[ref]^.ref^.offset,taicpu(p).oper[0]^.ref^.offset);
-                            RemoveCurrentP(p);
+                            RemoveCurrentP(p, hp1);
                             result:=true;
                             result:=true;
                             exit;
                             exit;
                           end
                           end
@@ -4808,8 +4798,7 @@ unit aoptx86;
                           Taicpu(hp1).loadoper(1,Taicpu(hp1).oper[0]^);
                           Taicpu(hp1).loadoper(1,Taicpu(hp1).oper[0]^);
                         Taicpu(hp1).loadconst(0,0);
                         Taicpu(hp1).loadconst(0,0);
                         Taicpu(hp1).opcode:=carryadd_opcode;
                         Taicpu(hp1).opcode:=carryadd_opcode;
-                        RemoveCurrentP(p);
-                        p:=hp1;
+                        RemoveCurrentP(p, hp1);
                         result:=true;
                         result:=true;
                         exit;
                         exit;
                       end;
                       end;
@@ -5530,8 +5519,7 @@ unit aoptx86;
                   ((MaskLength+taicpu(hp1).oper[0]^.val)>=topsize2memsize[taicpu(hp1).opsize]) then
                   ((MaskLength+taicpu(hp1).oper[0]^.val)>=topsize2memsize[taicpu(hp1).opsize]) then
                   begin
                   begin
                     DebugMsg(SPeepholeOptimization + 'AndShlToShl done',p);
                     DebugMsg(SPeepholeOptimization + 'AndShlToShl done',p);
-                    RemoveCurrentP(p);
-                    p:=hp1;
+                    RemoveCurrentP(p, hp1);
                     Result:=true;
                     Result:=true;
                     exit;
                     exit;
                   end;
                   end;
@@ -5704,7 +5692,7 @@ unit aoptx86;
         end;
         end;
 
 
       var
       var
-        hp1, hp2, hp3: tai;
+        hp1, hp2, hp3, hp4: tai;
       begin
       begin
         Result:=false;
         Result:=false;
         { replace
         { replace
@@ -5730,6 +5718,8 @@ unit aoptx86;
           (taicpu(p).oper[0]^.ref^.segment=NR_NO) and
           (taicpu(p).oper[0]^.ref^.segment=NR_NO) and
           (taicpu(p).oper[1]^.reg=NR_STACK_POINTER_REG) and
           (taicpu(p).oper[1]^.reg=NR_STACK_POINTER_REG) and
           GetNextInstruction(p, hp1) and
           GetNextInstruction(p, hp1) and
+          { Take a copy of hp1 }
+          SetAndTest(hp1, hp4) and
           { trick to skip label }
           { trick to skip label }
           ((hp1.typ=ait_instruction) or GetNextInstruction(hp1, hp1)) and
           ((hp1.typ=ait_instruction) or GetNextInstruction(hp1, hp1)) and
           SkipSimpleInstructions(hp1) and
           SkipSimpleInstructions(hp1) and
@@ -5753,7 +5743,7 @@ unit aoptx86;
             taicpu(hp1).opcode := A_JMP;
             taicpu(hp1).opcode := A_JMP;
             taicpu(hp1).is_jmp := true;
             taicpu(hp1).is_jmp := true;
             DebugMsg(SPeepholeOptimization + 'LeaCallLeaRet2Jmp done',p);
             DebugMsg(SPeepholeOptimization + 'LeaCallLeaRet2Jmp done',p);
-            RemoveCurrentP(p);
+            RemoveCurrentP(p, hp4);
             AsmL.Remove(hp2);
             AsmL.Remove(hp2);
             hp2.free;
             hp2.free;
             AsmL.Remove(hp3);
             AsmL.Remove(hp3);