mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-12 14:32:07 +02:00
* better support for regvars (still needs a move of the call to the optimize
procedure to a place where resetusableregisters is not yet called to work) * small regallocation fixes for -dnewoptimizations
This commit is contained in:
parent
aa8b9730a1
commit
4e361ef71f
@ -39,7 +39,7 @@ Procedure CSE(AsmL: PAasmOutput; First, Last: Pai);
|
|||||||
Implementation
|
Implementation
|
||||||
|
|
||||||
Uses
|
Uses
|
||||||
CObjects, verbose, hcodegen, globals,cpubase,cpuasm,DAOpt386;
|
CObjects, verbose, hcodegen, globals,cpubase,cpuasm,DAOpt386, tgeni386;
|
||||||
|
|
||||||
{
|
{
|
||||||
Function PaiInSequence(P: Pai; Const Seq: TContent): Boolean;
|
Function PaiInSequence(P: Pai; Const Seq: TContent): Boolean;
|
||||||
@ -220,7 +220,8 @@ Procedure AllocRegBetween(AsmL: PAasmOutput; Reg: TRegister; p1, p2: Pai);
|
|||||||
{ the type of p1 and p2 must not be in SkipInstr }
|
{ the type of p1 and p2 must not be in SkipInstr }
|
||||||
var hp: pai;
|
var hp: pai;
|
||||||
Begin
|
Begin
|
||||||
If not(assigned(p1)) Then
|
If not(reg in usableregs) or
|
||||||
|
not(assigned(p1)) Then
|
||||||
{ this happens with registers which are loaded implicitely, outside the }
|
{ this happens with registers which are loaded implicitely, outside the }
|
||||||
{ current block (e.g. esi with self) }
|
{ current block (e.g. esi with self) }
|
||||||
exit;
|
exit;
|
||||||
@ -229,10 +230,12 @@ Begin
|
|||||||
Include(PPaiProp(p1^.OptInfo)^.UsedRegs,Reg);
|
Include(PPaiProp(p1^.OptInfo)^.UsedRegs,Reg);
|
||||||
p1 := Pai(p1^.next);
|
p1 := Pai(p1^.next);
|
||||||
Repeat
|
Repeat
|
||||||
While (p1^.typ in (SkipInstr-[ait_regalloc])) Do
|
While assigned(p1) and
|
||||||
|
(p1^.typ in (SkipInstr-[ait_regalloc])) Do
|
||||||
p1 := Pai(p1^.next);
|
p1 := Pai(p1^.next);
|
||||||
{ remove all allocation/deallocation info about the register in between }
|
{ remove all allocation/deallocation info about the register in between }
|
||||||
If (p1^.typ = ait_regalloc) Then
|
If assigned(p1) and
|
||||||
|
(p1^.typ = ait_regalloc) Then
|
||||||
If (PaiRegAlloc(p1)^.Reg = Reg) Then
|
If (PaiRegAlloc(p1)^.Reg = Reg) Then
|
||||||
Begin
|
Begin
|
||||||
hp := Pai(p1^.Next);
|
hp := Pai(p1^.Next);
|
||||||
@ -241,8 +244,10 @@ Begin
|
|||||||
p1 := hp;
|
p1 := hp;
|
||||||
End
|
End
|
||||||
Else p1 := Pai(p1^.next);
|
Else p1 := Pai(p1^.next);
|
||||||
Until Not(p1^.typ in SkipInstr);
|
Until not(assigned(p1)) or
|
||||||
Until p1 = p2;
|
Not(p1^.typ in SkipInstr);
|
||||||
|
Until not(assigned(p1)) or
|
||||||
|
(p1 = p2);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Procedure SetAlignReg(p: Pai);
|
Procedure SetAlignReg(p: Pai);
|
||||||
@ -673,12 +678,15 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function ReplaceReg(orgReg, newReg: TRegister; p: pai;
|
function ReplaceReg(orgReg, newReg: TRegister; p: pai;
|
||||||
const c: TContent; orgRegCanBeModified: Boolean): Boolean;
|
const c: TContent; orgRegCanBeModified: Boolean;
|
||||||
|
var returnEndP: pai): Boolean;
|
||||||
{ Tries to replace orgreg with newreg in all instructions coming after p }
|
{ Tries to replace orgreg with newreg in all instructions coming after p }
|
||||||
{ until orgreg gets loaded with a new value. Returns true if successful, }
|
{ until orgreg gets loaded with a new value. Returns true if successful, }
|
||||||
{ false otherwise. If successful, the contents of newReg are set to c, }
|
{ false otherwise. If successful, the contents of newReg are set to c, }
|
||||||
{ which should hold the contents of newReg before the current sequence }
|
{ which should hold the contents of newReg before the current sequence }
|
||||||
{ started }
|
{ started }
|
||||||
|
{ if the functino returns true, returnEndP holds the lat instruction }
|
||||||
|
{ where newReg was replaced by orgReg }
|
||||||
var endP, hp: Pai;
|
var endP, hp: Pai;
|
||||||
sequenceEnd, tmpResult, newRegModified, orgRegRead: Boolean;
|
sequenceEnd, tmpResult, newRegModified, orgRegRead: Boolean;
|
||||||
begin
|
begin
|
||||||
@ -767,6 +775,7 @@ begin
|
|||||||
hp^.next^.previous := hp;
|
hp^.next^.previous := hp;
|
||||||
{$endif replaceregdebug}
|
{$endif replaceregdebug}
|
||||||
ReplaceReg := true;
|
ReplaceReg := true;
|
||||||
|
returnEndP := endP;
|
||||||
hp := p;
|
hp := p;
|
||||||
while hp <> endP do
|
while hp <> endP do
|
||||||
begin
|
begin
|
||||||
@ -861,10 +870,7 @@ Procedure DoCSE(AsmL: PAasmOutput; First, Last: Pai);
|
|||||||
two different sequences}
|
two different sequences}
|
||||||
Var Cnt, Cnt2: Longint;
|
Var Cnt, Cnt2: Longint;
|
||||||
p, hp1, hp2: Pai;
|
p, hp1, hp2: Pai;
|
||||||
hp3, hp4: Pai;
|
hp3, hp4, hp5: pai;
|
||||||
{$ifdef csdebug}
|
|
||||||
hp5: pai;
|
|
||||||
{$endif csdebug}
|
|
||||||
RegInfo: TRegInfo;
|
RegInfo: TRegInfo;
|
||||||
RegCounter: TRegister;
|
RegCounter: TRegister;
|
||||||
TmpState: Byte;
|
TmpState: Byte;
|
||||||
@ -963,7 +969,7 @@ Begin
|
|||||||
getLastInstruction(p,hp3);
|
getLastInstruction(p,hp3);
|
||||||
If not ReplaceReg(RegInfo.New2OldReg[RegCounter],
|
If not ReplaceReg(RegInfo.New2OldReg[RegCounter],
|
||||||
regCounter,hp3,
|
regCounter,hp3,
|
||||||
PPaiProp(hp4^.optInfo)^.Regs[regCounter],true) then
|
PPaiProp(hp4^.optInfo)^.Regs[regCounter],true,hp5) then
|
||||||
begin
|
begin
|
||||||
{$endif replacereg}
|
{$endif replacereg}
|
||||||
hp3 := New(Paicpu,Op_Reg_Reg(A_MOV, S_L,
|
hp3 := New(Paicpu,Op_Reg_Reg(A_MOV, S_L,
|
||||||
@ -1081,8 +1087,13 @@ Begin
|
|||||||
top_Reg:
|
top_Reg:
|
||||||
if ReplaceReg(paicpu(p)^.oper[0].reg,
|
if ReplaceReg(paicpu(p)^.oper[0].reg,
|
||||||
paicpu(p)^.oper[1].reg,p,
|
paicpu(p)^.oper[1].reg,p,
|
||||||
PPaiProp(hp4^.optInfo)^.Regs[regCounter],false) then
|
PPaiProp(hp4^.optInfo)^.Regs[regCounter],false,hp1) then
|
||||||
PPaiProp(p^.optInfo)^.canBeRemoved := true;
|
begin
|
||||||
|
PPaiProp(p^.optInfo)^.canBeRemoved := true;
|
||||||
|
allocRegBetween(asmL,paicpu(p)^.oper[0].reg,
|
||||||
|
PPaiProp(p^.optInfo)^.regs[paicpu(p)^.oper[0].reg].startMod,
|
||||||
|
hp1);
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
{$endif replacereg}
|
{$endif replacereg}
|
||||||
@ -1091,18 +1102,26 @@ Begin
|
|||||||
Case Paicpu(p)^.oper[1].typ Of
|
Case Paicpu(p)^.oper[1].typ Of
|
||||||
Top_Reg:
|
Top_Reg:
|
||||||
Begin
|
Begin
|
||||||
|
regCounter := Reg32(Paicpu(p)^.oper[1].reg);
|
||||||
If GetLastInstruction(p, hp1) Then
|
If GetLastInstruction(p, hp1) Then
|
||||||
With PPaiProp(hp1^.OptInfo)^.Regs[Reg32(Paicpu(p)^.oper[1].reg)] Do
|
With PPaiProp(hp1^.OptInfo)^.Regs[regCounter] Do
|
||||||
If (Typ = Con_Const) And
|
If (Typ = Con_Const) And
|
||||||
(paicpu(startMod)^.opsize >= paicpu(p)^.opsize) and
|
(paicpu(startMod)^.opsize >= paicpu(p)^.opsize) and
|
||||||
(paicpu(StartMod)^.oper[0].val = paicpu(p)^.oper[0].val) Then
|
(paicpu(StartMod)^.oper[0].val = paicpu(p)^.oper[0].val) Then
|
||||||
PPaiProp(p^.OptInfo)^.CanBeRemoved := True;
|
begin
|
||||||
|
PPaiProp(p^.OptInfo)^.CanBeRemoved := True;
|
||||||
|
allocRegBetween(asmL,regCounter,startMod,p);
|
||||||
|
end;
|
||||||
End;
|
End;
|
||||||
{$ifdef arithopt}
|
{$ifdef arithopt}
|
||||||
Top_Ref:
|
Top_Ref:
|
||||||
if getLastInstruction(p,hp1) and
|
if getLastInstruction(p,hp1) and
|
||||||
findRegWithConst(hp1,paicpu(p)^.opsize,paicpu(p)^.oper[0].val,regCounter) then
|
findRegWithConst(hp1,paicpu(p)^.opsize,paicpu(p)^.oper[0].val,regCounter) then
|
||||||
paicpu(p)^.loadreg(0,regCounter);
|
begin
|
||||||
|
paicpu(p)^.loadreg(0,regCounter);
|
||||||
|
allocRegBetween(AsmL,reg32(regCounter),
|
||||||
|
PPaiProp(hp1^.optinfo)^.regs[regCounter].startMod,p);
|
||||||
|
end;
|
||||||
{$endif arithopt}
|
{$endif arithopt}
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
@ -1171,7 +1190,12 @@ End.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.42 2000-01-28 15:15:31 jonas
|
Revision 1.43 2000-02-04 13:52:17 jonas
|
||||||
|
* better support for regvars (still needs a move of the call to the optimize
|
||||||
|
procedure to a place where resetusableregisters is not yet called to work)
|
||||||
|
* small regallocation fixes for -dnewoptimizations
|
||||||
|
|
||||||
|
Revision 1.42 2000/01/28 15:15:31 jonas
|
||||||
* moved skipinstr from daopt386 to aasm
|
* moved skipinstr from daopt386 to aasm
|
||||||
* fixed crashing bug with -dreplacereg in csopt386.pas
|
* fixed crashing bug with -dreplacereg in csopt386.pas
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ Var
|
|||||||
Implementation
|
Implementation
|
||||||
|
|
||||||
Uses
|
Uses
|
||||||
globals, systems, strings, verbose, hcodegen, symconst;
|
globals, systems, strings, verbose, hcodegen, symconst, tgeni386;
|
||||||
|
|
||||||
Type
|
Type
|
||||||
TRefCompare = function(const r1, r2: TReference): Boolean;
|
TRefCompare = function(const r1, r2: TReference): Boolean;
|
||||||
@ -396,7 +396,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure getFuncResRegs(var regs: TRegSet);
|
procedure getNoDeallocRegs(var regs: TRegSet);
|
||||||
|
var regCounter: TRegister;
|
||||||
begin
|
begin
|
||||||
regs := [];
|
regs := [];
|
||||||
if assigned(procinfo^.returntype.def) then
|
if assigned(procinfo^.returntype.def) then
|
||||||
@ -414,7 +415,10 @@ begin
|
|||||||
if procinfo^.returntype.def^.size = 8 then
|
if procinfo^.returntype.def^.size = 8 then
|
||||||
regs := regs + [R_EDX];
|
regs := regs + [R_EDX];
|
||||||
end;
|
end;
|
||||||
end
|
end;
|
||||||
|
for regCounter := R_EAX to R_EBX do
|
||||||
|
if not(regCounter in usableregs) then
|
||||||
|
regs := regs + [regCounter];
|
||||||
end;
|
end;
|
||||||
|
|
||||||
Procedure AddRegDeallocFor(asmL: paasmOutput; reg: TRegister; p: pai);
|
Procedure AddRegDeallocFor(asmL: paasmOutput; reg: TRegister; p: pai);
|
||||||
@ -422,7 +426,10 @@ var hp1: pai;
|
|||||||
funcResRegs: TRegset;
|
funcResRegs: TRegset;
|
||||||
funcResReg: boolean;
|
funcResReg: boolean;
|
||||||
begin
|
begin
|
||||||
getFuncResRegs(funcResRegs);
|
if not(reg in usableregs) then
|
||||||
|
exit;
|
||||||
|
getNoDeallocRegs(funcResRegs);
|
||||||
|
funcResRegs := funcResRegs - usableregs;
|
||||||
funcResReg := reg in funcResRegs;
|
funcResReg := reg in funcResRegs;
|
||||||
hp1 := p;
|
hp1 := p;
|
||||||
while not(funcResReg and
|
while not(funcResReg and
|
||||||
@ -434,7 +441,8 @@ begin
|
|||||||
hp1 := p;
|
hp1 := p;
|
||||||
{ don't insert a dealloc for registers which contain the function result }
|
{ don't insert a dealloc for registers which contain the function result }
|
||||||
{ if they are followed by a jump to the exit label (for exit(...)) }
|
{ if they are followed by a jump to the exit label (for exit(...)) }
|
||||||
if not((hp1^.typ = ait_instruction) and
|
if not(funcResReg) or
|
||||||
|
not((hp1^.typ = ait_instruction) and
|
||||||
(paicpu(hp1)^.opcode = A_JMP) and
|
(paicpu(hp1)^.opcode = A_JMP) and
|
||||||
(pasmlabel(paicpu(hp1)^.oper[0].sym) = aktexit2label)) then
|
(pasmlabel(paicpu(hp1)^.oper[0].sym) = aktexit2label)) then
|
||||||
begin
|
begin
|
||||||
@ -449,7 +457,7 @@ Procedure BuildLabelTableAndFixRegAlloc(asmL: PAasmOutput; Var LabelTable: PLabe
|
|||||||
Also fixes some RegDeallocs like "# %eax released; push (%eax)"}
|
Also fixes some RegDeallocs like "# %eax released; push (%eax)"}
|
||||||
Var p, hp1, hp2, lastP: Pai;
|
Var p, hp1, hp2, lastP: Pai;
|
||||||
regCounter: TRegister;
|
regCounter: TRegister;
|
||||||
UsedRegs, funcResRegs: TRegSet;
|
UsedRegs, noDeallocRegs: TRegSet;
|
||||||
Begin
|
Begin
|
||||||
UsedRegs := [];
|
UsedRegs := [];
|
||||||
If (LabelDif <> 0) Then
|
If (LabelDif <> 0) Then
|
||||||
@ -510,9 +518,9 @@ Begin
|
|||||||
until not(Assigned(p)) or
|
until not(Assigned(p)) or
|
||||||
not(p^.typ in (SkipInstr - [ait_regalloc]));
|
not(p^.typ in (SkipInstr - [ait_regalloc]));
|
||||||
End;
|
End;
|
||||||
{ don't add deallocation for function result variable }
|
{ don't add deallocation for function result variable or for regvars}
|
||||||
getFuncResRegs(funcResRegs);
|
getNoDeallocRegs(noDeallocRegs);
|
||||||
usedRegs := usedRegs - funcResRegs;
|
usedRegs := usedRegs - noDeallocRegs;
|
||||||
for regCounter := R_EAX to R_EDI do
|
for regCounter := R_EAX to R_EDI do
|
||||||
if regCounter in usedRegs then
|
if regCounter in usedRegs then
|
||||||
addRegDeallocFor(asmL,regCounter,lastP);
|
addRegDeallocFor(asmL,regCounter,lastP);
|
||||||
@ -2121,7 +2129,12 @@ End.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.80 2000-01-28 15:15:31 jonas
|
Revision 1.81 2000-02-04 13:52:17 jonas
|
||||||
|
* better support for regvars (still needs a move of the call to the optimize
|
||||||
|
procedure to a place where resetusableregisters is not yet called to work)
|
||||||
|
* small regallocation fixes for -dnewoptimizations
|
||||||
|
|
||||||
|
Revision 1.80 2000/01/28 15:15:31 jonas
|
||||||
* moved skipinstr from daopt386 to aasm
|
* moved skipinstr from daopt386 to aasm
|
||||||
* fixed crashing bug with -dreplacereg in csopt386.pas
|
* fixed crashing bug with -dreplacereg in csopt386.pas
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user