Browse Source

* fixes some issues with reg. allocation information

git-svn-id: trunk@21303 -
florian 13 years ago
parent
commit
748694a325
4 changed files with 117 additions and 27 deletions
  1. 26 10
      compiler/aopt.pas
  2. 5 5
      compiler/aoptbase.pas
  3. 41 10
      compiler/aoptobj.pas
  4. 45 2
      compiler/arm/aoptcpu.pas

+ 26 - 10
compiler/aopt.pas

@@ -61,6 +61,7 @@ Unit aopt;
     uses
     uses
       globtype, globals,
       globtype, globals,
       verbose,
       verbose,
+      cgbase,
       aoptda,aoptcpu,aoptcpud;
       aoptda,aoptcpu,aoptcpud;
 
 
     Constructor TAsmOptimizer.create(_AsmL: TAsmList);
     Constructor TAsmOptimizer.create(_AsmL: TAsmList);
@@ -110,11 +111,11 @@ Unit aopt;
     Procedure TAsmOptimizer.BuildLabelTableAndFixRegAlloc;
     Procedure TAsmOptimizer.BuildLabelTableAndFixRegAlloc;
     { Builds a table with the locations of the labels in the TAsmList.       }
     { Builds a table with the locations of the labels in the TAsmList.       }
     { Also fixes some RegDeallocs like "# %eax released; push (%eax)"           }
     { Also fixes some RegDeallocs like "# %eax released; push (%eax)"           }
-    Var p{, hp1, hp2}: tai;
-        {UsedRegs: TRegSet;}
+    Var p,hp1, hp2: tai;
+        Regs: TAllUsedRegs;
         LabelIdx : longint;
         LabelIdx : longint;
     Begin
     Begin
-      {UsedRegs := [];}
+      CreateUsedRegs(Regs);
       With LabelInfo^ Do
       With LabelInfo^ Do
         If (LabelDif <> 0) Then
         If (LabelDif <> 0) Then
           Begin
           Begin
@@ -137,13 +138,17 @@ Unit aopt;
                     end;
                     end;
                   ait_regAlloc:
                   ait_regAlloc:
                     begin
                     begin
-                    {!!!!!!!!!
                       if tai_regalloc(p).ratype=ra_alloc then
                       if tai_regalloc(p).ratype=ra_alloc then
                         Begin
                         Begin
-                          If Not(tai_regalloc(p).Reg in UsedRegs) Then
-                            UsedRegs := UsedRegs + [tai_regalloc(p).Reg]
+                          If Not(RegInUsedRegs(tai_regalloc(p).Reg,Regs)) Then
+                            IncludeRegInUsedRegs(tai_regalloc(p).Reg,Regs)
                           Else
                           Else
                             Begin
                             Begin
+                              hp1 := tai(p.previous);
+                              AsmL.remove(p);
+                              p.free;
+                              p := hp1;                            
+                              { not sure if this is useful, it even skips previous deallocs of the register (FK)
                               hp1 := p;
                               hp1 := p;
                               hp2 := nil;
                               hp2 := nil;
                               While GetLastInstruction(hp1, hp1) And
                               While GetLastInstruction(hp1, hp1) And
@@ -154,11 +159,12 @@ Unit aopt;
                                   hp1:=tai_regalloc.DeAlloc(tai_regalloc(p).Reg,hp2);
                                   hp1:=tai_regalloc.DeAlloc(tai_regalloc(p).Reg,hp2);
                                   InsertLLItem(tai(hp2.previous), hp2, hp1);
                                   InsertLLItem(tai(hp2.previous), hp2, hp1);
                                 End;
                                 End;
-                            End;
+                              }
+                            End;                            
                         End
                         End
                       else
                       else
                         Begin
                         Begin
-                          UsedRegs := UsedRegs - [tai_regalloc(p).Reg];
+                          ExcludeRegFromUsedRegs(tai_regalloc(p).Reg,Regs);
                           hp1 := p;
                           hp1 := p;
                           hp2 := nil;
                           hp2 := nil;
                           While Not(FindRegAlloc(tai_regalloc(p).Reg, tai(hp1.Next))) And
                           While Not(FindRegAlloc(tai_regalloc(p).Reg, tai(hp1.Next))) And
@@ -172,8 +178,17 @@ Unit aopt;
                               InsertLLItem(hp2, tai(hp2.Next), p);
                               InsertLLItem(hp2, tai(hp2.Next), p);
                               p := hp1;
                               p := hp1;
                             End
                             End
+                          else if findregalloc(tai_regalloc(p).reg, tai(p.next))
+                            and getnextinstruction(p,hp1) then
+                            begin
+                              hp1 := tai(p.previous);
+                              AsmL.remove(p);
+                              p.free;
+                              p := hp1;
+        //                      don't include here, since then the allocation will be removed when it's processed
+        //                      include(usedregs,supreg);
+                            end;
                         End
                         End
-                    };
                     End
                     End
                 End;
                 End;
                 P := tai(p.Next);
                 P := tai(p.Next);
