* 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$
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,67 +24,73 @@
}
Unit aopt;
{$i fpcdefs.inc}
Interface
Uses Aasmbase,aasmtai,aasmcpu, cobjects, aoptobj, aoptcpud, aoptcpub {aoptcs, aoptpeep} ;
Uses
aasmbase,aasmtai,aasmcpu,
aoptobj;
Type
PAsmOptimizer = ^TAsmOptimizer;
TAsmOptimizer = Object(TAoptObj)
TAsmOptimizer = class(TAoptObj)
{ _AsmL is the PAasmOutpout list that has to be optimized }
Constructor Init(_AsmL: PAasmOutput);
Constructor create(_AsmL: taasmoutput);
{ call the necessary optimizer procedures }
Procedure Optimize;
Destructor Done;
Destructor destroy;override;
private
Function FindLoHiLabels: Pai;
Function FindLoHiLabels: tai;
Procedure BuildLabelTableAndFixRegAlloc;
End;
procedure Optimize(AsmL:Paasmoutput);
var
casmoptimizer : class of tasmoptimizer;
procedure Optimize(AsmL:taasmoutput);
Implementation
uses cpuinfo, globtype, globals;
uses
cpuinfo, globtype, globals,
aoptda,aoptcpu,aoptcpud;
Constructor TAsmOptimizer.Init(_AsmL: PAasmOutput);
Constructor TAsmOptimizer.create(_AsmL: taasmoutput);
Begin
AsmL := _AsmL;
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;
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: Pai;
p: tai;
Begin
LabelFound := False;
P := BlockStart;
With LabelInfo^ Do
Begin
While Assigned(P) And
((P^.typ <> Ait_Marker) Or
(Pai_Marker(P)^.Kind <> AsmBlockStart)) Do
((P.typ <> Ait_Marker) Or
(tai_Marker(P).Kind <> AsmBlockStart)) Do
Begin
If (Pai(p)^.typ = ait_label) Then
If (Pai_Label(p)^.l^.is_used) Then
If (p.typ = ait_label) Then
If (tai_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
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;
@ -96,9 +102,9 @@ Begin
End;
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)" }
Var p, hp1, hp2: Pai;
Var p, hp1, hp2: tai;
UsedRegs: TRegSet;
Begin
UsedRegs := [];
@ -110,79 +116,82 @@ Begin
p := BlockStart;
While (P <> BlockEnd) Do
Begin
Case p^.typ Of
Case p.typ Of
ait_Label:
If Pai_Label(p)^.l^.is_used Then
LabelTable^[Pai_Label(p)^.l^.labelnr-LowLabel].PaiObj := p;
If tai_label(p).l.is_used Then
LabelTable^[tai_label(p).l.labelnr-LowLabel].PaiObj := p;
ait_regAlloc:
begin
if PairegAlloc(p)^.Allocation then
{!!!!!!!!!
if tai_regalloc(p).ratype=ra_alloc then
Begin
If Not(PaiRegAlloc(p)^.Reg in UsedRegs) Then
UsedRegs := UsedRegs + [PaiRegAlloc(p)^.Reg]
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(PaiRegAlloc(p)^.Reg, hp1)) Do
Not(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);
hp1:=tai_regalloc.DeAlloc(tai_regalloc(p).Reg,hp2);
InsertLLItem(tai(hp2.previous), hp2, hp1);
End;
End;
End
else
Begin
UsedRegs := UsedRegs - [PaiRegAlloc(p)^.Reg];
UsedRegs := UsedRegs - [tai_regalloc(p).Reg];
hp1 := p;
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
RegInInstruction(PaiRegAlloc(p)^.Reg, hp1) Do
RegInInstruction(tai_regalloc(p).Reg, hp1) Do
hp2 := hp1;
If hp2 <> nil Then
Begin
hp1 := Pai(p^.previous);
AsmL^.Remove(p);
InsertLLItem(hp2, Pai(hp2^.Next), p);
hp1 := tai(p.previous);
AsmL.Remove(p);
InsertLLItem(hp2, tai(hp2.Next), p);
p := hp1;
End
End
};
End
End
End;
P := Pai(p^.Next);
P := tai(p.Next);
While Assigned(p) And
(p^.typ in (SkipInstr - [ait_regalloc])) Do
P := Pai(P^.Next)
(p.typ in (SkipInstr - [ait_regalloc])) Do
P := tai(P.Next)
End
End;
Procedure TAsmOptimizer.Optimize;
Var HP: Pai;
DFA: PAOptDFACpu;
Var
HP: tai;
pass: longint;
Begin
BlockStart := Pai(AsmL^.First);
pass:=0;
BlockStart := tai(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 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
New(DFA,Init(AsmL,BlockStart,BlockEnd,LabelInfo));
// DFA:=TAOptDFACpu.Create(AsmL,BlockStart,BlockEnd,LabelInfo);
{ data flow analyzer }
DFA^.DoDFA;
DFA.DoDFA;
{ common subexpression elimination }
{ CSE;}
End;
@ -198,17 +207,17 @@ Begin
{ assembler block or nil}
BlockStart := BlockEnd;
While Assigned(BlockStart) And
(BlockStart^.typ = ait_Marker) And
(Pai_Marker(BlockStart)^.Kind = AsmBlockStart) Do
(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
(Pai_Marker(Blockstart)^.Kind <> AsmBlockEnd)) Do;
{ blockstart now contains a pai_marker(asmblockend) }
((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
(Pai_Marker(HP)^.Kind <> AsmBlockStart)
((HP.typ <> ait_Marker) Or
(tai_Marker(HP).Kind <> AsmBlockStart)
)
) Then
{skip the next assembler block }
@ -219,29 +228,34 @@ Begin
End;
End;
Destructor TAsmOptimizer.Done;
Destructor TAsmOptimizer.Destroy;
Begin
Dispose(LabelInfo)
End;
procedure Optimize(AsmL:Paasmoutput);
procedure Optimize(AsmL:taasmoutput);
var
p : PAsmOptimizer;
p : TAsmOptimizer;
begin
new(p,Init(AsmL));
p^.Optimize;
dispose(p,Done);
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
}

View File

@ -23,23 +23,29 @@
}
unit aoptbase;
Interface
{$i fpcdefs.inc}
uses aasmbase,aasmcpu,aasmtai,
cpubase;
interface
{ 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;
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 = Object
TAoptBase = class
{ processor independent methods }
constructor init;
destructor done;
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 }
@ -83,39 +89,24 @@ Type
end;
Function RefsEqual(Const R1, R2: TReference): Boolean;
implementation
Implementation
uses
globtype,globals, aoptcpub, cpuinfo;
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;
constructor taoptbase.create;
begin
inherited create;
end;
destructor taoptbase.done;
destructor taoptbase.destroy;
begin
inherited destroy;
end;
Function TAOptBase.RegInInstruction(Reg: TRegister; p1: tai): Boolean;
Var Count: AWord;
TmpResult: Boolean;
@ -124,7 +115,7 @@ Begin
Count := 0;
If (p1.typ = ait_instruction) Then
Repeat
TmpResult := RegInOp(Reg, PInstr(p1)^.oper[Count]);
TmpResult := RegInOp(Reg, PInstr(p1)^.oper[Count]^);
Inc(Count)
Until (Count = MaxOps) or TmpResult;
RegInInstruction := TmpResult
@ -156,6 +147,11 @@ Begin
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);
@ -258,11 +254,15 @@ Begin
Abstract
End;
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
}

