* 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,224 +24,238 @@
} }
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;
{ _AsmL is the PAasmOutpout list that has to be optimized } Type
Constructor Init(_AsmL: PAasmOutput); TAsmOptimizer = class(TAoptObj)
{ call the necessary optimizer procedures } { _AsmL is the PAasmOutpout list that has to be optimized }
Procedure Optimize; Constructor create(_AsmL: taasmoutput);
Destructor Done;
private { call the necessary optimizer procedures }
Procedure Optimize;
Destructor destroy;override;
Function FindLoHiLabels: Pai; private
Procedure BuildLabelTableAndFixRegAlloc; 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.create(_AsmL: taasmoutput);
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;
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
Begin Begin
GetMem(LabelTable, LabelDif*SizeOf(TLabelTableItem)); inherited create(_asml,nil,nil,nil);
FillChar(LabelTable^, LabelDif*SizeOf(TLabelTableItem), 0); {setup labeltable, always necessary}
p := BlockStart; New(LabelInfo);
While (P <> BlockEnd) Do LabelInfo^.LowLabel := High(AWord);
LabelInfo^.HighLabel := 0;
LabelInfo^.LabelDif := 0;
LabelInfo^.LabelTable:=nil;
End;
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
LabelFound := False;
P := BlockStart;
With LabelInfo^ Do
Begin Begin
Case p^.typ Of While Assigned(P) And
ait_Label: ((P.typ <> Ait_Marker) Or
If Pai_Label(p)^.l^.is_used Then (tai_Marker(P).Kind <> AsmBlockStart)) Do
LabelTable^[Pai_Label(p)^.l^.labelnr-LowLabel].PaiObj := p; Begin
ait_regAlloc: If (p.typ = ait_label) Then
begin If (tai_Label(p).l.is_used) Then
if PairegAlloc(p)^.Allocation then
Begin Begin
If Not(PaiRegAlloc(p)^.Reg in UsedRegs) Then LabelFound := True;
UsedRegs := UsedRegs + [PaiRegAlloc(p)^.Reg] If (tai_Label(p).l.labelnr < LowLabel) Then
Else 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 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; hp1 := p;
hp2 := nil; hp2 := nil;
While GetLastInstruction(hp1, hp1) And While Not(FindRegAlloc(tai_regalloc(p).Reg, tai(hp1.Next))) And
Not(RegInInstruction(PaiRegAlloc(p)^.Reg, hp1)) Do 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)); hp1 := tai(p.previous);
InsertLLItem(Pai(hp2^.previous), hp2, hp1); AsmL.Remove(p);
End; InsertLLItem(hp2, tai(hp2.Next), p);
End; p := hp1;
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;
End End
};
End End
End End
End End;
End; P := tai(p.Next);
P := Pai(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 := tai(P.Next)
P := Pai(P^.Next) End
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;
End;
Destructor TAsmOptimizer.Done;
Begin
Dispose(LabelInfo)
End;
procedure Optimize(AsmL:Paasmoutput);
var Procedure TAsmOptimizer.Optimize;
p : PAsmOptimizer; 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.Destroy;
Begin
Dispose(LabelInfo)
End;
procedure Optimize(AsmL:taasmoutput);
var
p : TAsmOptimizer;
begin
p:=casmoptimizer.Create(AsmL);
p.Optimize;
p.free
end;
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,246 +23,246 @@
} }
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 }
{ processor independent methods } TInstrSinceLastMod = Array[tregistertype] of pbyte;
constructor init; { the TAopBase object implements the basic methods that most other }
destructor done; { assembler optimizer objects require }
{ returns true if register Reg is used by instruction p1 } Type
Function RegInInstruction(Reg: TRegister; p1: tai): Boolean; TAoptBase = class
{ returns true if register Reg occurs in operand op } { processor independent methods }
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 } constructor create;
{Function RefsEqual(Const R1, R2: TReference): Boolean;} 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;
{ gets the next tai object after current that contains info relevant } { returns true if the references are completely equal }
{ to the optimizer in p1. If there is none, it returns false and } {Function RefsEqual(Const R1, R2: TReference): Boolean;}
{ sets p1 to nil }
Function GetNextInstruction(Current: tai; Var Next: tai): Boolean; { gets the next tai object after current that contains info relevant }
{ gets the previous tai object after current that contains info } { to the optimizer in p1. If there is none, it returns false and }
{ relevant to the optimizer in last. If there is none, it retuns } { sets p1 to nil }
{ false and sets last to nil } Function GetNextInstruction(Current: tai; Var Next: tai): Boolean;
Function GetLastInstruction(Current: tai; Var Last: 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 } { processor dependent methods }
{ returns the maximum width component of Reg. Only has to be } { returns the maximum width component of Reg. Only has to be }
{ overridden for the 80x86 (afaik) } { overridden for the 80x86 (afaik) }
Function RegMaxSize(Reg: TRegister): TRegister; Virtual; Function RegMaxSize(Reg: TRegister): TRegister; Virtual;
{ returns true if Reg1 and Reg2 are of the samae width. Only has to } { returns true if Reg1 and Reg2 are of the samae width. Only has to }
{ overridden for the 80x86 (afaik) } { overridden for the 80x86 (afaik) }
Function RegsSameSize(Reg1, Reg2: TRegister): Boolean; Virtual; Function RegsSameSize(Reg1, Reg2: TRegister): Boolean; Virtual;
{ returns whether P is a load instruction (load contents from a } { returns whether P is a load instruction (load contents from a }
{ memory location or (register) variable into a register) } { memory location or (register) variable into a register) }
Function IsLoadMemReg(p: tai): Boolean; Virtual; Function IsLoadMemReg(p: tai): Boolean; Virtual;
{ returns whether P is a load constant instruction (load a constant } { returns whether P is a load constant instruction (load a constant }
{ into a register) } { into a register) }
Function IsLoadConstReg(p: tai): Boolean; Virtual; Function IsLoadConstReg(p: tai): Boolean; Virtual;
{ returns whether P is a store instruction (store contents from a } { returns whether P is a store instruction (store contents from a }
{ register to a memory location or to a (register) variable) } { register to a memory location or to a (register) variable) }
Function IsStoreRegMem(p: tai): Boolean; Virtual; Function IsStoreRegMem(p: tai): Boolean; Virtual;
{ 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;
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; Function TAOptBase.RegInInstruction(Reg: TRegister; p1: tai): Boolean;
Begin Var Count: AWord;
Case op.typ Of TmpResult: Boolean;
Top_Reg: RegInOp := Reg = op.reg; Begin
Top_Ref: RegInOp := RegInRef(Reg, op.ref^) TmpResult := False;
Else RegInOp := False Count := 0;
End If (p1.typ = ait_instruction) Then
End; Repeat
TmpResult := RegInOp(Reg, PInstr(p1)^.oper[Count]^);
Inc(Count)
Until (Count = MaxOps) or TmpResult;
RegInInstruction := TmpResult
End;
Function TAOptBase.RegInRef(Reg: TRegister; Const Ref: TReference): Boolean; Function TAOptBase.RegInOp(Reg: TRegister; const op: toper): Boolean;
Begin Begin
Reg := RegMaxSize(Reg); Case op.typ Of
RegInRef := (Ref.Base = Reg) Top_Reg: RegInOp := Reg = op.reg;
{$ifdef RefsHaveIndexReg} Top_Ref: RegInOp := RegInRef(Reg, op.ref^)
Or (Ref.Index = Reg) Else RegInOp := False
{$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);
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
((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 End
Else End;
Begin
Last := Current;
GetLastInstruction := True;
End;
End;
{ ******************* Processor dependent stuff *************************** } 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.RegMaxSize(Reg: TRegister): TRegister; Function TAOptBase.GetNextInstruction(Current: tai; Var Next: tai): Boolean;
Begin Begin
RegMaxSize := Reg Repeat
End; 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
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.RegsSameSize(Reg1, Reg2: TRegister): Boolean; Function TAOptBase.GetLastInstruction(Current: tai; Var Last: tai): Boolean;
Begin Begin
RegsSameSize := True Repeat
End; 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
((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;
Function TAOptBase.IsLoadMemReg(p: tai): Boolean;
Begin
Abstract
End;
Function TAOptBase.IsLoadConstReg(p: tai): Boolean; { ******************* Processor dependent stuff *************************** }
Begin
Abstract
End;
Function TAOptBase.IsStoreRegMem(p: tai): Boolean; Function TAOptBase.RegMaxSize(Reg: TRegister): TRegister;
Begin Begin
Abstract RegMaxSize := Reg
End; End;
Function TAoptBase.a_load_reg_reg(reg1, reg2: TRegister): taicpu; Function TAOptBase.RegsSameSize(Reg1, Reg2: TRegister): Boolean;
Begin Begin
Abstract RegsSameSize := True
End; End;
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
} }

View File

@ -24,164 +24,177 @@
} }
Unit aoptda; Unit aoptda;
Interface {$i fpcdefs.inc}
uses aasm, cpubase, aoptcpub, aoptbase, aoptcpu; Interface
Type uses
TAOptDFA = Object(TAoptCpu) cpubase,cgbase,
{ uses the same constructor as TAoptCpu = constructor from TAoptObj } aasmbase,aasmtai,aasmcpu,
aoptcpub, aoptbase;
{ gathers the information regarding the contents of every register } Type
{ at the end of every instruction } TAOptDFA = class
Procedure DoDFA; { uses the same constructor as TAoptCpu = constructor from TAoptObj }
{ handles the processor dependent dataflow analizing } { gathers the information regarding the contents of every register }
Procedure CpuDFA(p: PInstr); Virtual; { at the end of every instruction }
Procedure DoDFA;
{ How many instructions are between the current instruction and the } { handles the processor dependent dataflow analizing }
{ last one that modified the register } Procedure CpuDFA(p: PInstr); Virtual;
InstrSinceLastMod: TInstrSinceLastMod;
{ convert a TInsChange value into the corresponding register } { How many instructions are between the current instruction and the }
Function TCh2Reg(Ch: TInsChange): TRegister; Virtual; { last one that modified the register }
{ returns whether the instruction P reads from register Reg } InstrSinceLastMod: TInstrSinceLastMod;
Function RegReadByInstr(Reg: TRegister; p: Pai): Boolean; Virtual;
End;
Implementation { 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;
uses globals, aoptobj; Implementation
Procedure TAOptDFA.DoDFA; uses
{ Analyzes the Data Flow of an assembler list. Analyses the reg contents } globals, aoptobj;
{ for the instructions between blockstart and blockend. Returns the last pai }
{ which has been processed } Procedure TAOptDFA.DoDFA;
Var { Analyzes the Data Flow of an assembler list. Analyses the reg contents }
CurProp: PPaiProp; { for the instructions between blockstart and blockend. Returns the last pai }
UsedRegs: TUsedRegs; { which has been processed }
p, hp, NewBlockStart : Pai; Var
TmpReg: TRegister; CurProp: TPaiProp;
Begin UsedRegs: TUsedRegs;
p := BlockStart; p, hp, NewBlockStart : tai;
UsedRegs.init; TmpReg: TRegister;
UsedRegs.Update(p);
NewBlockStart := SkipHead(p);
{ done implicitely by the constructor
FillChar(InstrSinceLastMod, SizeOf(InstrSinceLastMod), 0); }
While (P <> BlockEnd) Do
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:=TPaiProp.Create;
CurProp^.Regs := PPaiProp(hp^.OptInfo)^.Regs; If (p <> NewBlockStart) Then
{ !!!!!!!!!!!! } Begin
{$ifdef x86} GetLastInstruction(p, hp);
CurProp^.CondRegs.Flags := CurProp.Regs := TPaiProp(hp.OptInfo).Regs;
PPaiProp(hp^.OptInfo)^.CondRegs.Flags; { !!!!!!!!!!!! }
{$endif} {$ifdef x86}
End; CurProp.CondRegs.Flags :=
CurProp^.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs); TPaiProp(hp.OptInfo).CondRegs.Flags;
UsedRegs.Update(Pai(p^.Next)); {$endif}
PPaiProp(p^.OptInfo) := CurProp; End;
For TmpReg := LoGPReg To HiGPReg Do CurProp.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs);
Inc(InstrSinceLastMod[TmpReg]); UsedRegs.Update(tai(p.Next));
Case p^.typ Of TPaiProp(p.OptInfo) := CurProp;
ait_label: For TmpReg := LoGPReg To HiGPReg Do
If (Pai_label(p)^.l^.is_used) Then Inc(InstrSinceLastMod[TmpReg]);
CurProp^.DestroyAllRegs(InstrSinceLastMod); Case p^.typ Of
{$ifdef GDB} ait_label:
ait_stabs, ait_stabn, ait_stab_function_name:; If (Pai_label(p)^.l^.is_used) Then
{$endif GDB} CurProp^.DestroyAllRegs(InstrSinceLastMod);
ait_instruction: {$ifdef GDB}
if not(PInstr(p)^.is_jmp) then ait_stabs, ait_stabn, ait_stab_function_name:;
begin {$endif GDB}
If IsLoadMemReg(p) Then ait_instruction:
Begin if not(PInstr(p)^.is_jmp) then
CurProp^.ReadRef(PInstr(p)^.oper[LoadSrc].ref); begin
TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg); If IsLoadMemReg(p) Then
If RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^) And
(CurProp^.GetRegContentType(TmpReg) = Con_Ref) Then
Begin Begin
{ a load based on the value this register already } CurProp^.ReadRef(PInstr(p)^.oper[LoadSrc].ref);
{ contained } TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
If RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^) And
(CurProp^.GetRegContentType(TmpReg) = Con_Ref) Then
Begin
{ 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 if IsLoadConstReg(p) Then
Begin
TmpReg := RegMaxSize(PInstr(p)^.oper[LoadDst].reg);
With CurProp^.Regs[TmpReg] Do With CurProp^.Regs[TmpReg] Do
Begin Begin
CurProp^.IncWState(TmpReg); CurProp^.DestroyReg(TmpReg, InstrSinceLastMod);
{also store how many instructions are part of the } typ := Con_Const;
{ sequence in the first instruction's PPaiProp, so } StartMod := Pointer(PInstr(p)^.oper[LoadSrc].val);
{ 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 End
Else Else CpuDFA(Pinstr(p));
Begin End;
{ load of a register with a completely new value } Else CurProp^.DestroyAllRegs(InstrSinceLastMod);
CurProp^.DestroyReg(TmpReg, InstrSinceLastMod); End;
If Not(RegInRef(TmpReg, PInstr(p)^.oper[LoadSrc].ref^)) Then { Inc(InstrCnt);}
With CurProp^.Regs[TmpReg] Do GetNextInstruction(p, p);
Begin End;
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);
End
End
Else CpuDFA(Pinstr(p));
End;
Else CurProp^.DestroyAllRegs(InstrSinceLastMod);
End;
{ Inc(InstrCnt);}
GetNextInstruction(p, p);
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;
TCh2Reg:=R_NO; Begin
Abstract; TCh2Reg:=R_NO;
End; Abstract;
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

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

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

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

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