* fixed generic optimizer

* enabled generic optimizer for sparc
This commit is contained in:
florian 2004-10-30 15:21:37 +00:00
parent 86f78c7300
commit e04b172854
13 changed files with 1857 additions and 1268 deletions

View File

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

View File

@ -23,23 +23,29 @@
} }
unit aoptbase; unit aoptbase;
Interface {$i fpcdefs.inc}
uses aasmbase,aasmcpu,aasmtai, interface
cpubase;
{ the number of tai objects processed by an optimizer object since the last } uses
{ time a register was modified } aasmbase,aasmcpu,aasmtai,
Type TInstrSinceLastMod = Array[LoGPReg..HiGPReg] of byte; cpubase,
cgbase;
{ the TAopBase object implements the basic methods that most other } Type
{ assembler optimizer objects require } { the number of tai objects processed by an optimizer object since the last
Type time a register was modified }
TAoptBase = Object { 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 } { processor independent methods }
constructor init; constructor create;
destructor done; destructor destroy;override;
{ returns true if register Reg is used by instruction p1 } { returns true if register Reg is used by instruction p1 }
Function RegInInstruction(Reg: TRegister; p1: tai): Boolean; Function RegInInstruction(Reg: TRegister; p1: tai): Boolean;
{ returns true if register Reg occurs in operand op } { returns true if register Reg occurs in operand op }
@ -81,81 +87,71 @@ Type
{ create a paicpu Object that loads the contents of reg1 into reg2 } { create a paicpu Object that loads the contents of reg1 into reg2 }
Function a_load_reg_reg(reg1, reg2: TRegister): taicpu; Virtual; Function a_load_reg_reg(reg1, reg2: TRegister): taicpu; Virtual;
end; end;
Function RefsEqual(Const R1, R2: TReference): Boolean;
Implementation implementation
uses globals, aoptcpub, cpuinfo; uses
globtype,globals, aoptcpub, cpuinfo;
Function RefsEqual(Const R1, R2: TReference): Boolean; constructor taoptbase.create;
Begin begin
RefsEqual := (R1.Offset+R1.OffsetFixup = R2.Offset+R2.OffsetFixup) inherited create;
And (R1.Base = R2.Base) end;
{$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; destructor taoptbase.destroy;
begin begin
end; inherited destroy;
end;
destructor taoptbase.done;
begin
end;
Function TAOptBase.RegInInstruction(Reg: TRegister; p1: tai): Boolean; Function TAOptBase.RegInInstruction(Reg: TRegister; p1: tai): Boolean;
Var Count: AWord; Var Count: AWord;
TmpResult: Boolean; TmpResult: Boolean;
Begin Begin
TmpResult := False; TmpResult := False;
Count := 0; Count := 0;
If (p1.typ = ait_instruction) Then If (p1.typ = ait_instruction) Then
Repeat Repeat
TmpResult := RegInOp(Reg, PInstr(p1)^.oper[Count]); TmpResult := RegInOp(Reg, PInstr(p1)^.oper[Count]^);
Inc(Count) Inc(Count)
Until (Count = MaxOps) or TmpResult; Until (Count = MaxOps) or TmpResult;
RegInInstruction := TmpResult RegInInstruction := TmpResult
End; End;
Function TAOptBase.RegInOp(Reg: TRegister; const op: toper): Boolean; Function TAOptBase.RegInOp(Reg: TRegister; const op: toper): Boolean;
Begin Begin
Case op.typ Of Case op.typ Of
Top_Reg: RegInOp := Reg = op.reg; Top_Reg: RegInOp := Reg = op.reg;
Top_Ref: RegInOp := RegInRef(Reg, op.ref^) Top_Ref: RegInOp := RegInRef(Reg, op.ref^)
Else RegInOp := False Else RegInOp := False
End End
End; End;
Function TAOptBase.RegInRef(Reg: TRegister; Const Ref: TReference): Boolean; Function TAOptBase.RegInRef(Reg: TRegister; Const Ref: TReference): Boolean;
Begin Begin
Reg := RegMaxSize(Reg); Reg := RegMaxSize(Reg);
RegInRef := (Ref.Base = Reg) RegInRef := (Ref.Base = Reg)
{$ifdef RefsHaveIndexReg} {$ifdef RefsHaveIndexReg}
Or (Ref.Index = Reg) Or (Ref.Index = Reg)
{$endif RefsHaveIndexReg} {$endif RefsHaveIndexReg}
End; End;
Function TAOptBase.GetNextInstruction(Current: tai; Var Next: tai): Boolean; Function TAOptBase.GetNextInstruction(Current: tai; Var Next: tai): Boolean;
Begin Begin
Repeat Repeat
Current := tai(Current.Next); Current := tai(Current.Next);
While Assigned(Current) And While Assigned(Current) And
((Current.typ In SkipInstr) or ((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 ((Current.typ = ait_label) And
Not(Tai_Label(Current).l.is_used))) Do Not(Tai_Label(Current).l.is_used))) Do
Current := tai(Current.Next); Current := tai(Current.Next);
@ -182,10 +178,10 @@ Begin
Next := Nil; Next := Nil;
GetNextInstruction := False; GetNextInstruction := False;
End; End;
End; End;
Function TAOptBase.GetLastInstruction(Current: tai; Var Last: tai): Boolean; Function TAOptBase.GetLastInstruction(Current: tai; Var Last: tai): Boolean;
Begin Begin
Repeat Repeat
Current := Tai(Current.previous); Current := Tai(Current.previous);
While Assigned(Current) And While Assigned(Current) And
@ -223,46 +219,50 @@ Begin
Last := Current; Last := Current;
GetLastInstruction := True; GetLastInstruction := True;
End; End;
End; End;
{ ******************* Processor dependent stuff *************************** } { ******************* Processor dependent stuff *************************** }
Function TAOptBase.RegMaxSize(Reg: TRegister): TRegister; Function TAOptBase.RegMaxSize(Reg: TRegister): TRegister;
Begin Begin
RegMaxSize := Reg RegMaxSize := Reg
End; End;
Function TAOptBase.RegsSameSize(Reg1, Reg2: TRegister): Boolean; Function TAOptBase.RegsSameSize(Reg1, Reg2: TRegister): Boolean;
Begin Begin
RegsSameSize := True RegsSameSize := True
End; End;
Function TAOptBase.IsLoadMemReg(p: tai): Boolean; Function TAOptBase.IsLoadMemReg(p: tai): Boolean;
Begin Begin
Abstract Abstract
End; End;
Function TAOptBase.IsLoadConstReg(p: tai): Boolean; Function TAOptBase.IsLoadConstReg(p: tai): Boolean;
Begin Begin
Abstract Abstract
End; End;
Function TAOptBase.IsStoreRegMem(p: tai): Boolean; Function TAOptBase.IsStoreRegMem(p: tai): Boolean;
Begin Begin
Abstract Abstract
End; End;
Function TAoptBase.a_load_reg_reg(reg1, reg2: TRegister): taicpu; Function TAoptBase.a_load_reg_reg(reg1, reg2: TRegister): taicpu;
Begin Begin
Abstract Abstract
End; End;
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
} }

