فهرست منبع

* fixed generic optimizer
* enabled generic optimizer for sparc

florian 21 سال پیش
والد
کامیت
e04b172854

+ 197 - 183
compiler/aopt.pas

@@ -1,6 +1,6 @@
 {
     $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
 
     This unit contains the interface routines between the code generator
@@ -24,224 +24,238 @@
 }
 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
-        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
-            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
-                      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
+                          UsedRegs := UsedRegs - [tai_regalloc(p).Reg];
                           hp1 := p;
                           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;
                           If hp2 <> nil Then
                             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;
-        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}
 
 {
  $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;
 
-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
-      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);
+      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
-       (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
-             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);
-    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$
-  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
 
 }

+ 150 - 137
compiler/aoptda.pas

@@ -24,164 +24,177 @@
 }
 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
-      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
-          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
-                      { 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
-                          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
+                      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
-                  Else
+                  Else if IsLoadConstReg(p) Then
                     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
-              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;
 
-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.
 
 {
   $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
 
   Revision 1.7  2004/01/31 17:45:16  peter
     * Change several $ifdef i386 to x86
     * Change several OS_32 to OS_INT/OS_ADDR
-
 }

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1044 - 743
compiler/aoptobj.pas


+ 7 - 8
compiler/fpcdefs.inc

@@ -24,7 +24,7 @@
       {$ifndef USEOPT}
         {$define NOOPT}
       {$endif}
-      
+
       { 1.0.x generates broken code for sysutils }
       {$ifndef FORCE_SYSUTILS}
         {$undef USE_SYSUTILS}
@@ -37,7 +37,7 @@
        {$undef USE_SYSUTILS}
      {$endif}	
   {$endif}
-   
+
   {$define FPCPROCVAR}
   {$define USEEXCEPT}
 
@@ -58,18 +58,15 @@
   {$define cpu64bit}
   {$define cpuextended}
   {$define cpufloat128}
-  {$define noopt}
   {$define cputargethasfixedstack}
 {$endif x86_64}
 
 {$ifdef alpha}
   {$define cpu64bit}
-  {$define noopt}
 {$endif alpha}
 
 {$ifdef sparc}
   {$define cpuflags}
-  {$define noopt}
   {$define cputargethasfixedstack}
   {$define cpurequiresproperalignment}
 {$endif sparc}
@@ -84,19 +81,21 @@
   {$define cpuflags}
   {$define cpuneedsdiv32helper}
   {$define cputargethasfixedstack}
-  {$define noopt}
   {$define cpurequiresproperalignment}
 {$endif arm}
 
 {$ifdef m68k}
   {$define cpuflags}
   {$define cpufpemu}
-  {$define noopt}
 {$endif m68k}
 
 {
   $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
 
   Revision 1.43  2004/10/10 14:57:29  jonas

+ 6 - 3
compiler/psub.pas

@@ -24,7 +24,6 @@ unit psub;
 
 {$i fpcdefs.inc}
 
-
 interface
 
     uses
@@ -105,7 +104,7 @@ implementation
          {$ifdef i386}
            ,aopt386
          {$else i386}
-           ,aoptcpu
+           ,aopt
          {$endif i386}
        {$endif}
        ;
@@ -1404,7 +1403,11 @@ implementation
 end.
 {
   $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
 
   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;
         n,a,c : Tsuperregister;
         colourednodes : Tsuperregisterset;
-                adj_colours:set of 0..255;
+        adj_colours:set of 0..255;
         found : boolean;
 
     begin
@@ -1994,7 +1994,11 @@ unit rgobj;
 end.
 {
   $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
 
   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);
       begin
          inherited create(op);
+         is_jmp:=op in [A_BA,A_Bxx];
          condition:=cond;
          ops:=1;
          loadsymbol(0,_op1,0);
@@ -217,6 +218,7 @@ implementation
     constructor taicpu.op_sym(op : tasmop;_op1 : tasmsymbol);
       begin
          inherited create(op);
+         is_jmp:=op in [A_BA,A_Bxx];
          ops:=1;
          loadsymbol(0,_op1,0);
       end;
@@ -311,7 +313,11 @@ begin
 end.
 {
   $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
 
   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
 *****************************************************************************}
 
+    function RefsEqual(Const r1,r2: TReference) : Boolean;
     function  is_calljmp(o:tasmop):boolean;
 
     procedure inverse_flags(var f: TResFlags);
@@ -427,6 +428,17 @@ implementation
                                   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;
       const
         CallJmpOp=[A_JMPL..A_CBccc];
@@ -509,7 +521,11 @@ implementation
 end.
 {
   $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
 
   Revision 1.72  2004/09/21 17:25:13  peter

+ 11 - 3
compiler/sparc/cputarg.pas

@@ -22,7 +22,7 @@
 }
 unit cputarg;
 
-{$INCLUDE fpcdefs.inc}
+{$i fpcdefs.inc}
 
 interface
 
@@ -32,6 +32,10 @@ implementation
     uses
       systems { prevent a syntax error when nothing is included }
 
+{$ifndef NOOPT}
+      ,aoptcpu
+{$endif NOOPT}
+
 {**************************************
              Targets
 **************************************}
@@ -48,12 +52,16 @@ implementation
 **************************************}
 
       ,CpuGas
+
       ;
 
 end.
 {
   $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
 }

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است