Jelajahi Sumber

* basics for generic register usage information

git-svn-id: trunk@20886 -
florian 13 tahun lalu
induk
melakukan
2a6a4831ea
2 mengubah file dengan 118 tambahan dan 48 penghapusan
  1. 4 1
      compiler/aoptbase.pas
  2. 114 47
      compiler/aoptobj.pas

+ 4 - 1
compiler/aoptbase.pas

@@ -91,11 +91,12 @@ unit aoptbase;
 
     end;
 
+    function labelCanBeSkipped(p: tai_label): boolean;
 
   implementation
 
     uses
-      globtype,globals, aoptcpub;
+      globtype,globals,aoptcpub;
 
   constructor taoptbase.create;
     begin
@@ -148,11 +149,13 @@ unit aoptbase;
     Result:=true;
   End;
 
+
   function labelCanBeSkipped(p: tai_label): boolean;
   begin
     labelCanBeSkipped := not(p.labsym.is_used) or (p.labsym.labeltype<>alt_jump);
   end;
 
+
   Function TAOptBase.GetNextInstruction(Current: tai; Var Next: tai): Boolean;
   Begin
     Repeat

+ 114 - 47
compiler/aoptobj.pas

@@ -59,28 +59,34 @@ Unit AoptObj;
       TRefCompare = Function(const r1, r2: TReference): Boolean;
       //!!! FIXME
       TRegArray = Array[byte] of tsuperregister;
+
+
       TRegSet = Set of byte;
-    { possible actions on an operand: read, write or modify (= read & write) }
+      { possible actions on an operand: read, write or modify (= read & write) }
       TOpAction = (OpAct_Read, OpAct_Write, OpAct_Modify, OpAct_Unknown);
 
     { ************************************************************************* }
     { * Object to hold information on which regiters are in use and which not * }
     { ************************************************************************* }
+
+      { TUsedRegs }
+
       TUsedRegs = class
-        Constructor create;
-        Constructor create_regset(Const _RegSet: TRegSet);
+        Constructor create(aTyp : TRegisterType);
+        Constructor create_regset(aTyp : TRegisterType;Const _RegSet: TRegSet);
 
         Destructor Destroy;override;
-        { update the info with the pairegalloc objects coming after }
-        { p                                                         }
+
+        Procedure Clear;
+        { update the info with the pairegalloc objects coming after
+          p                                                         }
         Procedure Update(p: Tai);
         { is Reg currently in use }
         Function IsUsed(Reg: TRegister): Boolean;
         { get all the currently used registers }
         Function GetUsedRegs: TRegSet;
-
       Private
-
+        Typ : TRegisterType;
         UsedRegs: TRegSet;
       End;
 
@@ -120,10 +126,10 @@ Unit AoptObj;
     { gets one of these assigned: a pointer to it is stored in the OptInfo field }
     { ************************************************************************** }
 
+      { TPaiProp }
+
       TPaiProp = class(TAoptBaseCpu)
         Regs: TRegContent;
-        { info about allocation of general purpose integer registers }
-        UsedRegs: TUsedRegs;
         { can this instruction be removed? }
         CanBeRemoved: Boolean;
 
@@ -227,6 +233,8 @@ Unit AoptObj;
     { ********** General optimizer object, used to derive others from ********* }
     { ************************************************************************* }
 
+      { TAOptObj }
+
       TAOptObj = class(TAoptBaseCpu)
         { the PAasmOutput list this optimizer instance works on }
         AsmL: TAsmList;
@@ -240,15 +248,22 @@ Unit AoptObj;
         BlockStart, BlockEnd: Tai;
 
         DFA: TAOptDFA;
+
+        UsedRegs: array[TRegisterType] of TUsedRegs;
+
         { _AsmL is the PAasmOutpout list that has to be optimized,     }
         { _BlockStart and _BlockEnd the start and the end of the block }
         { that has to be optimized and _LabelInfo a pointer to a       }
         { TLabelInfo record                                            }
         Constructor create(_AsmL: TAsmList; _BlockStart, _BlockEnd: Tai;
                            _LabelInfo: PLabelInfo); virtual; reintroduce;
+        Destructor Destroy;override;
 
         { processor independent methods }
 
+        Procedure ClearUsedRegs;
+        Procedure UpdateUsedRegs(p : Tai);
+
         { returns true if the label L is found between hp and the next }
         { instruction                                                  }
         Function FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
@@ -312,57 +327,76 @@ Unit AoptObj;
       { ******************************** TUsedRegs ****************************** }
       { ************************************************************************* }
 
-      Constructor TUsedRegs.create;
+    Constructor TUsedRegs.create(aTyp : TRegisterType);
       Begin
+        Typ:=aTyp;
         UsedRegs := [];
       End;
 
-      Constructor TUsedRegs.create_regset(Const _RegSet: TRegSet);
+
+    Constructor TUsedRegs.create_regset(aTyp : TRegisterType;Const _RegSet: TRegSet);
       Begin
+        Typ:=aTyp;
         UsedRegs := _RegSet;
       End;
 
-      Procedure TUsedRegs.Update(p: Tai);
-      {updates UsedRegs with the RegAlloc Information coming after P}
+
+    {
+      updates UsedRegs with the RegAlloc Information coming after P
+    }
+    Procedure TUsedRegs.Update(p: Tai);
       Begin
-        Repeat
-          While Assigned(p) And
+        repeat
+          while assigned(p) and
                 ((p.typ in (SkipInstr - [ait_RegAlloc])) or
-                 ((p.typ = ait_label) And
-                  Not(Tai_Label(p).labsym.is_used))) Do
-               p := Tai(p.next);
-          While Assigned(p) And
+                 ((p.typ = ait_label) and
+                  labelCanBeSkipped(tai_label(p))) or
+                 ((p.typ = ait_marker) and
+                  (tai_Marker(p).Kind in [mark_AsmBlockEnd,mark_NoLineInfoStart,mark_NoLineInfoEnd]))) do
+               p := tai(p.next);
+          while assigned(p) and
                 (p.typ=ait_RegAlloc) Do
