Bladeren bron

* fixed generic optimizer
* enabled generic optimizer for sparc

florian 21 jaren geleden
bovenliggende
commit
e04b172854

+ 197 - 183
compiler/aopt.pas

@@ -1,6 +1,6 @@
 {
 {
     $Id$
     $Id$
-    Copyright (c) 1998-2002 by Jonas Maebe, member of the Free Pascal
+    Copyright (c) 1998-2004 by Jonas Maebe, member of the Free Pascal
     Development Team
     Development Team
 
 
     This unit contains the interface routines between the code generator
     This unit contains the interface routines between the code generator
@@ -24,224 +24,238 @@
 }
 }
 Unit aopt;
 Unit aopt;
 
 
-Interface
+{$i fpcdefs.inc}
 
 
-Uses Aasmbase,aasmtai,aasmcpu, cobjects, aoptobj, aoptcpud, aoptcpub {aoptcs, aoptpeep} ;
+  Interface
 
 
-Type
-  PAsmOptimizer = ^TAsmOptimizer;
-  TAsmOptimizer = Object(TAoptObj)
+    Uses
+      aasmbase,aasmtai,aasmcpu,
+      aoptobj;
 
 
-    { _AsmL is the PAasmOutpout list that has to be optimized }
-    Constructor Init(_AsmL: PAasmOutput);
+    Type
+      TAsmOptimizer = class(TAoptObj)
 
 
-    { call the necessary optimizer procedures }
-    Procedure Optimize;
-    Destructor Done;
+        { _AsmL is the PAasmOutpout list that has to be optimized }
+        Constructor create(_AsmL: taasmoutput);
 
 
-    private
+        { call the necessary optimizer procedures }
+        Procedure Optimize;
+        Destructor destroy;override;
 
 
-    Function FindLoHiLabels: Pai;
-    Procedure BuildLabelTableAndFixRegAlloc;
+      private
+        Function FindLoHiLabels: tai;
+        Procedure BuildLabelTableAndFixRegAlloc;
+      End;
 
 
-  End;
+    var
+      casmoptimizer : class of tasmoptimizer;
 
 
-procedure Optimize(AsmL:Paasmoutput);
+    procedure Optimize(AsmL:taasmoutput);
 
 
+  Implementation
 
 
-Implementation
+    uses
+      cpuinfo, globtype, globals,
+      aoptda,aoptcpu,aoptcpud;
 
 
-uses cpuinfo, globtype, globals;
-
-Constructor TAsmOptimizer.Init(_AsmL: PAasmOutput);
-Begin
-  AsmL := _AsmL;
-{setup labeltable, always necessary}
-  New(LabelInfo);
-  LabelInfo^.LowLabel := High(AWord);
-  LabelInfo^.HighLabel := 0;
-  LabelInfo^.LabelDif := 0;
-End;
+    Constructor TAsmOptimizer.create(_AsmL: taasmoutput);
+      Begin
+        inherited create(_asml,nil,nil,nil);
+      {setup labeltable, always necessary}
+        New(LabelInfo);
+        LabelInfo^.LowLabel := High(AWord);
+        LabelInfo^.HighLabel := 0;
+        LabelInfo^.LabelDif := 0;
+        LabelInfo^.LabelTable:=nil;
+      End;
 
 
-Function TAsmOptimizer.FindLoHiLabels: Pai;
-{ Walks through the paasmlist to find the lowest and highest label number.  }
-{ Returns the last Pai object of the current block                          }
-Var LabelFound: Boolean;
-    P: Pai;
-Begin
-  LabelFound := False;
-  P := BlockStart;
-  With LabelInfo^ Do
-    Begin
-      While Assigned(P) And
-            ((P^.typ <> Ait_Marker) Or
-             (Pai_Marker(P)^.Kind <> AsmBlockStart)) Do
-        Begin
-          If (Pai(p)^.typ = ait_label) Then
-            If (Pai_Label(p)^.l^.is_used) Then
-              Begin
-                LabelFound := True;
-                If (Pai_Label(p)^.l^.labelnr < LowLabel) Then
-                  LowLabel := Pai_Label(p)^.l^.labelnr;
-                If (Pai_Label(p)^.l^.labelnr > HighLabel) Then
-                  HighLabel := Pai_Label(p)^.l^.labelnr
-              End;
-          GetNextInstruction(p, p)
-        End;
-      FindLoHiLabels := p;
-      If LabelFound
-        Then LabelDif := HighLabel-LowLabel+1
-        Else LabelDif := 0
-    End
-End;
-
-Procedure TAsmOptimizer.BuildLabelTableAndFixRegAlloc;
-{ Builds a table with the locations of the labels in the paasmoutput.       }
-{ Also fixes some RegDeallocs like "# %eax released; push (%eax)"           }
-Var p, hp1, hp2: Pai;
-    UsedRegs: TRegSet;
-Begin
-  UsedRegs := [];
-  With LabelInfo^ Do
-    If (LabelDif <> 0) Then
+    Function TAsmOptimizer.FindLoHiLabels: tai;
+      { Walks through the paasmlist to find the lowest and highest label number.  }
+      { Returns the last Pai object of the current block                          }
+      Var LabelFound: Boolean;
+          p: tai;
       Begin
       Begin
-        GetMem(LabelTable, LabelDif*SizeOf(TLabelTableItem));
-        FillChar(LabelTable^, LabelDif*SizeOf(TLabelTableItem), 0);
-        p := BlockStart;
-        While (P <> BlockEnd) Do
+        LabelFound := False;
+        P := BlockStart;
+        With LabelInfo^ Do
           Begin
           Begin
-            Case p^.typ Of
-              ait_Label:
-                If Pai_Label(p)^.l^.is_used Then
-                  LabelTable^[Pai_Label(p)^.l^.labelnr-LowLabel].PaiObj := p;
-              ait_regAlloc:
-                begin
-                  if PairegAlloc(p)^.Allocation then
+            While Assigned(P) And
+                  ((P.typ <> Ait_Marker) Or
+                   (tai_Marker(P).Kind <> AsmBlockStart)) Do
+              Begin
+                If (p.typ = ait_label) Then
+                  If (tai_Label(p).l.is_used) Then
                     Begin
                     Begin