View File

@ -24,12 +24,17 @@
}
Unit aoptda;
{$i fpcdefs.inc}
Interface
uses aasm, cpubase, aoptcpub, aoptbase, aoptcpu;
uses
cpubase,cgbase,
aasmbase,aasmtai,aasmcpu,
aoptcpub, aoptbase;
Type
TAOptDFA = Object(TAoptCpu)
TAOptDFA = class
{ uses the same constructor as TAoptCpu = constructor from TAoptObj }
{ gathers the information regarding the contents of every register }
@ -44,47 +49,49 @@ Type
InstrSinceLastMod: TInstrSinceLastMod;
{ 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 }
Function RegReadByInstr(Reg: TRegister; p: Pai): Boolean; Virtual;
Function RegReadByInstr(Reg: TRegister; p: tai): Boolean; Virtual;
End;
Implementation
uses globals, aoptobj;
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;
CurProp: TPaiProp;
UsedRegs: TUsedRegs;
p, hp, NewBlockStart : Pai;
p, hp, NewBlockStart : tai;
TmpReg: TRegister;
Begin
{!!!!!!!!!!
p := BlockStart;
UsedRegs.init;
UsedRegs.Create;
UsedRegs.Update(p);
NewBlockStart := SkipHead(p);
{ done implicitely by the constructor
FillChar(InstrSinceLastMod, SizeOf(InstrSinceLastMod), 0); }
While (P <> BlockEnd) Do
Begin
CurProp := New(PPaiProp, init);
CurProp:=TPaiProp.Create;
If (p <> NewBlockStart) Then
Begin
GetLastInstruction(p, hp);
CurProp^.Regs := PPaiProp(hp^.OptInfo)^.Regs;
CurProp.Regs := TPaiProp(hp.OptInfo).Regs;
{ !!!!!!!!!!!! }
{$ifdef x86}
CurProp^.CondRegs.Flags :=
PPaiProp(hp^.OptInfo)^.CondRegs.Flags;
CurProp.CondRegs.Flags :=
TPaiProp(hp.OptInfo).CondRegs.Flags;
{$endif}
End;
CurProp^.UsedRegs.InitWithValue(UsedRegs.GetUsedRegs);
UsedRegs.Update(Pai(p^.Next));
PPaiProp(p^.OptInfo) := CurProp;
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
@ -153,6 +160,7 @@ Begin
{ Inc(InstrCnt);}
GetNextInstruction(p, p);
End;
}
End;
Procedure TAoptDFA.CpuDFA(p: PInstr);
@ -160,13 +168,15 @@ Begin
Abstract;
End;
{!!!!!!!
Function TAOptDFA.TCh2Reg(Ch: TInsChange): TRegister;
Begin
TCh2Reg:=R_NO;
Abstract;
End;
}
Function TAOptDFA.RegReadByInstr(Reg: TRegister; p: Pai): Boolean;
Function TAOptDFA.RegReadByInstr(Reg: TRegister; p: tai): Boolean;
Begin
RegReadByInstr:=false;
Abstract;
@ -177,11 +187,14 @@ 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
}