@@ -182,7 +197,8 @@ Unit aopt;
                       (p.typ in (SkipInstr - [ait_regalloc])) Do
                       (p.typ in (SkipInstr - [ait_regalloc])) Do
                   P := tai(P.Next)
                   P := tai(P.Next)
               End;
               End;
-          End
+          End;
+      ReleaseUsedRegs(Regs);
     End;
     End;
 
 
     procedure tasmoptimizer.clear;
     procedure tasmoptimizer.clear;

+ 5 - 5
compiler/aoptbase.pas

@@ -47,7 +47,7 @@ unit aoptbase;
         constructor create; virtual;
         constructor create; virtual;
         destructor destroy;override;
         destructor destroy;override;
         { returns true if register Reg is used by instruction p1 }
         { returns true if register Reg is used by instruction p1 }
-        Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;
+        Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;virtual;
         { returns true if register Reg occurs in operand op }
         { returns true if register Reg occurs in operand op }
         Function RegInOp(Reg: TRegister; const op: toper): Boolean;
         Function RegInOp(Reg: TRegister; const op: toper): Boolean;
         { returns true if register Reg is used in the reference Ref }
         { returns true if register Reg is used in the reference Ref }
@@ -201,12 +201,12 @@ unit aoptbase;
       Current := Tai(Current.previous);
       Current := Tai(Current.previous);
       While Assigned(Current) And
       While Assigned(Current) And
             (((Current.typ = ait_Marker) And
             (((Current.typ = ait_Marker) And
-              Not(Tai_Marker(Current).Kind in [mark_AsmBlockEnd,mark_NoPropInfoEnd])) or
+              Not(Tai_Marker(Current).Kind in [mark_AsmBlockEnd{,mark_NoPropInfoEnd}])) or
              (Current.typ In SkipInstr) or
              (Current.typ In SkipInstr) or
              ((Current.typ = ait_label) And
              ((Current.typ = ait_label) And
               labelCanBeSkipped(Tai_Label(Current)))) Do
               labelCanBeSkipped(Tai_Label(Current)))) Do
         Current := Tai(Current.previous);
         Current := Tai(Current.previous);
-      If Assigned(Current) And
+{      If Assigned(Current) And
          (Current.typ = ait_Marker) And
          (Current.typ = ait_Marker) And
          (Tai_Marker(Current).Kind = mark_NoPropInfoEnd) Then
          (Tai_Marker(Current).Kind = mark_NoPropInfoEnd) Then
         Begin
         Begin
@@ -214,10 +214,10 @@ unit aoptbase;
                 ((Current.typ <> ait_Marker) Or
                 ((Current.typ <> ait_Marker) Or
                  (Tai_Marker(Current).Kind <> mark_NoPropInfoStart)) Do
                  (Tai_Marker(Current).Kind <> mark_NoPropInfoStart)) Do
             Current := Tai(Current.previous);
             Current := Tai(Current.previous);
-        End;
+        End; }
     Until Not(Assigned(Current)) Or
     Until Not(Assigned(Current)) Or
           (Current.typ <> ait_Marker) Or
           (Current.typ <> ait_Marker) Or
-          (Tai_Marker(Current).Kind <> mark_NoPropInfoStart);
+          not(tai_Marker(current).Kind in [mark_NoPropInfoStart,mark_NoPropInfoEnd]);
     If Not(Assigned(Current)) or
     If Not(Assigned(Current)) or
        (Current.typ In SkipInstr) or
        (Current.typ In SkipInstr) or
        ((Current.typ = ait_label) And
        ((Current.typ = ait_label) And

+ 41 - 10
compiler/aoptobj.pas

@@ -164,17 +164,17 @@ Unit AoptObj;
           TInstrSinceLastMod);
           TInstrSinceLastMod);
         { destroy the contents of all registers }
         { destroy the contents of all registers }
         Procedure DestroyAllRegs(var InstrSinceLastMod: TInstrSinceLastMod);
         Procedure DestroyAllRegs(var InstrSinceLastMod: TInstrSinceLastMod);
-        { a register's contents are modified, but not destroyed (the new value }
-        { depends on the old one)                                              }
+        { a register's contents are modified, but not destroyed (the new value
+          depends on the old one)                                              }
         Procedure ModifyReg(reg: TRegister; var InstrSinceLastMod:
         Procedure ModifyReg(reg: TRegister; var InstrSinceLastMod:
           TInstrSinceLastMod);
           TInstrSinceLastMod);