-                      If Not(PaiRegAlloc(p)^.Reg in UsedRegs) Then
-                        UsedRegs := UsedRegs + [PaiRegAlloc(p)^.Reg]
-                      Else
+                      LabelFound := True;
+                      If (tai_Label(p).l.labelnr < LowLabel) Then
+                        LowLabel := tai_Label(p).l.labelnr;
+                      If (tai_Label(p).l.labelnr > HighLabel) Then
+                        HighLabel := tai_Label(p).l.labelnr
+                    End;
+                GetNextInstruction(p, p)
+              End;
+            FindLoHiLabels := p;
+            If LabelFound
+              Then LabelDif := HighLabel-LowLabel+1
+              Else LabelDif := 0
+          End
+      End;
+
+    Procedure TAsmOptimizer.BuildLabelTableAndFixRegAlloc;
+    { Builds a table with the locations of the labels in the taasmoutput.       }
+    { Also fixes some RegDeallocs like "# %eax released; push (%eax)"           }
+    Var p, hp1, hp2: tai;
+        UsedRegs: TRegSet;
+    Begin
+      UsedRegs := [];
+      With LabelInfo^ Do
+        If (LabelDif <> 0) Then
+          Begin
+            GetMem(LabelTable, LabelDif*SizeOf(TLabelTableItem));
+            FillChar(LabelTable^, LabelDif*SizeOf(TLabelTableItem), 0);
+            p := BlockStart;
+            While (P <> BlockEnd) Do
+              Begin
+                Case p.typ Of
+                  ait_Label:
+                    If tai_label(p).l.is_used Then
+                      LabelTable^[tai_label(p).l.labelnr-LowLabel].PaiObj := p;
+                  ait_regAlloc:
+                    begin
+                    {!!!!!!!!!
+                      if tai_regalloc(p).ratype=ra_alloc then
+                        Begin
+                          If Not(tai_regalloc(p).Reg in UsedRegs) Then
+                            UsedRegs := UsedRegs + [tai_regalloc(p).Reg]
+                          Else
+                            Begin
+                              hp1 := p;
+                              hp2 := nil;
+                              While GetLastInstruction(hp1, hp1) And
+                                    Not(RegInInstruction(tai_regalloc(p).Reg, hp1)) Do
+                                hp2:=hp1;
+                              If hp2<>nil Then
+                                Begin
+                                  hp1:=tai_regalloc.DeAlloc(tai_regalloc(p).Reg,hp2);
+                                  InsertLLItem(tai(hp2.previous), hp2, hp1);
+                                End;
+                            End;
+                        End
+                      else
                         Begin
                         Begin
+                          UsedRegs := UsedRegs - [tai_regalloc(p).Reg];
                           hp1 := p;
                           hp1 := p;
                           hp2 := nil;
                           hp2 := nil;
-                          While GetLastInstruction(hp1, hp1) And
-                                Not(RegInInstruction(PaiRegAlloc(p)^.Reg, hp1)) Do
+                          While Not(FindRegAlloc(tai_regalloc(p).Reg, tai(hp1.Next))) And
+                                GetNextInstruction(hp1, hp1) And
+                                RegInInstruction(tai_regalloc(p).Reg, hp1) Do
                             hp2 := hp1;
                             hp2 := hp1;
                           If hp2 <> nil Then
                           If hp2 <> nil Then
                             Begin
                             Begin
-                              hp1 := New(PaiRegAlloc, DeAlloc(PaiRegAlloc(p)^.Reg));
-                              InsertLLItem(Pai(hp2^.previous), hp2, hp1);
-                            End;
-                        End;
-                    End
-                  else
-                    Begin
-                      UsedRegs := UsedRegs - [PaiRegAlloc(p)^.Reg];
-                      hp1 := p;
-                      hp2 := nil;
-                      While Not(FindRegAlloc(PaiRegAlloc(p)^.Reg, Pai(hp1^.Next))) And
-                            GetNextInstruction(hp1, hp1) And
-                            RegInInstruction(PaiRegAlloc(p)^.Reg, hp1) Do
-                        hp2 := hp1;
-                      If hp2 <> nil Then
-                        Begin
-                          hp1 := Pai(p^.previous);
-                          AsmL^.Remove(p);
-                          InsertLLItem(hp2, Pai(hp2^.Next), p);
-                          p := hp1;
+                              hp1 := tai(p.previous);
+                              AsmL.Remove(p);
+                              InsertLLItem(hp2, tai(hp2.Next), p);
+                              p := hp1;
+                            End
                         End
                         End
+                    };
                     End
                     End
                 End
                 End
-            End
-          End;
-        P := Pai(p^.Next);
-        While Assigned(p) And
-              (p^.typ in (SkipInstr - [ait_regalloc])) Do
-          P := Pai(P^.Next)
-      End
-End;
+              End;
+            P := tai(p.Next);
+            While Assigned(p) And
+                  (p.typ in (SkipInstr - [ait_regalloc])) Do
+              P := tai(P.Next)
+          End
+    End;
 
 
 
 
 
 
-Procedure TAsmOptimizer.Optimize;
-Var HP: Pai;
-    DFA: PAOptDFACpu;
-Begin
-  BlockStart := Pai(AsmL^.First);
-  While Assigned(BlockStart) Do
-    Begin
-      { Initialize BlockEnd and the LabelInfo (low and high label) }
-      BlockEnd := FindLoHiLabels;
-      { initialize the LabelInfo (labeltable) and fix the regalloc info }
-      BuildLabelTableAndFixRegAlloc;
-      { peephole optimizations, twice because you can't do them all in one }
-      { pass                                                               }
-{      PeepHoleOptPass1;
-      PeepHoleOptPass1;}
-      If (cs_slowoptimize in aktglobalswitches) Then
-        Begin
-          New(DFA,Init(AsmL,BlockStart,BlockEnd,LabelInfo));
-          { data flow analyzer }
-          DFA^.DoDFA;
-          { common subexpression elimination }
-{          CSE;}
-        End;
-      { more peephole optimizations }
-{      PeepHoleOptPass2;}
-      {dispose labeltabel}
-      If Assigned(LabelInfo^.LabelTable) Then
-        Begin
-          Dispose(LabelInfo^.LabelTable);
-          LabelInfo := Nil
-        End;
-      { continue where we left off, BlockEnd is either the start of an }
-      { assembler block or nil}
-      BlockStart := BlockEnd;
-      While Assigned(BlockStart) And
-            (BlockStart^.typ = ait_Marker) And
-            (Pai_Marker(BlockStart)^.Kind = AsmBlockStart) Do
-        Begin
-         { we stopped at an assembler block, so skip it }
-          While GetNextInstruction(BlockStart, BlockStart) And
-                ((BlockStart^.Typ <> Ait_Marker) Or
-                 (Pai_Marker(Blockstart)^.Kind <> AsmBlockEnd)) Do;
-         { blockstart now contains a pai_marker(asmblockend) }
-          If Not(GetNextInstruction(BlockStart, HP) And
-                 ((HP^.typ <> ait_Marker) Or
-                  (Pai_Marker(HP)^.Kind <> AsmBlockStart)
-                 )
-                ) Then
-           {skip the next assembler block }
-           BlockStart := HP;
-         { otherwise there is no assembler block anymore after the current }
-         { one, so optimize the next block of "normal" instructions        }
-        End
-    End;
-End;
+    Procedure TAsmOptimizer.Optimize;
+      Var
+        HP: tai;
+        pass: longint;
+      Begin
+        pass:=0;
+        BlockStart := tai(AsmL.First);
+        While Assigned(BlockStart) Do
+          Begin
+             if pass = 0 then
+               PrePeepHoleOpts;
+            { Peephole optimizations }
+             PeepHoleOptPass1;
+            { Only perform them twice in the first pass }
+             if pass = 0 then
+               PeepHoleOptPass1;
+            If (cs_slowoptimize in aktglobalswitches) Then
+              Begin
+                // DFA:=TAOptDFACpu.Create(AsmL,BlockStart,BlockEnd,LabelInfo);
+                { data flow analyzer }
+                DFA.DoDFA;
+                { common subexpression elimination }
+      {          CSE;}
+              End;
+            { more peephole optimizations }
+      {      PeepHoleOptPass2;}
+            {dispose labeltabel}
+            If Assigned(LabelInfo^.LabelTable) Then
+              Begin
+                Dispose(LabelInfo^.LabelTable);
+                LabelInfo := Nil
+              End;
+            { continue where we left off, BlockEnd is either the start of an }
+            { assembler block or nil}
+            BlockStart := BlockEnd;
+            While Assigned(BlockStart) And
+                  (BlockStart.typ = ait_Marker) And
+                  (tai_Marker(BlockStart).Kind = AsmBlockStart) Do
+              Begin
+               { we stopped at an assembler block, so skip it }
+                While GetNextInstruction(BlockStart, BlockStart) And
+                      ((BlockStart.Typ <> Ait_Marker) Or
+                       (tai_Marker(Blockstart).Kind <> AsmBlockEnd)) Do;
+               { blockstart now contains a tai_marker(asmblockend) }
+                If Not(GetNextInstruction(BlockStart, HP) And
+                       ((HP.typ <> ait_Marker) Or
+                        (tai_Marker(HP).Kind <> AsmBlockStart)
+                       )
+                      ) Then
+                 {skip the next assembler block }
+                 BlockStart := HP;
+               { otherwise there is no assembler block anymore after the current }
+               { one, so optimize the next block of "normal" instructions        }
+              End
+          End;
+      End;
 
 
-Destructor TAsmOptimizer.Done;
-Begin
-  Dispose(LabelInfo)
-End;
+    Destructor TAsmOptimizer.Destroy;
+      Begin
+        Dispose(LabelInfo)
+      End;
 
 
 
 
-procedure Optimize(AsmL:Paasmoutput);
-var
-  p : PAsmOptimizer;
-begin
-  new(p,Init(AsmL));
-  p^.Optimize;
-  dispose(p,Done);
-end;
+    procedure Optimize(AsmL:taasmoutput);
+      var
+        p : TAsmOptimizer;
+      begin
+        p:=casmoptimizer.Create(AsmL);
+        p.Optimize;
+        p.free
+      end;
 
 
 
 
-End.
+begin
+  casmoptimizer:=TAsmOptimizer;
+end.
 
 
 {Virtual methods, most have to be overridden by processor dependent methods}
 {Virtual methods, most have to be overridden by processor dependent methods}
 
 
 {
 {
  $Log$
  $Log$
- Revision 1.6  2004-06-20 08:55:28  florian
-   * logs truncated
+ Revision 1.7  2004-10-30 15:21:37  florian
+   * fixed generic optimizer
+   * enabled generic optimizer for sparc
 
 
+ Revision 1.6  2004/06/20 08:55:28  florian
+   * logs truncated
 }
 }

+ 232 - 232
compiler/aoptbase.pas

@@ -23,246 +23,246 @@
 }
 }
 unit aoptbase;
 unit aoptbase;
 
 