View File

@ -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 processor independent assembler optimizer
@ -25,12 +25,19 @@
}
Unit AoptObj;
{$i fpcdefs.inc}
{ general, processor independent objects for use by the assembler optimizer }
Interface
uses aasmbase,aasmcpu,aasmtai,
cclasses, cpuinfo, cpubase, aoptbase, aoptcpub;
uses
globtype,
aasmbase,aasmcpu,aasmtai,
cclasses,
cgbase,
cpuinfo, cpubase,
aoptbase, aoptcpub, aoptda;
{ ************************************************************************* }
{ ********************************* Constants ***************************** }
@ -51,17 +58,20 @@ Type
{ ************************* Some general type definitions ***************** }
{ ************************************************************************* }
TRefCompare = Function(const r1, r2: TReference): Boolean;
TRegArray = Array[LoReg..HiReg] of TRegister;
TRegSet = Set of LoReg..HiReg;
//!!! FIXME
TRegArray = Array[byte] of tsuperregister;
TRegSet = Set of byte;
{ possible actions on an operand: read, write or modify (= read & write) }
TOpAction = (OpAct_Read, OpAct_Write, OpAct_Modify, OpAct_Unknown);
{ ************************************************************************* }
{ * Object to hold information on which regiters are in use and which not * }
{ ************************************************************************* }
TUsedRegs = Object
Constructor init;
Constructor InitWithValue(Const _RegSet: TRegSet);
TUsedRegs = class
Constructor create;
Constructor create_regset(Const _RegSet: TRegSet);
Destructor Destroy;override;
{ update the info with the pairegalloc objects coming after }
{ p }
Procedure Update(p: Tai);
@ -69,7 +79,6 @@ Type
Function IsUsed(Reg: TRegister): Boolean;
{ get all the currently used registers }
Function GetUsedRegs: TRegSet;
Destructor Done;
Private
@ -104,25 +113,22 @@ Type
Typ: Byte;
End;
TRegContent = Array[LoGPReg..HiGPReg] Of TContent;
//!!! FIXME
TRegContent = Array[byte] Of TContent;
{ ************************************************************************** }
{ information object with the contents of every register. Every Tai object }
{ gets one of these assigned: a pointer to it is stored in the OptInfo field }
{ ************************************************************************** }
PPaiProp = ^TPaiProp;
TPaiProp = Object(TAoptBaseCpu)
TPaiProp = class(TAoptBaseCpu)
Regs: TRegContent;
{ info about allocation of general purpose integer registers }
UsedRegs: TUsedRegs;
{ info about the conditional registers }
CondRegs: TCondRegs;
{ can this instruction be removed? }
CanBeRemoved: Boolean;
Constructor init;
Constructor create;
{ checks the whole sequence of which (so regs[which].StartMod and and }
{ the next NrOfMods Tai objects) to see whether Reg is used somewhere, }
@ -217,8 +223,8 @@ Type
{ fragment }
LowLabel, HighLabel: AWord;
LabelDif: AWord;
{ table that contains the addresses of the Pai_Label objects associated }
{ with each label number }
{ table that contains the addresses of the Pai_Label objects associated
with each label number }
LabelTable: PLabelTable;
End;
@ -226,7 +232,7 @@ Type
{ ********** General optimizer object, used to derive others from ********* }
{ ************************************************************************* }
TAOptObj = Object(TAoptBaseCpu)
TAOptObj = class(TAoptBaseCpu)
{ the PAasmOutput list this optimizer instance works on }
AsmL: TAasmOutput;
@ -238,11 +244,12 @@ Type
{ Start and end of the block that is currently being optimized }
BlockStart, BlockEnd: Tai;
DFA: TAOptDFA;
{ _AsmL is the PAasmOutpout list that has to be optimized, }
{ _BlockStart and _BlockEnd the start and the end of the block }
{ that has to be optimized and _LabelInfo a pointer to a }
{ TLabelInfo record }
Constructor Init(_AsmL: TAasmOutput; _BlockStart, _BlockEnd: Tai;
Constructor create(_AsmL: TAasmOutput; _BlockStart, _BlockEnd: Tai;
_LabelInfo: PLabelInfo);
{ processor independent methods }
@ -255,21 +262,41 @@ Type
Procedure InsertLLItem(prev, foll, new_one: TLinkedListItem);
{ If P is a Tai object releveant to the optimizer, P is returned }
{ If it is not relevant tot he optimizer, the first object after P }
{ that is relevant is returned }
{ If P is a Tai object releveant to the optimizer, P is returned
If it is not relevant tot he optimizer, the first object after P
that is relevant is returned }
Function SkipHead(P: Tai): Tai;
{ returns true if the operands o1 and o2 are completely equal }
Function OpsEqual(const o1,o2:toper): Boolean;
{ Returns true if a ait_alloc object for Reg is found in the block }
{ of Tai's starting with StartPai and ending with the next "real" }
{ instruction }
{ Returns true if a ait_alloc object for Reg is found in the block
of Tai's starting with StartPai and ending with the next "real"
instruction }
Function FindRegAlloc(Reg: TRegister; StartPai: Tai): Boolean;
{ processor dependent methods }
{ traces sucessive jumps to their final destination and sets it, e.g.
je l1 je l3
<code> <code>
l1: becomes l1:
je l2 je l3
<code> <code>
l2: l2:
jmp l3 jmp l3
the level parameter denotes how deeep we have already followed the jump,
to avoid endless loops with constructs such as "l5: ; jmp l5" }
function GetFinalDestination(hp: taicpu; level: longint): boolean;
function getlabelwithsym(sym: tasmlabel): tai;
{ peephole optimizer }
procedure PrePeepHoleOpts;virtual;
procedure PeepHoleOptPass1;virtual;
procedure PeepHoleOptPass2;virtual;
procedure PostPeepHoleOpts;virtual;
{ processor dependent methods }
End;
Function ArrayRefsEq(const r1, r2: TReference): Boolean;
@ -278,18 +305,21 @@ Type
Implementation
uses globtype, globals, cgbase;
uses
globals,
verbose,
procinfo;
{ ************************************************************************* }
{ ******************************** TUsedRegs ****************************** }
{ ************************************************************************* }
Constructor TUsedRegs.init;
Constructor TUsedRegs.create;
Begin
UsedRegs := [];
End;
Constructor TUsedRegs.InitWithValue(Const _RegSet: TRegSet);
Constructor TUsedRegs.create_regset(Const _RegSet: TRegSet);
Begin
UsedRegs := _RegSet;
End;
@ -306,11 +336,13 @@ Begin
While Assigned(p) And
(p.typ=ait_RegAlloc) Do
Begin
if tai_regalloc(p).allocation then
{!!!!!!!! FIXME
if tai_regalloc(p).ratype=ra_alloc then
UsedRegs := UsedRegs + [tai_regalloc(p).Reg]
else
UsedRegs := UsedRegs - [tai_regalloc(p).Reg];
p := Tai(p.next);
}
End;
Until Not(Assigned(p)) Or
(Not(p.typ in SkipInstr) And
@ -320,7 +352,7 @@ End;
Function TUsedRegs.IsUsed(Reg: TRegister): Boolean;
Begin
IsUsed := Reg in UsedRegs
//!!!!!!!!!!! IsUsed := Reg in UsedRegs
End;
Function TUsedRegs.GetUsedRegs: TRegSet;
@ -328,18 +360,21 @@ Begin
GetUsedRegs := UsedRegs;
End;
Destructor TUsedRegs.Done; {$ifdef inl} inline; {$endif inl}
Destructor TUsedRegs.Destroy;
Begin
inherited destroy;
end;
{ ************************************************************************* }
{ **************************** TPaiProp *********************************** }
{ ************************************************************************* }
Constructor TPaiProp.Init;
Constructor TPaiProp.Create;
Begin
{!!!!!!
UsedRegs.Init;
CondRegs.init;
}
{ DirFlag: TFlagContents; I386 specific}
End;
@ -350,6 +385,7 @@ Var p: Tai;
Counter: Byte;
TmpResult: Boolean;
Begin
{!!!!!!!!!!1
RegsChecked := [];
content := regs[which];
p := content.StartMod;
@ -359,15 +395,15 @@ Begin
(Counter <= Content.NrOfMods) Do
Begin
If IsLoadMemReg(p) Then
With PInstr(p)^.oper[LoadSrc].ref^ Do
With PInstr(p)^.oper[LoadSrc]^.ref^ Do
If (Base = ProcInfo.FramePointer)
{$ifdef RefsHaveIndexReg}
And (Index = R_NO)
{$endif RefsHaveIndexReg} Then
Begin
RegsChecked := RegsChecked +
[RegMaxSize(PInstr(p)^.oper[LoadDst].reg)];
If Reg = RegMaxSize(PInstr(p)^.oper[LoadDst].reg) Then
[RegMaxSize(PInstr(p)^.oper[LoadDst]^.reg)];
If Reg = RegMaxSize(PInstr(p)^.oper[LoadDst]^.reg) Then
Break;
End
Else
@ -387,6 +423,7 @@ Begin
GetNextInstruction(p,p)
End;
RegInSequence := TmpResult
}
End;
@ -397,6 +434,7 @@ Procedure TPaiProp.DestroyReg(Reg: TRegister; var InstrSinceLastMod:
Var TmpWState, TmpRState: Byte;
Counter: TRegister;
Begin
{!!!!!!!
Reg := RegMaxSize(Reg);
If (Reg in [LoGPReg..HiGPReg]) Then
For Counter := LoGPReg to HiGPReg Do
@ -413,16 +451,19 @@ Begin
WState := TmpWState;
RState := TmpRState
End
}
End;
Function ArrayRefsEq(const r1, r2: TReference): Boolean;
Begin
{!!!!!!!!!!
ArrayRefsEq := (R1.Offset+R1.OffsetFixup = R2.Offset+R2.OffsetFixup) And
{$ifdef refsHaveSegmentReg}
(R1.Segment = R2.Segment) And
{$endif}
(R1.Base = R2.Base) And
(R1.Symbol=R2.Symbol);
}
End;
Procedure TPaiProp.DestroyRefs(Const Ref: TReference; WhichReg: TRegister;
@ -433,6 +474,7 @@ Procedure TPaiProp.DestroyRefs(Const Ref: TReference; WhichReg: TRegister;
Var RefsEq: TRefCompare;
Counter: TRegister;
Begin
{!!!!!!!!!!!
WhichReg := RegMaxSize(WhichReg);
If (Ref.base = procinfo.FramePointer) or
Assigned(Ref.Symbol) Then
@ -503,11 +545,13 @@ Begin
)
)
Then DestroyReg(Counter, InstrSinceLastMod)
}
End;
Procedure TPaiProp.DestroyAllRegs(var InstrSinceLastMod: TInstrSinceLastMod);
Var Counter: TRegister;
Begin {initializes/desrtoys all registers}
{!!!!!!!!!
For Counter := LoGPReg To HiGPReg Do
Begin
ReadReg(Counter);
@ -515,11 +559,13 @@ Begin {initializes/desrtoys all registers}
End;
CondRegs.Init;
{ FPURegs.Init; }
}
End;
Procedure TPaiProp.DestroyOp(const o:Toper; var InstrSinceLastMod:
TInstrSinceLastMod);
Begin
{!!!!!!!
Case o.typ Of
top_reg: DestroyReg(o.reg, InstrSinceLastMod);
top_ref:
@ -529,23 +575,28 @@ Begin
End;
top_symbol:;
End;
}
End;
Procedure TPaiProp.ReadReg(Reg: TRegister);
Begin
{!!!!!!!
Reg := RegMaxSize(Reg);
If Reg in General_Registers Then
IncRState(RegMaxSize(Reg))
}
End;
Procedure TPaiProp.ReadRef(Ref: PReference);
Begin
{!!!!!!!
If Ref^.Base <> R_NO Then
ReadReg(Ref^.Base);
{$ifdef refsHaveIndexReg}
If Ref^.Index <> R_NO Then
ReadReg(Ref^.Index);
{$endif}
}
End;
Procedure TPaiProp.ReadOp(const o:toper);
@ -553,13 +604,15 @@ Begin
Case o.typ Of
top_reg: ReadReg(o.reg);
top_ref: ReadRef(o.ref);
top_symbol : ;
else
internalerror(200410241);
End;
End;
Procedure TPaiProp.ModifyReg(reg: TRegister; Var InstrSinceLastMod:
TInstrSinceLastMod);
Begin
{!!!!!!!
With Regs[reg] Do
If (Typ = Con_Ref)
Then
@ -574,6 +627,7 @@ Begin
End
Else
DestroyReg(Reg, InstrSinceLastMod);
}
End;
Procedure TPaiProp.ModifyOp(const oper: TOper; var InstrSinceLastMod:
@ -590,33 +644,33 @@ End;
Procedure TPaiProp.IncWState(Reg: TRegister);{$ifdef inl} inline;{$endif inl}
Begin
IncState(Regs[Reg].WState);
//!!!! IncState(Regs[Reg].WState);
End;
Procedure TPaiProp.IncRState(Reg: TRegister);{$ifdef inl} inline;{$endif inl}
Begin
IncState(Regs[Reg].RState);
//!!!! IncState(Regs[Reg].RState);
End;
Function TPaiProp.GetWState(Reg: TRegister): TStateInt; {$ifdef inl} inline;{$endif inl}
Begin
GetWState := Regs[Reg].WState
//!!!! GetWState := Regs[Reg].WState
End;
Function TPaiProp.GetRState(Reg: TRegister): TStateInt; {$ifdef inl} inline;{$endif inl}
Begin
GetRState := Regs[Reg].RState
//!!!! GetRState := Regs[Reg].RState
End;
Function TPaiProp.GetRegContentType(Reg: TRegister): Byte; {$ifdef inl} inline;{$endif inl}
Begin
GetRegContentType := Regs[Reg].typ
//!!!! GetRegContentType := Regs[Reg].typ
End;
Destructor TPaiProp.Done;
Begin
UsedRegs.Done;
CondRegs.Done;
//!!!! UsedRegs.Done;
//!!!! CondRegs.Done;
{ DirFlag: TFlagContents; I386 specific}
End;
{ ************************ private TPaiProp stuff ************************* }
@ -637,8 +691,8 @@ Begin
Begin
Count := 0;
Repeat
If (TInstr(p).oper[Count].typ = Top_Ref) Then
TmpResult := RefsEq(Ref, PInstr(p)^.oper[Count].ref^);
If (TInstr(p).oper[Count]^.typ = Top_Ref) Then
TmpResult := RefsEq(Ref, PInstr(p)^.oper[Count]^.ref^);
Inc(Count);
Until (Count = MaxOps) or TmpResult;
End;
@ -670,7 +724,7 @@ End;
{ ***************************** TAoptObj ********************************** }
{ ************************************************************************* }
Constructor TAoptObj.Init(_AsmL: TAasmOutput; _BlockStart, _BlockEnd: Tai;
Constructor TAoptObj.create(_AsmL: TAasmOutput; _BlockStart, _BlockEnd: Tai;
_LabelInfo: PLabelInfo);
Begin
AsmL := _AsmL;
@ -708,6 +762,9 @@ Begin
new_one.next := foll;
prev.next := new_one;
foll.previous := new_one;
{ should we update line information? }
if (not (tai(new_one).typ in SkipLineInfo)) and
(not (tai(foll).typ in SkipLineInfo)) then
Tailineinfo(new_one).fileinfo := Tailineinfo(foll).fileinfo
End
End
@ -752,8 +809,6 @@ Begin
OpsEqual := RefsEqual(o1.ref^, o2.ref^);
Top_Const :
OpsEqual:=o1.val=o2.val;
Top_Symbol :
OpsEqual:=(o1.sym=o2.sym) and (o1.symofs=o2.symofs);
Top_None :
OpsEqual := True
else OpsEqual := False
@ -770,7 +825,7 @@ Begin
Not(Tai_Label(StartPai).l.Is_Used))) Do
StartPai := Tai(StartPai.Next);
If Assigned(StartPai) And
(StartPai.typ = ait_regAlloc) and (tai_regalloc(StartPai).allocation) Then
(StartPai.typ = ait_regAlloc) and (tai_regalloc(StartPai).ratype=ra_alloc) Then
Begin
if tai_regalloc(StartPai).Reg = Reg then
begin
@ -784,11 +839,257 @@ Begin
Until false;
End;
function SkipLabels(hp: tai; var hp2: tai): boolean;
{skips all labels and returns the next "real" instruction}
begin
while assigned(hp.next) and
(tai(hp.next).typ in SkipInstr + [ait_label,ait_align]) Do
hp := tai(hp.next);
if assigned(hp.next) then
begin
SkipLabels := True;
hp2 := tai(hp.next)
end
else
begin
hp2 := hp;
SkipLabels := False
end;
end;
function FindAnyLabel(hp: tai; var l: tasmlabel): Boolean;
begin
FindAnyLabel := false;
while assigned(hp.next) and
(tai(hp.next).typ in (SkipInstr+[ait_align])) Do
hp := tai(hp.next);
if assigned(hp.next) and
(tai(hp.next).typ = ait_label) then
begin
FindAnyLabel := true;
l := tai_label(hp.next).l;
end
end;
{$ifopt r+}
{$define rangewason}
{$r-}
{$endif}
function tAOptObj.getlabelwithsym(sym: tasmlabel): tai;
begin
if (sym.labelnr >= labelinfo^.lowlabel) and
(sym.labelnr <= labelinfo^.highlabel) then { range check, a jump can go past an assembler block! }
getlabelwithsym := labelinfo^.labeltable^[sym.labelnr-labelinfo^.lowlabel].paiobj
else
getlabelwithsym := nil;
end;
{$ifdef rangewason}
{$r+}
{$undef rangewason}
{$endif}
function TAOptObj.GetFinalDestination(hp: taicpu; level: longint): boolean;
{traces sucessive jumps to their final destination and sets it, e.g.
je l1 je l3
<code> <code>
l1: becomes l1:
je l2 je l3
<code> <code>
l2: l2:
jmp l3 jmp l3
the level parameter denotes how deeep we have already followed the jump,
to avoid endless loops with constructs such as "l5: ; jmp l5" }
var p1, p2: tai;
l: tasmlabel;
begin
if level > 20 then
exit;
GetfinalDestination := false;
p1 := getlabelwithsym(tasmlabel(hp.oper[0]^.ref^.symbol));
if assigned(p1) then
begin
SkipLabels(p1,p1);
if (tai(p1).typ = ait_instruction) and
(taicpu(p1).is_jmp) then
if { the next instruction after the label where the jump hp arrives}
{ is unconditional or of the same type as hp, so continue }
(taicpu(p1).condition in [C_None,hp.condition]) or
{ the next instruction after the label where the jump hp arrives}
{ is the opposite of hp (so this one is never taken), but after }
{ that one there is a branch that will be taken, so perform a }
{ little hack: set p1 equal to this instruction (that's what the}
{ last SkipLabels is for, only works with short bool evaluation)}
((taicpu(p1).condition = inverse_cond[hp.condition]) and
SkipLabels(p1,p2) and
(p2.typ = ait_instruction) and
(taicpu(p2).is_jmp) and
(taicpu(p2).condition in [C_None,hp.condition]) and
SkipLabels(p1,p1)) then
begin
{ quick check for loops of the form "l5: ; jmp l5 }
if (tasmlabel(taicpu(p1).oper[0]^.ref^.symbol).labelnr =
tasmlabel(hp.oper[0]^.ref^.symbol).labelnr) then
exit;
if not GetFinalDestination(taicpu(p1),succ(level)) then
exit;
tasmlabel(hp.oper[0]^.ref^.symbol).decrefs;
hp.oper[0]^.ref^.symbol:=taicpu(p1).oper[0]^.ref^.symbol;
tasmlabel(hp.oper[0]^.ref^.symbol).increfs;
end
else
if (taicpu(p1).condition = inverse_cond[hp.condition]) then
if not FindAnyLabel(p1,l) then
begin
{$ifdef finaldestdebug}
insertllitem(asml,p1,p1.next,tai_comment.Create(
strpnew('previous label inserted'))));
{$endif finaldestdebug}
objectlibrary.getlabel(l);
insertllitem(p1,p1.next,tai_label.Create(l));
tasmlabel(taicpu(hp).oper[0]^.ref^.symbol).decrefs;
hp.oper[0]^.ref^.symbol := l;
l.increfs;
{ this won't work, since the new label isn't in the labeltable }
{ so it will fail the rangecheck. Labeltable should become a }
{ hashtable to support this: }
{ GetFinalDestination(asml, hp); }
end
else
begin
{$ifdef finaldestdebug}
insertllitem(asml,p1,p1.next,tai_comment.Create(
strpnew('next label reused'))));
{$endif finaldestdebug}
l.increfs;
hp.oper[0]^.ref^.symbol := l;
if not GetFinalDestination(hp,succ(level)) then
exit;
end;
end;
GetFinalDestination := true;
end;
procedure TAOptObj.PrePeepHoleOpts;
begin
end;
procedure TAOptObj.PeepHoleOptPass1;
var
p,hp1,hp2 : tai;
begin
p := BlockStart;
//!!!! UsedRegs := [];
while (p <> BlockEnd) Do
begin
//!!!! UpDateUsedRegs(UsedRegs, tai(p.next));
case p.Typ Of
ait_instruction:
begin
{ Handle Jmp Optimizations }
if taicpu(p).is_jmp then
begin
{ the following if-block removes all code between a jmp and the next label,
because it can never be executed
}
if (taicpu(p).opcode = aopt_uncondjmp) then
begin
while GetNextInstruction(p, hp1) and
(hp1.typ <> ait_label) do
if not(hp1.typ in ([ait_label,ait_align]+skipinstr)) then
begin
asml.remove(hp1);
hp1.free;
end
else break;
end;
{ remove jumps to a label coming right after them }
if GetNextInstruction(p, hp1) then
begin
if FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol), hp1) and
{$warning FIXME removing the first instruction fails}
(p<>blockstart) then
begin
hp2:=tai(hp1.next);
asml.remove(p);
p.free;
p:=hp2;
continue;
end
else
begin
if hp1.typ = ait_label then
SkipLabels(hp1,hp1);
if (tai(hp1).typ=ait_instruction) and
(taicpu(hp1).opcode=aopt_uncondjmp) and
GetNextInstruction(hp1, hp2) and
FindLabel(tasmlabel(taicpu(p).oper[0]^.ref^.symbol), hp2) then
begin
if taicpu(p).opcode=aopt_condjmp then
begin
taicpu(p).condition:=inverse_cond[taicpu(p).condition];
tai_label(hp2).l.decrefs;
taicpu(p).oper[0]^.ref^.symbol:=taicpu(hp1).oper[0]^.ref^.symbol;
taicpu(p).oper[0]^.ref^.symbol.increfs;
{$ifdef SPARC}
hp2:=tai(hp1.next);
asml.remove(hp2);
hp2.free;
{$endif SPARC}
asml.remove(hp1);
hp1.free;
GetFinalDestination(taicpu(p),0);
end
else
begin
GetFinalDestination(taicpu(p),0);
p:=tai(p.next);
continue;
end;
end
else
GetFinalDestination(taicpu(p),0);
end;
end;
end
else
{ All other optimizes }
begin
end; { if is_jmp }
end;
end;
//!!!!!!!! updateUsedRegs(UsedRegs,p);
p:=tai(p.next);
end;
end;
procedure TAOptObj.PeepHoleOptPass2;
begin
end;
procedure TAOptObj.PostPeepHoleOpts;
begin
end;
End.
{
$Log$
Revision 1.11 2004-06-20 08:55:28 florian
Revision 1.12 2004-10-30 15:21:37 florian
* fixed generic optimizer
* enabled generic optimizer for sparc
Revision 1.11 2004/06/20 08:55:28 florian
* logs truncated
Revision 1.10 2004/01/31 17:45:17 peter
@ -797,5 +1098,4 @@ End.
Revision 1.9 2004/01/30 13:42:03 florian
* fixed more alignment issues
}

View File

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

View File

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

View File

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

View File

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

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

View File

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