-        { an operand's contents are modified, but not destroyed (the new value }
-        { depends on the old one)                                              }
+        { an operand's contents are modified, but not destroyed (the new value
+          depends on the old one)                                              }
         Procedure ModifyOp(const oper: TOper; var InstrSinceLastMod:
         Procedure ModifyOp(const oper: TOper; var InstrSinceLastMod:
           TInstrSinceLastMod);
           TInstrSinceLastMod);
 
 
-        { increase the write state of a register (call every time a register is }
-        { written to)                                                           }
+        { increase the write state of a register (call every time a register is
+          written to)                                                           }
         Procedure IncWState(Reg: TRegister);
         Procedure IncWState(Reg: TRegister);
         { increase the read state of a register (call every time a register is }
         { increase the read state of a register (call every time a register is }
         { read from)                                                           }
         { read from)                                                           }
@@ -262,11 +262,15 @@ Unit AoptObj;
 
 
         { processor independent methods }
         { processor independent methods }
 
 
+        Procedure CreateUsedRegs(var regs: TAllUsedRegs);
         Procedure ClearUsedRegs;
         Procedure ClearUsedRegs;
         Procedure UpdateUsedRegs(p : Tai);
         Procedure UpdateUsedRegs(p : Tai);
         procedure UpdateUsedRegs(var Regs: TAllUsedRegs; p: Tai);
         procedure UpdateUsedRegs(var Regs: TAllUsedRegs; p: Tai);
         Function CopyUsedRegs(var dest : TAllUsedRegs) : boolean;
         Function CopyUsedRegs(var dest : TAllUsedRegs) : boolean;
         Procedure ReleaseUsedRegs(const regs : TAllUsedRegs);
         Procedure ReleaseUsedRegs(const regs : TAllUsedRegs);
+        Function RegInUsedRegs(reg : TRegister;regs : TAllUsedRegs) : boolean;
+        Procedure IncludeRegInUsedRegs(reg : TRegister;var regs : TAllUsedRegs);
+        Procedure ExcludeRegFromUsedRegs(reg: TRegister;var regs : TAllUsedRegs);
 
 
         { returns true if the label L is found between hp and the next }
         { returns true if the label L is found between hp and the next }
         { instruction                                                  }
         { instruction                                                  }
@@ -778,15 +782,12 @@ Unit AoptObj;
 
 
       Constructor TAoptObj.create(_AsmL: TAsmList; _BlockStart, _BlockEnd: Tai;
       Constructor TAoptObj.create(_AsmL: TAsmList; _BlockStart, _BlockEnd: Tai;
                                   _LabelInfo: PLabelInfo);
                                   _LabelInfo: PLabelInfo);
-      var
-        i : TRegisterType;
       Begin
       Begin
         AsmL := _AsmL;
         AsmL := _AsmL;
         BlockStart := _BlockStart;
         BlockStart := _BlockStart;
         BlockEnd := _BlockEnd;
         BlockEnd := _BlockEnd;
         LabelInfo := _LabelInfo;
         LabelInfo := _LabelInfo;
-        for i:=low(TRegisterType) to high(TRegisterType) do
-          UsedRegs[i]:=TUsedRegs.Create(i);
+        CreateUsedRegs(UsedRegs);
       End;
       End;
 
 
       destructor TAOptObj.Destroy;
       destructor TAOptObj.Destroy;
@@ -799,6 +800,15 @@ Unit AoptObj;
         end;
         end;
 
 
 
 
+      procedure TAOptObj.CreateUsedRegs(var regs: TAllUsedRegs);
+        var
+          i : TRegisterType;
+        begin
+          for i:=low(TRegisterType) to high(TRegisterType) do
+            Regs[i]:=TUsedRegs.Create(i);
+        end;
+
+
       procedure TAOptObj.ClearUsedRegs;
       procedure TAOptObj.ClearUsedRegs;
         var
         var
           i : TRegisterType;
           i : TRegisterType;
@@ -835,6 +845,7 @@ Unit AoptObj;
           dest[i]:=TUsedRegs.Create_Regset(i,UsedRegs[i].GetUsedRegs);
           dest[i]:=TUsedRegs.Create_Regset(i,UsedRegs[i].GetUsedRegs);
       end;
       end;
 
 
+
       procedure TAOptObj.ReleaseUsedRegs(const regs: TAllUsedRegs);
       procedure TAOptObj.ReleaseUsedRegs(const regs: TAllUsedRegs);
         var
         var
           i : TRegisterType;
           i : TRegisterType;
@@ -844,6 +855,26 @@ Unit AoptObj;
       end;
       end;
 
 
 
 