-Interface
-
-uses aasmbase,aasmcpu,aasmtai,
-  cpubase;
-
-{ the number of tai objects processed by an optimizer object since the last }
-{ time a register was modified                                              }
-Type TInstrSinceLastMod = Array[LoGPReg..HiGPReg] of byte;
-
-{ the TAopBase object implements the basic methods that most other }
-{ assembler optimizer objects require                              }
-Type
-  TAoptBase = Object
-    { processor independent methods }
-
-    constructor init;
-    destructor done;
-    { returns true if register Reg is used by instruction p1 }
-    Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;
-    { returns true if register Reg occurs in operand op }
-    Function RegInOp(Reg: TRegister; const op: toper): Boolean;
-    { returns true if register Reg is used in the reference Ref }
-    Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
-
-    { returns true if the references are completely equal }
-    {Function RefsEqual(Const R1, R2: TReference): Boolean;}
-
-    { gets the next tai object after current that contains info relevant }
-    { to the optimizer in p1. If there is none, it returns false and     }
-    { sets p1 to nil                                                     }
-    Function GetNextInstruction(Current: tai; Var Next: tai): Boolean;
-    { gets the previous tai object after current that contains info  }
-    { relevant to the optimizer in last. If there is none, it retuns }
-    { false and sets last to nil                                     }
-    Function GetLastInstruction(Current: tai; Var Last: tai): Boolean;
-
-
-    { processor dependent methods }
-
-    { returns the maximum width component of Reg. Only has to be }
-    { overridden for the 80x86 (afaik)                           }
-    Function RegMaxSize(Reg: TRegister): TRegister; Virtual;
-    { returns true if Reg1 and Reg2 are of the samae width. Only has to }
-    { overridden for the 80x86 (afaik)                                  }
-    Function RegsSameSize(Reg1, Reg2: TRegister): Boolean; Virtual;
-    { returns whether P is a load instruction (load contents from a }
-    { memory location or (register) variable into a register)       }
-    Function IsLoadMemReg(p: tai): Boolean; Virtual;
-    { returns whether P is a load constant instruction (load a constant }
-    { into a register)                                                  }
-    Function IsLoadConstReg(p: tai): Boolean; Virtual;
-    { returns whether P is a store instruction (store contents from a }
-    { register to a memory location or to a (register) variable)      }
-    Function IsStoreRegMem(p: tai): Boolean; Virtual;
-
-    { create a paicpu Object that loads the contents of reg1 into reg2 }
-    Function a_load_reg_reg(reg1, reg2: TRegister): taicpu; Virtual;
-
-end;
-
-Function RefsEqual(Const R1, R2: TReference): Boolean;
-
-
-Implementation
-
-uses globals, aoptcpub, cpuinfo;
-
-Function RefsEqual(Const R1, R2: TReference): Boolean;
-Begin
-  RefsEqual := (R1.Offset+R1.OffsetFixup = R2.Offset+R2.OffsetFixup)
-               And (R1.Base = R2.Base)
-{$ifdef RefsHaveindex}
-               And (R1.Index = R2.Index)
-{$endif RefsHaveindex}
-{$ifdef RefsHaveScale}
-               And (R1.ScaleFactor = R2.ScaleFactor)
-{$endif RefsHaveScale}
-               And (R1.Symbol = R2.Symbol)
-{$ifdef RefsHaveSegment}
-               And (R1.Segment = R2.Segment)
-{$endif RefsHaveSegment}
-               ;
-End;
-
-
-constructor taoptbase.init;
-begin
-end;
-
-destructor taoptbase.done;
-begin
-end;
-
-Function TAOptBase.RegInInstruction(Reg: TRegister; p1: tai): Boolean;
-Var Count: AWord;
-    TmpResult: Boolean;
-Begin
-  TmpResult := False;
-  Count := 0;
-  If (p1.typ = ait_instruction) Then
+{$i fpcdefs.inc}
+
+  interface
+
+    uses
+      aasmbase,aasmcpu,aasmtai,
+      cpubase,
+      cgbase;
+
+    Type
+      { the number of tai objects processed by an optimizer object since the last
+        time a register was modified                                              }
+      { size at each dimension depends on the registers of this type }
+      TInstrSinceLastMod = Array[tregistertype] of pbyte;
+
+    { the TAopBase object implements the basic methods that most other }
+    { assembler optimizer objects require                              }
+    Type
+      TAoptBase = class
+        { processor independent methods }
+
+        constructor create;
+        destructor destroy;override;
+        { returns true if register Reg is used by instruction p1 }
+        Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;
+        { returns true if register Reg occurs in operand op }
+        Function RegInOp(Reg: TRegister; const op: toper): Boolean;
+        { returns true if register Reg is used in the reference Ref }
+        Function RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
+
+        { returns true if the references are completely equal }
+        {Function RefsEqual(Const R1, R2: TReference): Boolean;}
+
+        { gets the next tai object after current that contains info relevant }
+        { to the optimizer in p1. If there is none, it returns false and     }
+        { sets p1 to nil                                                     }
+        Function GetNextInstruction(Current: tai; Var Next: tai): Boolean;
+        { gets the previous tai object after current that contains info  }
+        { relevant to the optimizer in last. If there is none, it retuns }
+        { false and sets last to nil                                     }
+        Function GetLastInstruction(Current: tai; Var Last: tai): Boolean;
+
+
+        { processor dependent methods }
+
+        { returns the maximum width component of Reg. Only has to be }
+        { overridden for the 80x86 (afaik)                           }
+        Function RegMaxSize(Reg: TRegister): TRegister; Virtual;
+        { returns true if Reg1 and Reg2 are of the samae width. Only has to }
+        { overridden for the 80x86 (afaik)                                  }
+        Function RegsSameSize(Reg1, Reg2: TRegister): Boolean; Virtual;
+        { returns whether P is a load instruction (load contents from a }
+        { memory location or (register) variable into a register)       }
+        Function IsLoadMemReg(p: tai): Boolean; Virtual;
+        { returns whether P is a load constant instruction (load a constant }
+        { into a register)                                                  }
+        Function IsLoadConstReg(p: tai): Boolean; Virtual;
+        { returns whether P is a store instruction (store contents from a }
+        { register to a memory location or to a (register) variable)      }
+        Function IsStoreRegMem(p: tai): Boolean; Virtual;
+
+        { create a paicpu Object that loads the contents of reg1 into reg2 }
+        Function a_load_reg_reg(reg1, reg2: TRegister): taicpu; Virtual;
+
+    end;
+
+
+  implementation
+
+    uses
+      globtype,globals, aoptcpub, cpuinfo;
+
+  constructor taoptbase.create;
+    begin
+      inherited create;
+    end;
+
+
+  destructor taoptbase.destroy;
+    begin
+      inherited destroy;
+    end;
+
+
+  Function TAOptBase.RegInInstruction(Reg: TRegister; p1: tai): Boolean;
+    Var Count: AWord;
+        TmpResult: Boolean;
+    Begin
+      TmpResult := False;
+      Count := 0;
+      If (p1.typ = ait_instruction) Then
+        Repeat
+          TmpResult := RegInOp(Reg, PInstr(p1)^.oper[Count]^);
+          Inc(Count)
+        Until (Count = MaxOps) or TmpResult;
+      RegInInstruction := TmpResult
+    End;
+
+
+  Function TAOptBase.RegInOp(Reg: TRegister; const op: toper): Boolean;
+    Begin
+      Case op.typ Of
+        Top_Reg: RegInOp := Reg = op.reg;
+        Top_Ref: RegInOp := RegInRef(Reg, op.ref^)
+        Else RegInOp := False
+      End
+    End;
+
+
+  Function TAOptBase.RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
+  Begin
+    Reg := RegMaxSize(Reg);
+    RegInRef := (Ref.Base = Reg)
+  {$ifdef RefsHaveIndexReg}
+    Or (Ref.Index = Reg)
+  {$endif RefsHaveIndexReg}
+  End;
+
+  Function TAOptBase.GetNextInstruction(Current: tai; Var Next: tai): Boolean;
+  Begin
     Repeat
     Repeat