-            Begin
-          {!!!!!!!! FIXME
-              if tai_regalloc(p).ratype=ra_alloc then
-                UsedRegs := UsedRegs + [tai_regalloc(p).Reg]
-              else
-                UsedRegs := UsedRegs - [tai_regalloc(p).Reg];
-              p := Tai(p.next);
-          }
-            End;
-        Until Not(Assigned(p)) Or
-              (Not(p.typ in SkipInstr) And
-               Not((p.typ = ait_label) And
-                  Not(Tai_Label(p).labsym.is_used)));
+            begin
+              if (getregtype(tai_regalloc(p).reg) = typ) then
+                begin
+                  case tai_regalloc(p).ratype of
+                    ra_alloc :
+                      Include(UsedRegs, getsupreg(tai_regalloc(p).reg));
+                    ra_dealloc :
+                      Exclude(UsedRegs, getsupreg(tai_regalloc(p).reg));
+                  end;
+                end;
+              p := tai(p.next);
+            end;
+        until not(assigned(p)) or
+              (not(p.typ in SkipInstr) and
+               not((p.typ = ait_label) and
+                   labelCanBeSkipped(tai_label(p))));
       End;
 
-      Function TUsedRegs.IsUsed(Reg: TRegister): Boolean;
+
+    Function TUsedRegs.IsUsed(Reg: TRegister): Boolean;
       Begin
-        //!!!!!!!!!!! IsUsed := Reg in UsedRegs
-        Result:=False; { unimplemented }
+        IsUsed := (getregtype(Reg)=Typ) and (getsupreg(Reg) in UsedRegs);
       End;
 
-      Function TUsedRegs.GetUsedRegs: TRegSet;
+
+    Function TUsedRegs.GetUsedRegs: TRegSet;
       Begin
         GetUsedRegs := UsedRegs;
       End;
 
-      Destructor TUsedRegs.Destroy;
-        Begin
-          inherited destroy;
-        end;
+
+    Destructor TUsedRegs.Destroy;
+      Begin
+        inherited destroy;
+      end;
+
+
+    procedure TUsedRegs.Clear;
+      begin
+        UsedRegs := [];
+      end;
 
       { ************************************************************************* }
       { **************************** TPaiProp *********************************** }
@@ -377,6 +411,7 @@ Unit AoptObj;
         {  DirFlag: TFlagContents; I386 specific}
         End;
 
+
       Function TPaiProp.RegInSequence(Reg, which: TRegister): Boolean;
       {
       Var p: Tai;
@@ -736,13 +771,45 @@ Unit AoptObj;
 
       Constructor TAoptObj.create(_AsmL: TAsmList; _BlockStart, _BlockEnd: Tai;
                                   _LabelInfo: PLabelInfo);
+      var
+        i : TRegisterType;
       Begin
         AsmL := _AsmL;
         BlockStart := _BlockStart;
         BlockEnd := _BlockEnd;
-        LabelInfo := _LabelInfo
+        LabelInfo := _LabelInfo;
+        for i:=low(TRegisterType) to high(TRegisterType) do
+          UsedRegs[i]:=TUsedRegs.Create(i);
       End;
 
+      destructor TAOptObj.Destroy;
+        var
+          i : TRegisterType;
+        begin
+          for i:=low(TRegisterType) to high(TRegisterType) do
+            UsedRegs[i].Destroy;
+          inherited Destroy;
+        end;
+
+
+      procedure TAOptObj.ClearUsedRegs;
+        var
+          i : TRegisterType;
+        begin
+          for i:=low(TRegisterType) to high(TRegisterType) do
+            UsedRegs[i].Clear;
+        end;
+
+
+      procedure TAOptObj.UpdateUsedRegs(p : Tai);
+        var
+          i : TRegisterType;
+        begin
+          for i:=low(TRegisterType) to high(TRegisterType) do
+            UsedRegs[i].Update(p);
+        end;
+
+
       Function TAOptObj.FindLabel(L: TasmLabel; Var hp: Tai): Boolean;
       Var TempP: Tai;
       Begin
@@ -1008,10 +1075,10 @@ Unit AoptObj;
         p,hp1,hp2 : tai;
       begin
         p := BlockStart;
-        //!!!! UsedRegs := [];
+        ClearUsedRegs;
         while (p <> BlockEnd) Do
           begin
-            //!!!! UpDateUsedRegs(UsedRegs, tai(p.next));
+            UpdateUsedRegs(tai(p.next));
             if PeepHoleOptPass1Cpu(p) then
               continue;
             case p.Typ Of
@@ -1116,7 +1183,7 @@ Unit AoptObj;
                     end; { if is_jmp }
                 end;
             end;
-            //!!!!!!!! updateUsedRegs(UsedRegs,p);
+            UpdateUsedRegs(p);
             p:=tai(p.next);
           end;
       end;
@@ -1132,13 +1199,13 @@ Unit AoptObj;
         p: tai;
       begin
         p := BlockStart;
-        //!!!! UsedRegs := [];
+        ClearUsedRegs;
         while (p <> BlockEnd) Do
           begin
-            //!!!! UpDateUsedRegs(UsedRegs, tai(p.next));
+            UpdateUsedRegs(tai(p.next));
             if PostPeepHoleOptsCpu(p) then
               continue;
-            //!!!!!!!! updateUsedRegs(UsedRegs,p);
+            UpdateUsedRegs(p);
             p:=tai(p.next);
           end;
       end;