+      Function TAOptObj.RegInUsedRegs(reg : TRegister;regs : TAllUsedRegs) : boolean;
+      begin
+        result:=regs[getregtype(reg)].IsUsed(reg);
+      end;
+
+
+      procedure TAOptObj.IncludeRegInUsedRegs(reg: TRegister;
+       var regs: TAllUsedRegs);
+      begin
+        include(regs[getregtype(reg)].UsedRegs,getsupreg(Reg));
+      end;
+
+
+      procedure TAOptObj.ExcludeRegFromUsedRegs(reg: TRegister;
+       var regs: TAllUsedRegs);
+      begin
+        exclude(regs[getregtype(reg)].UsedRegs,getsupreg(Reg));
+      end;
+
+
       Function TAOptObj.FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
       Function TAOptObj.FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
       Var TempP: Tai;
       Var TempP: Tai;
       Begin
       Begin

+ 45 - 2
compiler/arm/aoptcpu.pas

@@ -28,13 +28,17 @@ Unit aoptcpu;
 
 
 Interface
 Interface
 
 
-uses cpubase, aasmtai, aopt, aoptcpub;
+uses cgbase, cpubase, aasmtai, aopt, aoptcpub, aoptobj;
 
 
 Type
 Type
+
+  { TCpuAsmOptimizer }
+
   TCpuAsmOptimizer = class(TAsmOptimizer)
   TCpuAsmOptimizer = class(TAsmOptimizer)
     { uses the same constructor as TAopObj }
     { uses the same constructor as TAopObj }
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
     function PeepHoleOptPass1Cpu(var p: tai): boolean; override;
     procedure PeepHoleOptPass2;override;
     procedure PeepHoleOptPass2;override;
+    Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;override;
   End;
   End;
 
 
   TCpuPreRegallocScheduler = class(TAsmOptimizer)
   TCpuPreRegallocScheduler = class(TAsmOptimizer)
@@ -51,7 +55,7 @@ Implementation
   uses
   uses
     cutils,
     cutils,
     verbose,
     verbose,
-    cgbase,cgutils,
+    cgutils,
     aasmbase,aasmdata,aasmcpu;
     aasmbase,aasmdata,aasmcpu;
 
 
   function CanBeCond(p : tai) : boolean;
   function CanBeCond(p : tai) : boolean;
@@ -118,6 +122,7 @@ Implementation
     var
     var
       hp1,hp2: tai;
       hp1,hp2: tai;
       i: longint;
       i: longint;
+      TmpUsedRegs: TAllUsedRegs;
     begin
     begin
       result := false;
       result := false;
       case p.typ of
       case p.typ of
@@ -216,6 +221,36 @@ Implementation
                             taicpu(hp1).loadreg(1,taicpu(p).oper[0]^.reg);
                             taicpu(hp1).loadreg(1,taicpu(p).oper[0]^.reg);
                           end;
                           end;
                         result := true;
                         result := true;
+                      end
+                    else
+                    { Remove superfluous mov after ldr
+                      changes
+                      ldr reg1, ref
+                      mov reg2, reg1
+                      to
+                      ldr reg2, ref
+
+                      conditions are:
+                        * reg1 must be released after mov
+                        * mov can not contain shifterops
+                        * ldr+mov have the same conditions
+                        * mov does not set flags
+                    }
+                    if GetNextInstruction(p, hp1) and
+                       MatchInstruction(hp1, A_MOV, [taicpu(p).condition], [PF_None]) and
+                       (taicpu(hp1).ops=2) and {We can't optimize if there is a shiftop}
+                       MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) then
+                      begin
+                        CopyUsedRegs(TmpUsedRegs);
+                        UpdateUsedRegs(TmpUsedRegs, tai(p.next));
+                        If not(RegUsedAfterInstruction(taicpu(p).oper[0]^.reg,hp1,TmpUsedRegs)) then
+                        begin
+                          asml.insertbefore(tai_comment.Create(strpnew('Peephole LdrMov2Ldr removed superfluous mov')), hp1);
+                          taicpu(p).loadreg(0,taicpu(hp1).oper[0]^.reg);
+                          asml.remove(hp1);
+                          hp1.free;
+                        end;
+                        ReleaseUsedRegs(TmpUsedRegs);
                       end;
                       end;
                   end;
                   end;
                 A_MOV:
                 A_MOV:
@@ -562,6 +597,14 @@ Implementation
         end;
         end;
     end;
     end;
 
 
+  function TCpuAsmOptimizer.RegInInstruction(Reg: TRegister; p1: tai): Boolean;
+    begin
+      If (p1.typ = ait_instruction) and (taicpu(p1).opcode=A_BL) then
+        Result:=true
+      else
+        Result:=inherited RegInInstruction(Reg, p1);
+    end;
+
   const
   const
     { set of opcode which might or do write to memory }
     { set of opcode which might or do write to memory }
     { TODO : extend armins.dat to contain r/w info }
     { TODO : extend armins.dat to contain r/w info }