-      TmpResult := RegInOp(Reg, PInstr(p1)^.oper[Count]);
-      Inc(Count)
-    Until (Count = MaxOps) or TmpResult;
-  RegInInstruction := TmpResult
-End;
-
-
-Function TAOptBase.RegInOp(Reg: TRegister; const op: toper): Boolean;
-Begin
-  Case op.typ Of
-    Top_Reg: RegInOp := Reg = op.reg;
-    Top_Ref: RegInOp := RegInRef(Reg, op.ref^)
-    Else RegInOp := False
-  End
-End;
-
-
-Function TAOptBase.RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
-Begin
-  Reg := RegMaxSize(Reg);
-  RegInRef := (Ref.Base = Reg)
-{$ifdef RefsHaveIndexReg}
-  Or (Ref.Index = Reg)
-{$endif RefsHaveIndexReg}
-End;
-
-Function TAOptBase.GetNextInstruction(Current: tai; Var Next: tai): Boolean;
-Begin
-  Repeat
-    Current := tai(Current.Next);
-    While Assigned(Current) And
-          ((Current.typ In SkipInstr) or
-           ((Current.typ = ait_label) And
-            Not(Tai_Label(Current).l.is_used))) Do
       Current := tai(Current.Next);
       Current := tai(Current.Next);
+      While Assigned(Current) And
+            ((Current.typ In SkipInstr) or
+{$ifdef SPARC}
+             ((Current.typ=ait_instruction) and
+              (taicpu(Current).opcode=A_NOP)
+             ) or
+{$endif SPARC}
+             ((Current.typ = ait_label) And
+              Not(Tai_Label(Current).l.is_used))) Do
+        Current := tai(Current.Next);
+      If Assigned(Current) And
+         (Current.typ = ait_Marker) And
+         (Tai_Marker(Current).Kind = NoPropInfoStart) Then
+        Begin
+          While Assigned(Current) And
+                ((Current.typ <> ait_Marker) Or
+                 (Tai_Marker(Current).Kind <> NoPropInfoEnd)) Do
+            Current := Tai(Current.Next);
+        End;
+    Until Not(Assigned(Current)) Or
+          (Current.typ <> ait_Marker) Or
+          (Tai_Marker(Current).Kind <> NoPropInfoEnd);
+    Next := Current;
     If Assigned(Current) And
     If Assigned(Current) And
-       (Current.typ = ait_Marker) And
-       (Tai_Marker(Current).Kind = NoPropInfoStart) Then
-      Begin
-        While Assigned(Current) And
-              ((Current.typ <> ait_Marker) Or
-               (Tai_Marker(Current).Kind <> NoPropInfoEnd)) Do
-          Current := Tai(Current.Next);
-      End;
-  Until Not(Assigned(Current)) Or
-        (Current.typ <> ait_Marker) Or
-        (Tai_Marker(Current).Kind <> NoPropInfoEnd);
-  Next := Current;
-  If Assigned(Current) And
-     Not((Current.typ In SkipInstr) or
-         ((Current.typ = ait_label) And
-          Not(Tai_Label(Current).l.is_used)))
-    Then GetNextInstruction := True
-    Else
-      Begin
-        Next := Nil;
-        GetNextInstruction := False;
-      End;
-End;
-
-Function TAOptBase.GetLastInstruction(Current: tai; Var Last: tai): Boolean;
-Begin
-  Repeat
-    Current := Tai(Current.previous);
-    While Assigned(Current) And
-          (((Current.typ = ait_Marker) And
-            Not(Tai_Marker(Current).Kind in [AsmBlockEnd,NoPropInfoEnd])) or
-           (Current.typ In SkipInstr) or
+       Not((Current.typ In SkipInstr) or
            ((Current.typ = ait_label) And
            ((Current.typ = ait_label) And
-             Not(Tai_Label(Current).l.is_used))) Do
+            Not(Tai_Label(Current).l.is_used)))
+      Then GetNextInstruction := True
+      Else
+        Begin
+          Next := Nil;
+          GetNextInstruction := False;
+        End;
+  End;
+
+  Function TAOptBase.GetLastInstruction(Current: tai; Var Last: tai): Boolean;
+  Begin
+    Repeat
       Current := Tai(Current.previous);
       Current := Tai(Current.previous);
