mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-07 04:33:51 +02:00
* CSE now updates the RegAlloc's
This commit is contained in:
parent
ca15c4c4fb
commit
6ca2b6e276
@ -208,6 +208,36 @@ Begin {CheckSequence}
|
||||
{$endif fpc}
|
||||
End; {CheckSequence}
|
||||
|
||||
Procedure AllocRegBetween(AsmL: PAasmOutput; Reg: TRegister; p1, p2: Pai);
|
||||
{ allocates register Reg between (and including) instructions p1 and p2 }
|
||||
{ the type of p1 and p2 must not be in SkipInstr }
|
||||
var hp: pai;
|
||||
Begin
|
||||
If not(assigned(p1)) Then
|
||||
{ this happens with registers which are loaded implicitely, outside the }
|
||||
{ current block (e.g. esi with self) }
|
||||
exit;
|
||||
Repeat
|
||||
If Assigned(p1^.OptInfo) Then
|
||||
Include(PPaiProp(p1^.OptInfo)^.UsedRegs,Reg);
|
||||
p1 := Pai(p1^.next);
|
||||
Repeat
|
||||
While (p1^.typ in (SkipInstr-[ait_regalloc])) Do
|
||||
p1 := Pai(p1^.next);
|
||||
{ remove all allocation/deallocation info about the register in between }
|
||||
If (p1^.typ = ait_regalloc) Then
|
||||
If (PaiRegAlloc(p1)^.Reg = Reg) Then
|
||||
Begin
|
||||
hp := Pai(p1^.Next);
|
||||
AsmL^.Remove(p1);
|
||||
Dispose(p1, Done);
|
||||
p1 := hp;
|
||||
End
|
||||
Else p1 := Pai(p1^.next);
|
||||
Until Not(p1^.typ in SkipInstr);
|
||||
Until p1 = p2;
|
||||
End;
|
||||
|
||||
Procedure DoCSE(AsmL: PAasmOutput; First, Last: Pai);
|
||||
{marks the instructions that can be removed by RemoveInstructs. They're not
|
||||
removed immediately because sometimes an instruction needs to be checked in
|
||||
@ -288,8 +318,6 @@ Begin
|
||||
InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3);
|
||||
{hp4 is used to get the contents of the registers before the sequence}
|
||||
GetLastInstruction(hp2, hp4);
|
||||
{ If some registers were different in the old and the new sequence, move }
|
||||
{ the contents of those old registers to the new ones }
|
||||
{$IfDef CSDebug}
|
||||
For RegCounter := R_EAX To R_EDI Do
|
||||
If (RegCounter in RegInfo.RegsLoadedForRef) Then
|
||||
@ -299,18 +327,21 @@ Begin
|
||||
InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp5);
|
||||
End;
|
||||
{$EndIf CSDebug}
|
||||
{ If some registers were different in the old and the new sequence, move }
|
||||
{ the contents of those old registers to the new ones }
|
||||
For RegCounter := R_EAX To R_EDI Do
|
||||
If Not(RegCounter in [R_ESP,procinfo^.framepointer]) And
|
||||
(RegInfo.New2OldReg[RegCounter] <> R_NO) Then
|
||||
Begin
|
||||
If (RegInfo.New2OldReg[RegCounter] <> R_NO) Then
|
||||
AllocRegBetween(AsmL,RegInfo.New2OldReg[RegCounter],
|
||||
PPaiProp(hp4^.OptInfo)^.Regs[RegInfo.New2OldReg[RegCounter]].StartMod,hp2);
|
||||
If Not(RegCounter In RegInfo.RegsLoadedForRef) And
|
||||
{old reg new reg}
|
||||
(RegInfo.New2OldReg[RegCounter] <> RegCounter) Then
|
||||
|
||||
Begin
|
||||
hp3 := New(Paicpu,Op_Reg_Reg(A_MOV, S_L,
|
||||
{old reg new reg}
|
||||
RegInfo.New2OldReg[RegCounter], RegCounter));
|
||||
hp3^.fileinfo := hp2^.fileinfo;
|
||||
InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp3);
|
||||
End
|
||||
Else
|
||||
@ -332,7 +363,6 @@ Begin
|
||||
{ RegLoadedForRef, have to be changed to their contents from before the }
|
||||
{ sequence. }
|
||||
Begin
|
||||
|
||||
{load Cnt2 with the total number of instructions of this sequence}
|
||||
Cnt2 := PPaiProp(hp4^.OptInfo)^.
|
||||
Regs[RegInfo.New2OldReg[RegCounter]].NrOfMods;
|
||||
@ -499,7 +529,10 @@ End.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.26 1999-09-30 14:43:13 jonas
|
||||
Revision 1.27 1999-10-01 13:51:40 jonas
|
||||
* CSE now updates the RegAlloc's
|
||||
|
||||
Revision 1.26 1999/09/30 14:43:13 jonas
|
||||
* fixed small efficiency which caused some missed optimizations (saves 1
|
||||
assembler instruction on the whole compiler/RTL source tree! :)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user