* CSE now updates the RegAlloc's

This commit is contained in:
Jonas Maebe 1999-10-01 13:51:40 +00:00
parent ca15c4c4fb
commit 6ca2b6e276

View File

@ -208,6 +208,36 @@ Begin {CheckSequence}
{$endif fpc} {$endif fpc}
End; {CheckSequence} 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); Procedure DoCSE(AsmL: PAasmOutput; First, Last: Pai);
{marks the instructions that can be removed by RemoveInstructs. They're not {marks the instructions that can be removed by RemoveInstructs. They're not
removed immediately because sometimes an instruction needs to be checked in removed immediately because sometimes an instruction needs to be checked in
@ -288,8 +318,6 @@ Begin
InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3); InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3);
{hp4 is used to get the contents of the registers before the sequence} {hp4 is used to get the contents of the registers before the sequence}
GetLastInstruction(hp2, hp4); 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} {$IfDef CSDebug}
For RegCounter := R_EAX To R_EDI Do For RegCounter := R_EAX To R_EDI Do
If (RegCounter in RegInfo.RegsLoadedForRef) Then If (RegCounter in RegInfo.RegsLoadedForRef) Then
@ -299,18 +327,21 @@ Begin
InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp5); InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp5);
End; End;
{$EndIf CSDebug} {$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 For RegCounter := R_EAX To R_EDI Do
Begin If Not(RegCounter in [R_ESP,procinfo^.framepointer]) And
If (RegInfo.New2OldReg[RegCounter] <> R_NO) Then (RegInfo.New2OldReg[RegCounter] <> R_NO) Then
Begin
AllocRegBetween(AsmL,RegInfo.New2OldReg[RegCounter],
PPaiProp(hp4^.OptInfo)^.Regs[RegInfo.New2OldReg[RegCounter]].StartMod,hp2);
If Not(RegCounter In RegInfo.RegsLoadedForRef) And If Not(RegCounter In RegInfo.RegsLoadedForRef) And
{old reg new reg} {old reg new reg}
(RegInfo.New2OldReg[RegCounter] <> RegCounter) Then (RegInfo.New2OldReg[RegCounter] <> RegCounter) Then
Begin Begin
hp3 := New(Paicpu,Op_Reg_Reg(A_MOV, S_L, hp3 := New(Paicpu,Op_Reg_Reg(A_MOV, S_L,
{old reg new reg} {old reg new reg}
RegInfo.New2OldReg[RegCounter], RegCounter)); RegInfo.New2OldReg[RegCounter], RegCounter));
hp3^.fileinfo := hp2^.fileinfo;
InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp3); InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp3);
End End
Else Else
@ -322,7 +353,7 @@ Begin
{ jne l1 jne l1 } { jne l1 jne l1 }
{ movl 8(%ebp), %eax } { movl 8(%ebp), %eax }
{ movl (%eax), %edi movl %eax, %edi } { movl (%eax), %edi movl %eax, %edi }
{ movl %edi, -4(%ebp) movl %edi, -4(%ebp) } { movl %edi, -4(%ebp) movl %edi, -4(%ebp) }
{ movl 8(%ebp), %eax } { movl 8(%ebp), %eax }
{ pushl 70(%eax) pushl 70(%eax) } { pushl 70(%eax) pushl 70(%eax) }
{ } { }
@ -331,60 +362,59 @@ Begin
{ registers that are completely removed from a sequence (= registers in } { registers that are completely removed from a sequence (= registers in }
{ RegLoadedForRef, have to be changed to their contents from before the } { RegLoadedForRef, have to be changed to their contents from before the }
{ sequence. } { sequence. }
Begin Begin
{load Cnt2 with the total number of instructions of this sequence} {load Cnt2 with the total number of instructions of this sequence}
Cnt2 := PPaiProp(hp4^.OptInfo)^. Cnt2 := PPaiProp(hp4^.OptInfo)^.
Regs[RegInfo.New2OldReg[RegCounter]].NrOfMods; Regs[RegInfo.New2OldReg[RegCounter]].NrOfMods;
hp3 := hp2; hp3 := hp2;
For Cnt := 1 to Pred(Cnt2) Do For Cnt := 1 to Pred(Cnt2) Do
GetNextInstruction(hp3, hp3);
TmpState := PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState;
GetNextInstruction(hp3, hp3); GetNextInstruction(hp3, hp3);
TmpState := PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState;
GetNextInstruction(hp3, hp3);
{$ifdef csdebug} {$ifdef csdebug}
Writeln('Cnt2: ',Cnt2); Writeln('Cnt2: ',Cnt2);
hp5 := new(pai_asm_comment,init(strpnew('starting here...'))); hp5 := new(pai_asm_comment,init(strpnew('starting here...')));
InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp5); InsertLLItem(AsmL, Pai(hp2^.previous), hp2, hp5);
{$endif csdebug} {$endif csdebug}
hp3 := hp2; hp3 := hp2;
{first change the contents of the register inside the sequence} {first change the contents of the register inside the sequence}
For Cnt := 1 to Cnt2 Do For Cnt := 1 to Cnt2 Do
Begin Begin
{save the WState of the last pai object of the sequence for later use} {save the WState of the last pai object of the sequence for later use}
TmpState := PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState; TmpState := PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState;
{$ifdef csdebug} {$ifdef csdebug}
hp5 := new(pai_asm_comment,init(strpnew('WState for '+att_reg2str[Regcounter]+': ' hp5 := new(pai_asm_comment,init(strpnew('WState for '+att_reg2str[Regcounter]+': '
+tostr(tmpstate)))); +tostr(tmpstate))));
InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5); InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
{$endif csdebug}
PPaiProp(hp3^.OptInfo)^.Regs[RegCounter] :=
PPaiProp(hp4^.OptInfo)^.Regs[RegCounter];
GetNextInstruction(hp3, hp3);
End;
{here, hp3 = p = Pai object right after the sequence, TmpState = WState of
RegCounter at the last Pai object of the sequence}
GetLastInstruction(hp3, hp3);
While GetNextInstruction(hp3, hp3) And
(PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState
= TmpState) Do
{$ifdef csdebug}
begin
hp5 := new(pai_asm_comment,init(strpnew('WState for '+att_reg2str[Regcounter]+': '+
tostr(PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState))));
InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
{$endif csdebug} {$endif csdebug}
PPaiProp(hp3^.OptInfo)^.Regs[RegCounter] := PPaiProp(hp3^.OptInfo)^.Regs[RegCounter] :=
PPaiProp(hp4^.OptInfo)^.Regs[RegCounter]; PPaiProp(hp4^.OptInfo)^.Regs[RegCounter];
GetNextInstruction(hp3, hp3);
End;
{here, hp3 = p = Pai object right after the sequence, TmpState = WState of
RegCounter at the last Pai object of the sequence}
GetLastInstruction(hp3, hp3);
While GetNextInstruction(hp3, hp3) And
(PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState
= TmpState) Do
{$ifdef csdebug} {$ifdef csdebug}
end; begin
hp5 := new(pai_asm_comment,init(strpnew('WState for '+att_reg2str[Regcounter]+': '+
tostr(PPaiProp(hp3^.OptInfo)^.Regs[RegCounter].WState))));
InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
{$endif csdebug}
PPaiProp(hp3^.OptInfo)^.Regs[RegCounter] :=
PPaiProp(hp4^.OptInfo)^.Regs[RegCounter];
{$ifdef csdebug}
end;
{$endif csdebug} {$endif csdebug}
{$ifdef csdebug} {$ifdef csdebug}
hp5 := new(pai_asm_comment,init(strpnew('stopping here...'))); hp5 := new(pai_asm_comment,init(strpnew('stopping here...')));
InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5); InsertLLItem(AsmL, hp3, pai(hp3^.next), hp5);
{$endif csdebug} {$endif csdebug}
End; End;
End; End;
hp3 := New(Pai_Marker,Init(NoPropInfoEnd)); hp3 := New(Pai_Marker,Init(NoPropInfoEnd));
InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3); InsertLLItem(AsmL, Pai(hp2^.Previous), hp2, hp3);
If hp1 <> nil Then p := hp1; If hp1 <> nil Then p := hp1;
@ -499,7 +529,10 @@ End.
{ {
$Log$ $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 * fixed small efficiency which caused some missed optimizations (saves 1
assembler instruction on the whole compiler/RTL source tree! :) assembler instruction on the whole compiler/RTL source tree! :)