-    If Assigned(Current) And
-       (Current.typ = ait_Marker) And
-       (Tai_Marker(Current).Kind = NoPropInfoEnd) Then
-      Begin
-        While Assigned(Current) And
-              ((Current.typ <> ait_Marker) Or
-               (Tai_Marker(Current).Kind <> NoPropInfoStart)) Do
-          Current := Tai(Current.previous);
-      End;
-  Until Not(Assigned(Current)) Or
-        (Current.typ <> ait_Marker) Or
-        (Tai_Marker(Current).Kind <> NoPropInfoStart);
-  If Not(Assigned(Current)) or
-     (Current.typ In SkipInstr) or
-     ((Current.typ = ait_label) And
-      Not(Tai_Label(Current).l.is_used)) or
-     ((Current.typ = ait_Marker) And
-      (Tai_Marker(Current).Kind = AsmBlockEnd))
-    Then
-      Begin
-        Last := Nil;
-        GetLastInstruction := False
-      End
-    Else
-      Begin
-        Last := Current;
-        GetLastInstruction := True;
-      End;
-End;
-
-
-{ ******************* Processor dependent stuff *************************** }
-
-Function TAOptBase.RegMaxSize(Reg: TRegister): TRegister;
-Begin
-  RegMaxSize := Reg
-End;
-
-Function TAOptBase.RegsSameSize(Reg1, Reg2: TRegister): Boolean;
-Begin
-  RegsSameSize := True
-End;
-
-Function TAOptBase.IsLoadMemReg(p: tai): Boolean;
-Begin
-  Abstract
-End;
-
-Function TAOptBase.IsLoadConstReg(p: tai): Boolean;
-Begin
-  Abstract
-End;
-
-Function TAOptBase.IsStoreRegMem(p: tai): Boolean;
-Begin
-  Abstract
-End;
-
-Function TAoptBase.a_load_reg_reg(reg1, reg2: TRegister): taicpu;
-Begin
-  Abstract
-End;
-
-End.
+      While Assigned(Current) And
+            (((Current.typ = ait_Marker) And
+              Not(Tai_Marker(Current).Kind in [AsmBlockEnd,NoPropInfoEnd])) or
+             (Current.typ In SkipInstr) or
+             ((Current.typ = ait_label) And
+               Not(Tai_Label(Current).l.is_used))) Do
+        Current := Tai(Current.previous);
+      If Assigned(Current) And
+         (Current.typ = ait_Marker) And
+         (Tai_Marker(Current).Kind = NoPropInfoEnd) Then
+        Begin
+          While Assigned(Current) And
+                ((Current.typ <> ait_Marker) Or
+                 (Tai_Marker(Current).Kind <> NoPropInfoStart)) Do
+            Current := Tai(Current.previous);
+        End;
+    Until Not(Assigned(Current)) Or
+          (Current.typ <> ait_Marker) Or
+          (Tai_Marker(Current).Kind <> NoPropInfoStart);
+    If Not(Assigned(Current)) or
+       (Current.typ In SkipInstr) or
+       ((Current.typ = ait_label) And
+        Not(Tai_Label(Current).l.is_used)) or
+       ((Current.typ = ait_Marker) And
+        (Tai_Marker(Current).Kind = AsmBlockEnd))
+      Then
+        Begin
+          Last := Nil;
+          GetLastInstruction := False
+        End
+      Else
+        Begin
+          Last := Current;
+          GetLastInstruction := True;
+        End;
+  End;
+
+
+  { ******************* Processor dependent stuff *************************** }
+
+  Function TAOptBase.RegMaxSize(Reg: TRegister): TRegister;
+  Begin
+    RegMaxSize := Reg
+  End;
+
+  Function TAOptBase.RegsSameSize(Reg1, Reg2: TRegister): Boolean;
+  Begin
+    RegsSameSize := True
+  End;
+
+  Function TAOptBase.IsLoadMemReg(p: tai): Boolean;
+  Begin
+    Abstract
+  End;
+
+  Function TAOptBase.IsLoadConstReg(p: tai): Boolean;
+  Begin
+    Abstract
+  End;
+
+  Function TAOptBase.IsStoreRegMem(p: tai): Boolean;
+  Begin
+    Abstract
+  End;
+
+  Function TAoptBase.a_load_reg_reg(reg1, reg2: TRegister): taicpu;
+  Begin
+    Abstract
+  End;
+
+end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.7  2004-06-20 08:55:28  florian
+  Revision 1.8  2004-10-30 15:21:37  florian
+    * fixed generic optimizer
+    * enabled generic optimizer for sparc
+
+  Revision 1.7  2004/06/20 08:55:28  florian
     * logs truncated
     * logs truncated
 
 
 }
 }

+ 150 - 137
compiler/aoptda.pas

@@ -24,164 +24,177 @@
 }
 }
 Unit aoptda;
 Unit aoptda;
 
 
-Interface
-
-uses aasm, cpubase, aoptcpub, aoptbase, aoptcpu;
-
-Type
-  TAOptDFA = Object(TAoptCpu)
-    { uses the same constructor as TAoptCpu = constructor from TAoptObj }
-
-    { gathers the information regarding the contents of every register }
-    { at the end of every instruction                                  }
-    Procedure DoDFA;
-
-    { handles the processor dependent dataflow analizing               }
-    Procedure CpuDFA(p: PInstr); Virtual;
-
-    { How many instructions are between the current instruction and the }
-    { last one that modified the register                               }
-    InstrSinceLastMod: TInstrSinceLastMod;
-
-    { convert a TInsChange value into the corresponding register }
-    Function TCh2Reg(Ch: TInsChange): TRegister; Virtual;
-    { returns whether the instruction P reads from register Reg }
-    Function RegReadByInstr(Reg: TRegister; p: Pai): Boolean; Virtual;
-  End;
-
-Implementation
-
-uses globals, aoptobj;
-
-Procedure TAOptDFA.DoDFA;
-{ Analyzes the Data Flow of an assembler list. Analyses the reg contents     }
-{ for the instructions between blockstart and blockend. Returns the last pai }
-{ which has been processed                                                   }
-Var
-    CurProp: PPaiProp;
-    UsedRegs: TUsedRegs;
-    p, hp, NewBlockStart : Pai;
-    TmpReg: TRegister;
-Begin
-  p := BlockStart;
-  UsedRegs.init;
-  UsedRegs.Update(p);
-  NewBlockStart := SkipHead(p);
-  { done implicitely by the constructor
-  FillChar(InstrSinceLastMod, SizeOf(InstrSinceLastMod), 0); }
-  While (P <> BlockEnd) Do
+{$i fpcdefs.inc}
+
+  Interface
+
+    uses
+      cpubase,cgbase,
+      aasmbase,aasmtai,aasmcpu,
+      aoptcpub, aoptbase;
+
+    Type
+      TAOptDFA = class
+        { uses the same constructor as TAoptCpu = constructor from TAoptObj }
+
+        { gathers the information regarding the contents of every register }
+        { at the end of every instruction                                  }
+        Procedure DoDFA;
+
+        { handles the processor dependent dataflow analizing               }
+        Procedure CpuDFA(p: PInstr); Virtual;
+
+        { How many instructions are between the current instruction and the }
+        { last one that modified the register                               }
+        InstrSinceLastMod: TInstrSinceLastMod;
+
+        { convert a TInsChange value into the corresponding register }
+        //!!!!!!!!!! Function TCh2Reg(Ch: TInsChange): TRegister; Virtual;
+        { returns whether the instruction P reads from register Reg }
+        Function RegReadByInstr(Reg: TRegister; p: tai): Boolean; Virtual;
+      End;
+
+  Implementation
+
+    uses
+      globals, aoptobj;
+
+    Procedure TAOptDFA.DoDFA;
+    { Analyzes the Data Flow of an assembler list. Analyses the reg contents     }
+    { for the instructions between blockstart and blockend. Returns the last pai }
+    { which has been processed                                                   }
+    Var
+        CurProp: TPaiProp;
+        UsedRegs: TUsedRegs;
+        p, hp, NewBlockStart : tai;
+        TmpReg: TRegister;
     Begin
     Begin