View File

@ -24,12 +24,17 @@
} }
Unit aoptda; Unit aoptda;
Interface {$i fpcdefs.inc}
uses aasm, cpubase, aoptcpub, aoptbase, aoptcpu; Interface
Type uses
TAOptDFA = Object(TAoptCpu) cpubase,cgbase,
aasmbase,aasmtai,aasmcpu,
aoptcpub, aoptbase;
Type
TAOptDFA = class
{ uses the same constructor as TAoptCpu = constructor from TAoptObj } { uses the same constructor as TAoptCpu = constructor from TAoptObj }
{ gathers the information regarding the contents of every register } { gathers the information regarding the contents of every register }
@ -44,56 +49,58 @@ Type
InstrSinceLastMod: TInstrSinceLastMod; InstrSinceLastMod: TInstrSinceLastMod;
{ convert a TInsChange value into the corresponding register } { convert a TInsChange value into the corresponding register }
Function TCh2Reg(Ch: TInsChange): TRegister; Virtual; //!!!!!!!!!! Function TCh2Reg(Ch: TInsChange): TRegister; Virtual;
{ returns whether the instruction P reads from register Reg } { returns whether the instruction P reads from register Reg }
Function RegReadByInstr(Reg: TRegister; p: Pai): Boolean; Virtual; Function RegReadByInstr(Reg: TRegister; p: tai): Boolean; Virtual;
End; End;
Implementation Implementation
uses globals, aoptobj; uses
globals, aoptobj;
Procedure TAOptDFA.DoDFA; Procedure TAOptDFA.DoDFA;
{ Analyzes the Data Flow of an assembler list. Analyses the reg contents } { Analyzes the Data Flow of an assembler list. Analyses the reg contents }
{ for the instructions between blockstart and blockend. Returns the last pai } { for the instructions between blockstart and blockend. Returns the last pai }
{ which has been processed } { which has been processed }
Var Var
CurProp: PPaiProp; CurProp: TPaiProp;
UsedRegs: TUsedRegs; UsedRegs: TUsedRegs;
p, hp, NewBlockStart : Pai; p, hp, NewBlockStart : tai;
TmpReg: TRegister; TmpReg: TRegister;
Begin Begin
{!!!!!!!!!!
p := BlockStart; p := BlockStart;
UsedRegs.init; UsedRegs.Create;
UsedRegs.Update(p); UsedRegs.Update(p);
NewBlockStart := SkipHead(p); NewBlockStart := SkipHead(p);
{ done implicitely by the constructor { done implicitely by the constructor
FillChar(InstrSinceLastMod, SizeOf(InstrSinceLastMod), 0); } FillChar(InstrSinceLastMod, SizeOf(InstrSinceLastMod), 0); }
While (P <> BlockEnd) Do While (P <> BlockEnd) Do
Begin Begin
CurProp := New(PPaiProp, init); CurProp:=TPaiProp.Create;
If (p <> NewBlockStart) Then If (p <> NewBlockStart) Then
Begin Begin
GetLastInstruction(p, hp); GetLastInstruction(p, hp);
CurProp^.Regs := PPaiProp(hp^.OptInfo)^.Regs; CurProp.Regs := TPaiProp(hp.OptInfo).Regs;
{ !!!!!!!!!!!! } { !!!!!!!!!!!! }
{$ifdef x86} {$ifdef x86}
CurProp^.CondRegs.Flags := CurProp.CondRegs.Flags :=
PPaiProp(hp^.OptInfo)^.CondRegs.Flags; TPaiProp(hp.OptInfo).CondRegs.Flags;
{$endif} {$endif}
End; End;
CurProp^.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs); CurProp.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs);
UsedRegs.Update(Pai(p^.Next)); UsedRegs.Update(tai(p.Next));
PPaiProp(p^.OptInfo) := CurProp; TPaiProp(p.OptInfo) := CurProp;
For TmpReg := LoGPReg To HiGPReg Do For TmpReg := LoGPReg To HiGPReg Do
Inc(InstrSinceLastMod[TmpReg]); Inc(InstrSinceLastMod[TmpReg]);
Case p^.typ Of Case p^.typ Of
ait_label: ait_label:
If (Pai_label(p)^.l^.is_used) Then If (Pai_label(p)^.l^.is_used) Then
CurProp^.DestroyAllRegs(InstrSinceLastMod); CurProp^.DestroyAllRegs(InstrSinceLastMod);
{$ifdef GDB} {$ifdef GDB}
ait_stabs, ait_stabn, ait_stab_function_name:; ait_stabs, ait_stabn, ait_stab_function_name:;
{$endif GDB} {$endif GDB}
ait_instruction: ait_instruction:
if not(PInstr(p)^.is_jmp) then if not(PInstr(p)^.is_jmp) then
begin begin
@ -150,38 +157,44 @@ Begin
End; End;
Else CurProp^.DestroyAllRegs(InstrSinceLastMod); Else CurProp^.DestroyAllRegs(InstrSinceLastMod);
End; End;
{ Inc(InstrCnt);} { Inc(InstrCnt);}
GetNextInstruction(p, p); GetNextInstruction(p, p);
End; End;
End; }
End;
Procedure TAoptDFA.CpuDFA(p: PInstr); Procedure TAoptDFA.CpuDFA(p: PInstr);
Begin Begin
Abstract; Abstract;
End; End;
Function TAOptDFA.TCh2Reg(Ch: TInsChange): TRegister; {!!!!!!!
Begin Function TAOptDFA.TCh2Reg(Ch: TInsChange): TRegister;
Begin
TCh2Reg:=R_NO; TCh2Reg:=R_NO;
Abstract; Abstract;
End; End;
}
Function TAOptDFA.RegReadByInstr(Reg: TRegister; p: Pai): Boolean; Function TAOptDFA.RegReadByInstr(Reg: TRegister; p: tai): Boolean;
Begin Begin
RegReadByInstr:=false; RegReadByInstr:=false;
Abstract; Abstract;
End; 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 Load Diff

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
compiler/sparc/aoptcpub.pas Normal file
View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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 Revision 1.6 2004-10-30 15:21:38 florian
* logs truncated * fixed generic optimizer
* enabled generic optimizer for sparc
Revision 1.5 2004/06/20 08:55:32 florian
* logs truncated
} }