-      CurProp := New(PPaiProp, init);
-      If (p <> NewBlockStart) Then
+    {!!!!!!!!!!
+      p := BlockStart;
+      UsedRegs.Create;
+      UsedRegs.Update(p);
+      NewBlockStart := SkipHead(p);
+      { done implicitely by the constructor
+      FillChar(InstrSinceLastMod, SizeOf(InstrSinceLastMod), 0); }
+      While (P <> BlockEnd) Do
         Begin
         Begin
-          GetLastInstruction(p, hp);
-          CurProp^.Regs := PPaiProp(hp^.OptInfo)^.Regs;
-{ !!!!!!!!!!!! }
-{$ifdef x86}
-          CurProp^.CondRegs.Flags :=
-            PPaiProp(hp^.OptInfo)^.CondRegs.Flags;
-{$endif}
-        End;
-      CurProp^.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs);
-      UsedRegs.Update(Pai(p^.Next));
-      PPaiProp(p^.OptInfo) := CurProp;
-      For TmpReg := LoGPReg To HiGPReg Do
-        Inc(InstrSinceLastMod[TmpReg]);
-      Case p^.typ Of
-        ait_label:
-          If (Pai_label(p)^.l^.is_used) Then
-            CurProp^.DestroyAllRegs(InstrSinceLastMod);
-{$ifdef GDB}
-        ait_stabs, ait_stabn, ait_stab_function_name:;
-{$endif GDB}
-        ait_instruction:
-          if not(PInstr(p)^.is_jmp) then
-            begin
-              If IsLoadMemReg(p) Then
-                Begin
-                  CurProp^.ReadRef(PInstr(p)^.oper[LoadSrc].ref);
-                  TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
-                  If RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^) And
-                     (CurProp^.GetRegContentType(TmpReg) = Con_Ref) Then
+          CurProp:=TPaiProp.Create;
+          If (p <> NewBlockStart) Then
+            Begin
+              GetLastInstruction(p, hp);
+              CurProp.Regs := TPaiProp(hp.OptInfo).Regs;
+    { !!!!!!!!!!!! }
+    {$ifdef x86}
+              CurProp.CondRegs.Flags :=
+                TPaiProp(hp.OptInfo).CondRegs.Flags;
+    {$endif}
+            End;
+          CurProp.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs);
+          UsedRegs.Update(tai(p.Next));
+          TPaiProp(p.OptInfo) := CurProp;
+          For TmpReg := LoGPReg To HiGPReg Do
+            Inc(InstrSinceLastMod[TmpReg]);
+          Case p^.typ Of
+            ait_label:
+              If (Pai_label(p)^.l^.is_used) Then
+                CurProp^.DestroyAllRegs(InstrSinceLastMod);
+    {$ifdef GDB}
+            ait_stabs, ait_stabn, ait_stab_function_name:;
+    {$endif GDB}
+            ait_instruction:
+              if not(PInstr(p)^.is_jmp) then
+                begin
+                  If IsLoadMemReg(p) Then
                     Begin
                     Begin
-                      { a load based on the value this register already }
-                      { contained                                       }
-                      With CurProp^.Regs[TmpReg] Do
+                      CurProp^.ReadRef(PInstr(p)^.oper[LoadSrc].ref);
+                      TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
+                      If RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^) And
+                         (CurProp^.GetRegContentType(TmpReg) = Con_Ref) Then
                         Begin
                         Begin
-                          CurProp^.IncWState(TmpReg);
-                           {also store how many instructions are part of the  }
-                           { sequence in the first instruction's PPaiProp, so }
-                           { it can be easily accessed from within            }
-                           { CheckSequence                                    }
-                          Inc(NrOfMods, InstrSinceLastMod[TmpReg]);
-                          PPaiProp(Pai(StartMod)^.OptInfo)^.Regs[TmpReg].NrOfMods := NrOfMods;
-                          InstrSinceLastMod[TmpReg] := 0
+                          { a load based on the value this register already }
+                          { contained                                       }
+                          With CurProp^.Regs[TmpReg] Do
+                            Begin
+                              CurProp^.IncWState(TmpReg);
+                               {also store how many instructions are part of the  }
+                               { sequence in the first instruction's PPaiProp, so }
+                               { it can be easily accessed from within            }
+                               { CheckSequence                                    }
+                              Inc(NrOfMods, InstrSinceLastMod[TmpReg]);
+                              PPaiProp(Pai(StartMod)^.OptInfo)^.Regs[TmpReg].NrOfMods := NrOfMods;
+                              InstrSinceLastMod[TmpReg] := 0
+                            End
                         End
                         End
+                      Else
+                        Begin
+                          { load of a register with a completely new value }
+                          CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
+                          If Not(RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^)) Then
+                            With CurProp^.Regs[TmpReg] Do
+                              Begin
+                                Typ := Con_Ref;
+                                StartMod := p;
+                                NrOfMods := 1;
+                              End
+                        End;
+      {$ifdef StateDebug}
+                        hp := new(pai_asm_comment,init(strpnew(std_reg2str[TmpReg]+': '+tostr(CurProp^.Regs[TmpReg].WState))));
+                        InsertLLItem(AsmL, p, p^.next, hp);
+      {$endif StateDebug}
+
                     End
                     End
-                  Else
+                  Else if IsLoadConstReg(p) Then
                     Begin
                     Begin
-                      { load of a register with a completely new value }
-                      CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
-                      If Not(RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^)) Then
-                        With CurProp^.Regs[TmpReg] Do
-                          Begin
-                            Typ := Con_Ref;
-                            StartMod := p;
-                            NrOfMods := 1;
-                          End
-                    End;
-  {$ifdef StateDebug}
-                    hp := new(pai_asm_comment,init(strpnew(std_reg2str[TmpReg]+': '+tostr(CurProp^.Regs[TmpReg].WState))));
-                    InsertLLItem(AsmL, p, p^.next, hp);
-  {$endif StateDebug}
-
-                End
-              Else if IsLoadConstReg(p) Then
-                Begin
-                  TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
-                  With CurProp^.Regs[TmpReg] Do
-                    Begin
-                      CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
-                      typ := Con_Const;
-                      StartMod := Pointer(PInstr(p)^.oper[LoadSrc].val);
+                      TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
+                      With CurProp^.Regs[TmpReg] Do
+                        Begin
+                          CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
+                          typ := Con_Const;
+                          StartMod := Pointer(PInstr(p)^.oper[LoadSrc].val);
+                        End
                     End
                     End
-                End
-              Else CpuDFA(Pinstr(p));
-            End;
-        Else CurProp^.DestroyAllRegs(InstrSinceLastMod);
-      End;
-{      Inc(InstrCnt);}
-      GetNextInstruction(p, p);
+                  Else CpuDFA(Pinstr(p));
+                End;
+            Else CurProp^.DestroyAllRegs(InstrSinceLastMod);
+          End;
+    {      Inc(InstrCnt);}
+          GetNextInstruction(p, p);
+        End;
+    }
     End;
     End;
-End;
 
 
-Procedure TAoptDFA.CpuDFA(p: PInstr);
-Begin
-  Abstract;
-End;
+    Procedure TAoptDFA.CpuDFA(p: PInstr);
+    Begin
+      Abstract;
+    End;
 
 
-Function TAOptDFA.TCh2Reg(Ch: TInsChange): TRegister;
-Begin
-  TCh2Reg:=R_NO;
-  Abstract;
-End;
+  {!!!!!!!
+    Function TAOptDFA.TCh2Reg(Ch: TInsChange): TRegister;
+    Begin
+      TCh2Reg:=R_NO;
+      Abstract;
+    End;
+  }
 
 
-Function TAOptDFA.RegReadByInstr(Reg: TRegister; p: Pai): Boolean;
-Begin
-  RegReadByInstr:=false;
-  Abstract;
-End;
+    Function TAOptDFA.RegReadByInstr(Reg: TRegister; p: tai): Boolean;
+    Begin
+      RegReadByInstr:=false;
+      Abstract;
+    End;
 
 
 
 
 End.
 End.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.8  2004-06-20 08:55:28  florian
+  Revision 1.9  2004-10-30 15:21:37  florian
+    * fixed generic optimizer
+    * enabled generic optimizer for sparc
+
+  Revision 1.8  2004/06/20 08:55:28  florian
     * logs truncated
     * logs truncated
 
 
   Revision 1.7  2004/01/31 17:45:16  peter
   Revision 1.7  2004/01/31 17:45:16  peter
     * Change several $ifdef i386 to x86
     * Change several $ifdef i386 to x86
     * Change several OS_32 to OS_INT/OS_ADDR
     * Change several OS_32 to OS_INT/OS_ADDR
-
 }
 }

File diff suppressed because it is too large
+ 1044 - 743
compiler/aoptobj.pas


+ 7 - 8
compiler/fpcdefs.inc

@@ -24,7 +24,7 @@
       {$ifndef USEOPT}
       {$ifndef USEOPT}
         {$define NOOPT}
         {$define NOOPT}
       {$endif}
       {$endif}
-      
+
       { 1.0.x generates broken code for sysutils }
       { 1.0.x generates broken code for sysutils }
       {$ifndef FORCE_SYSUTILS}
       {$ifndef FORCE_SYSUTILS}
         {$undef USE_SYSUTILS}
         {$undef USE_SYSUTILS}
@@ -37,7 +37,7 @@
        {$undef USE_SYSUTILS}
        {$undef USE_SYSUTILS}
      {$endif}	
      {$endif}	
   {$endif}
   {$endif}
-   
+
   {$define FPCPROCVAR}
   {$define FPCPROCVAR}
   {$define USEEXCEPT}
   {$define USEEXCEPT}
 
 
@@ -58,18 +58,15 @@
   {$define cpu64bit}
   {$define cpu64bit}
   {$define cpuextended}
   {$define cpuextended}
   {$define cpufloat128}
   {$define cpufloat128}
-  {$define noopt}
   {$define cputargethasfixedstack}
   {$define cputargethasfixedstack}
 {$endif x86_64}
 {$endif x86_64}
 
 
 {$ifdef alpha}
 {$ifdef alpha}
   {$define cpu64bit}
   {$define cpu64bit}
-  {$define noopt}
 {$endif alpha}
 {$endif alpha}
 
 
 {$ifdef sparc}
 {$ifdef sparc}
   {$define cpuflags}
   {$define cpuflags}
-  {$define noopt}
   {$define cputargethasfixedstack}
   {$define cputargethasfixedstack}
   {$define cpurequiresproperalignment}
   {$define cpurequiresproperalignment}
 {$endif sparc}
 {$endif sparc}
@@ -84,19 +81,21 @@
   {$define cpuflags}
   {$define cpuflags}
   {$define cpuneedsdiv32helper}
   {$define cpuneedsdiv32helper}
   {$define cputargethasfixedstack}
   {$define cputargethasfixedstack}
-  {$define noopt}
   {$define cpurequiresproperalignment}
   {$define cpurequiresproperalignment}
 {$endif arm}
 {$endif arm}
 
 
 {$ifdef m68k}
 {$ifdef m68k}
   {$define cpuflags}
   {$define cpuflags}
   {$define cpufpemu}
   {$define cpufpemu}
-  {$define noopt}
 {$endif m68k}
 {$endif m68k}
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.44  2004-10-14 18:29:22  peter
+  Revision 1.45  2004-10-30 15:21:37  florian
+    * fixed generic optimizer
+    * enabled generic optimizer for sparc
+
+  Revision 1.44  2004/10/14 18:29:22  peter
     * disable USE_SYSUTILS when compiled with 1.9.4 or 1.0.x
     * disable USE_SYSUTILS when compiled with 1.9.4 or 1.0.x
 
 
   Revision 1.43  2004/10/10 14:57:29  jonas
   Revision 1.43  2004/10/10 14:57:29  jonas

+ 6 - 3
compiler/psub.pas

@@ -24,7 +24,6 @@ unit psub;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
-
 interface
 interface
 
 
     uses
     uses
@@ -105,7 +104,7 @@ implementation
          {$ifdef i386}
          {$ifdef i386}
            ,aopt386
            ,aopt386
          {$else i386}
          {$else i386}
-           ,aoptcpu
+           ,aopt
          {$endif i386}
          {$endif i386}
        {$endif}
        {$endif}
        ;
        ;
@@ -1404,7 +1403,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.210  2004-10-24 20:01:08  peter
+  Revision 1.211  2004-10-30 15:21:37  florian
+    * fixed generic optimizer
+    * enabled generic optimizer for sparc
+
+  Revision 1.210  2004/10/24 20:01:08  peter
     * remove saveregister calling convention
     * remove saveregister calling convention
 
 
   Revision 1.209  2004/10/15 09:14:17  mazen
   Revision 1.209  2004/10/15 09:14:17  mazen

+ 6 - 2
compiler/rgobj.pas

@@ -1235,7 +1235,7 @@ unit rgobj;
         i,j,k : word;
         i,j,k : word;
         n,a,c : Tsuperregister;
         n,a,c : Tsuperregister;
         colourednodes : Tsuperregisterset;
         colourednodes : Tsuperregisterset;
-                adj_colours:set of 0..255;
+        adj_colours:set of 0..255;
         found : boolean;
         found : boolean;
 
 
     begin
     begin
@@ -1994,7 +1994,11 @@ unit rgobj;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.144  2004-10-24 17:04:01  peter
+  Revision 1.145  2004-10-30 15:21:37  florian
+    * fixed generic optimizer
+    * enabled generic optimizer for sparc
+
+  Revision 1.144  2004/10/24 17:04:01  peter
     * during translation only process regalloc for the current regtype
     * during translation only process regalloc for the current regtype
 
 
   Revision 1.143  2004/10/15 09:14:17  mazen
   Revision 1.143  2004/10/15 09:14:17  mazen

+ 7 - 1
compiler/sparc/aasmcpu.pas

@@ -208,6 +208,7 @@ implementation
     constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
     constructor taicpu.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
       begin
       begin
          inherited create(op);
          inherited create(op);
+         is_jmp:=op in [A_BA,A_Bxx];
          condition:=cond;
          condition:=cond;
          ops:=1;
          ops:=1;
          loadsymbol(0,_op1,0);
          loadsymbol(0,_op1,0);
@@ -217,6 +218,7 @@ implementation
     constructor taicpu.op_sym(op : tasmop;_op1 : tasmsymbol);
     constructor taicpu.op_sym(op : tasmop;_op1 : tasmsymbol);
       begin
       begin
          inherited create(op);
          inherited create(op);
+         is_jmp:=op in [A_BA,A_Bxx];
          ops:=1;
          ops:=1;
          loadsymbol(0,_op1,0);
          loadsymbol(0,_op1,0);
       end;
       end;
@@ -311,7 +313,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.50  2004-06-20 08:55:32  florian
+  Revision 1.51  2004-10-30 15:21:38  florian
+    * fixed generic optimizer
+    * enabled generic optimizer for sparc
+
+  Revision 1.50  2004/06/20 08:55:32  florian
     * logs truncated
     * logs truncated
 
 
   Revision 1.49  2004/06/20 08:47:33  florian
   Revision 1.49  2004/06/20 08:47:33  florian

+ 51 - 0
compiler/sparc/aoptcpu.pas

@@ -0,0 +1,51 @@
+{
+    $Id$
+    Copyright (c) 1998-2004 by Jonas Maebe
+
+    This unit calls the optimization procedures to optimize the assembler
+    code for sparc
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+
+unit aoptcpu;
+
+{$i fpcdefs.inc}
+
+  Interface
+
+    uses
+      cpubase, aoptobj, aoptcpub, aopt;
+
+    Type
+      TCpuAsmOptimizer = class(TAsmOptimizer)
+      End;
+
+  Implementation
+
+begin
+  casmoptimizer:=TCpuAsmOptimizer;
+end.
+{
+  $Log$
+  Revision 1.1  2004-10-30 15:21:38  florian
+    * fixed generic optimizer
+    * enabled generic optimizer for sparc
+
+  Revision 1.10  2004/06/20 08:55:31  florian
+    * logs truncated
+}

+ 132 - 0
compiler/sparc/aoptcpub.pas

@@ -0,0 +1,132 @@
+ {
+    $Id$
+    Copyright (c) 1998-2004 by Jonas Maebe, member of the Free Pascal
+    Development Team
+
+    This unit contains several types and constants necessary for the
+    optimizer to work on the sparc architecture
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+Unit aoptcpub; { Assembler OPTimizer CPU specific Base }
+
+{$i fpcdefs.inc}
+
+{ enable the following define if memory references can have both a base and }
+{ index register in 1 operand                                               }
+
+{$define RefsHaveIndexReg}
+
+{ enable the following define if memory references can have a scaled index }
+
+{ define RefsHaveScale}
+
+{ enable the following define if memory references can have a segment }
+{ override                                                            }
+
+{ define RefsHaveSegment}
+
+Interface
+
+Uses
+  cpubase,aasmcpu,AOptBase;
+
+Type
+
+{ type of a normal instruction }
+  TInstr = Taicpu;
+  PInstr = ^TInstr;
+
+{ ************************************************************************* }
+{ **************************** TCondRegs ********************************** }
+{ ************************************************************************* }
+{ Info about the conditional registers                                      }
+  TCondRegs = Object
+    Constructor Init;
+    Destructor Done;
+  End;
+
+{ ************************************************************************* }
+{ **************************** TAoptBaseCpu ******************************* }
+{ ************************************************************************* }
+
+  TAoptBaseCpu = class(TAoptBase)
+  End;
+
+
+{ ************************************************************************* }
+{ ******************************* Constants ******************************* }
+{ ************************************************************************* }
+Const
+
+{ the maximum number of things (registers, memory, ...) a single instruction }
+{ changes                                                                    }
+
+  MaxCh = 3;
+
+{ the maximum number of operands an instruction has }
+
+  MaxOps = 3;
+
+{Oper index of operand that contains the source (reference) with a load }
+{instruction                                                            }
+
+  LoadSrc = 0;
+
+{Oper index of operand that contains the destination (register) with a load }
+{instruction                                                                }
+
+  LoadDst = 1;
+
+{Oper index of operand that contains the source (register) with a store }
+{instruction                                                            }
+
+  StoreSrc = 0;
+
+{Oper index of operand that contains the destination (reference) with a load }
+{instruction                                                                 }
+
+  StoreDst = 1;
+
+  aopt_uncondjmp = A_BA;
+  aopt_condjmp = A_Bxx;
+
+Implementation
+
+{ ************************************************************************* }
+{ **************************** TCondRegs ********************************** }
+{ ************************************************************************* }
+Constructor TCondRegs.init;
+Begin
+End;
+
+Destructor TCondRegs.Done; {$ifdef inl} inline; {$endif inl}
+Begin
+End;
+
+End.
+
+{
+ $Log$
+ Revision 1.1  2004-10-30 15:21:38  florian
+   * fixed generic optimizer
+   * enabled generic optimizer for sparc
+
+ Revision 1.6  2004/06/20 08:55:31  florian
+   * logs truncated
+
+}

+ 43 - 0
compiler/sparc/aoptcpud.pas

@@ -0,0 +1,43 @@
+{
+    $Id$
+    Copyright (c) 1998-2004 by Jonas Maebe, member of the Free Pascal
+    Development Team
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+Unit aoptcpud;
+
+{$i fpcdefs.inc}
+
+  interface
+
+    uses
+      aoptda;
+
+    type
+      TAOptDFACpu = class(TAOptDFA)
+      end;
+
+  implementation
+
+end.
+{
+  $Log$
+  Revision 1.1  2004-10-30 15:21:38  florian
+    * fixed generic optimizer
+    * enabled generic optimizer for sparc
+}

+ 17 - 1
compiler/sparc/cpubase.pas

@@ -393,6 +393,7 @@ uses
                                   Helpers
                                   Helpers
 *****************************************************************************}
 *****************************************************************************}
 
 
+    function RefsEqual(Const r1,r2: TReference) : Boolean;
     function  is_calljmp(o:tasmop):boolean;
     function  is_calljmp(o:tasmop):boolean;
 
 
     procedure inverse_flags(var f: TResFlags);
     procedure inverse_flags(var f: TResFlags);
@@ -427,6 +428,17 @@ implementation
                                   Helpers
                                   Helpers
 *****************************************************************************}
 *****************************************************************************}
 
 
+    function RefsEqual(Const r1,r2: TReference) : Boolean;
+      begin
+        RefsEqual := (r1.Offset=r2.Offset) and
+                     (r1.Base=r2.Base) and
+                     (r1.Index=r2.Index) and
+                     (r1.symbol=r2.symbol) and
+                     (r1.relsymbol=r2.relsymbol) and
+                     (r1.refaddr=r2.refaddr);
+      end;
+
+
     function is_calljmp(o:tasmop):boolean;
     function is_calljmp(o:tasmop):boolean;
       const
       const
         CallJmpOp=[A_JMPL..A_CBccc];
         CallJmpOp=[A_JMPL..A_CBccc];
@@ -509,7 +521,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.73  2004-10-25 17:04:51  peter
+  Revision 1.74  2004-10-30 15:21:38  florian
+    * fixed generic optimizer
+    * enabled generic optimizer for sparc
+
+  Revision 1.73  2004/10/25 17:04:51  peter
     * add saved_standard_registers
     * add saved_standard_registers
 
 
   Revision 1.72  2004/09/21 17:25:13  peter
   Revision 1.72  2004/09/21 17:25:13  peter

+ 11 - 3
compiler/sparc/cputarg.pas

@@ -22,7 +22,7 @@
 }
 }
 unit cputarg;
 unit cputarg;
 
 
-{$INCLUDE fpcdefs.inc}
+{$i fpcdefs.inc}
 
 
 interface
 interface
 
 
@@ -32,6 +32,10 @@ implementation
     uses
     uses
       systems { prevent a syntax error when nothing is included }
       systems { prevent a syntax error when nothing is included }
 
 
+{$ifndef NOOPT}
+      ,aoptcpu
+{$endif NOOPT}
+
 {**************************************
 {**************************************
              Targets
              Targets
 **************************************}
 **************************************}
@@ -48,12 +52,16 @@ implementation
 **************************************}
 **************************************}
 
 
       ,CpuGas
       ,CpuGas
+
       ;
       ;
 
 
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.5  2004-06-20 08:55:32  florian
-    * logs truncated
+  Revision 1.6  2004-10-30 15:21:38  florian
+    * fixed generic optimizer
+    * enabled generic optimizer for sparc
 
 
+  Revision 1.5  2004/06/20 08:55:32  florian
+    * logs truncated
 }
 }

Some files were not shown because too many files changed in this diff