* modified patch by Gareth Moreton to pool TmpUsedRegs in the assembler optimizers, resolves #34679

git-svn-id: trunk@40938 -
This commit is contained in:
florian 2019-01-20 14:16:38 +00:00
parent 1b31c90bba
commit 94d7a02fae
6 changed files with 60 additions and 74 deletions

View File

@ -36,6 +36,9 @@ Unit aopt;
Type Type
TAsmOptimizer = class(TAoptObj) TAsmOptimizer = class(TAoptObj)
{ Pooled object that can be used by optimisation procedures to evaluate
future register usage without upsetting the current state. }
TmpUsedRegs: TAllUsedRegs;
{ _AsmL is the PAasmOutpout list that has to be optimized } { _AsmL is the PAasmOutpout list that has to be optimized }
Constructor create(_AsmL: TAsmList); virtual; reintroduce; Constructor create(_AsmL: TAsmList); virtual; reintroduce;
@ -87,6 +90,7 @@ Unit aopt;
inherited create(_asml,nil,nil,nil); inherited create(_asml,nil,nil,nil);
{ setup labeltable, always necessary } { setup labeltable, always necessary }
New(LabelInfo); New(LabelInfo);
CreateUsedRegs(TmpUsedRegs);
End; End;
procedure TAsmOptimizer.FindLoHiLabels; procedure TAsmOptimizer.FindLoHiLabels;
@ -318,6 +322,7 @@ Unit aopt;
Destructor TAsmOptimizer.Destroy; Destructor TAsmOptimizer.Destroy;
Begin Begin
ReleaseUsedRegs(TmpUsedRegs);
if assigned(LabelInfo^.LabelTable) then if assigned(LabelInfo^.LabelTable) then
Freemem(LabelInfo^.LabelTable); Freemem(LabelInfo^.LabelTable);
Dispose(LabelInfo); Dispose(LabelInfo);

View File

@ -270,6 +270,8 @@ Unit AoptObj;
Procedure UpdateUsedRegs(p : Tai); Procedure UpdateUsedRegs(p : Tai);
class procedure UpdateUsedRegs(var Regs: TAllUsedRegs; p: Tai); class procedure UpdateUsedRegs(var Regs: TAllUsedRegs; p: Tai);
Function CopyUsedRegs(var dest : TAllUsedRegs) : boolean; Function CopyUsedRegs(var dest : TAllUsedRegs) : boolean;
procedure RestoreUsedRegs(const Regs : TAllUsedRegs);
procedure TransferUsedRegs(var dest: TAllUsedRegs);
class Procedure ReleaseUsedRegs(const regs : TAllUsedRegs); class Procedure ReleaseUsedRegs(const regs : TAllUsedRegs);
class Function RegInUsedRegs(reg : TRegister;regs : TAllUsedRegs) : boolean; class Function RegInUsedRegs(reg : TRegister;regs : TAllUsedRegs) : boolean;
class Procedure IncludeRegInUsedRegs(reg : TRegister;var regs : TAllUsedRegs); class Procedure IncludeRegInUsedRegs(reg : TRegister;var regs : TAllUsedRegs);
@ -457,7 +459,7 @@ Unit AoptObj;
End; End;
Function TUsedRegs.GetUsedRegs: TRegSet; Function TUsedRegs.GetUsedRegs: TRegSet; inline;
Begin Begin
GetUsedRegs := UsedRegs; GetUsedRegs := UsedRegs;
End; End;
@ -945,6 +947,30 @@ Unit AoptObj;
end; end;
procedure TAOptObj.RestoreUsedRegs(const Regs: TAllUsedRegs);
var
i : TRegisterType;
begin
{ Note that the constructor Create_Regset is being called as a regular
method - it is not instantiating a new object. This is because it is
the only published means to modify the internal state en-masse. [Kit] }
for i:=low(TRegisterType) to high(TRegisterType) do
UsedRegs[i].Create_Regset(i,Regs[i].GetUsedRegs);
end;
procedure TAOptObj.TransferUsedRegs(var dest: TAllUsedRegs);
var
i : TRegisterType;
begin
{ Note that the constructor Create_Regset is being called as a regular
method - it is not instantiating a new object. This is because it is
the only published means to modify the internal state en-masse. [Kit] }
for i:=low(TRegisterType) to high(TRegisterType) do
dest[i].Create_Regset(i, UsedRegs[i].GetUsedRegs);
end;
class procedure TAOptObj.ReleaseUsedRegs(const regs: TAllUsedRegs); class procedure TAOptObj.ReleaseUsedRegs(const regs: TAllUsedRegs);
var var
i : TRegisterType; i : TRegisterType;

View File

@ -646,7 +646,6 @@ Implementation
var var
hp1,hp2,hp3,hp4: tai; hp1,hp2,hp3,hp4: tai;
i, i2: longint; i, i2: longint;
TmpUsedRegs: TAllUsedRegs;
tempop: tasmop; tempop: tasmop;
oldreg: tregister; oldreg: tregister;
dealloc: tai_regalloc; dealloc: tai_regalloc;
@ -932,7 +931,7 @@ Implementation
MatchInstruction(hp2, A_STR, [taicpu(p).condition], [PF_H]) and MatchInstruction(hp2, A_STR, [taicpu(p).condition], [PF_H]) and
MatchOperand(taicpu(hp2).oper[0]^, taicpu(p).oper[0]^.reg) then MatchOperand(taicpu(hp2).oper[0]^, taicpu(p).oper[0]^.reg) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
UpdateUsedRegs(TmpUsedRegs, tai(hp1.next)); UpdateUsedRegs(TmpUsedRegs, tai(hp1.next));
if not(RegUsedAfterInstruction(taicpu(p).oper[0]^.reg,hp2,TmpUsedRegs)) then if not(RegUsedAfterInstruction(taicpu(p).oper[0]^.reg,hp2,TmpUsedRegs)) then
@ -946,7 +945,6 @@ Implementation
p:=hp2; p:=hp2;
Result:=true; Result:=true;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end end
{ fold { fold
mov reg1,reg0, shift imm1 mov reg1,reg0, shift imm1

View File

@ -231,7 +231,6 @@ Implementation
alloc, dealloc: tai_regalloc; alloc, dealloc: tai_regalloc;
i: integer; i: integer;
l: TAsmLabel; l: TAsmLabel;
TmpUsedRegs : TAllUsedRegs;
begin begin
result := false; result := false;
case p.typ of case p.typ of
@ -325,7 +324,7 @@ Implementation
(taicpu(hp1).oper[1]^.reg=taicpu(p).oper[0]^.reg) and (taicpu(hp1).oper[1]^.reg=taicpu(p).oper[0]^.reg) and
not(MatchOperand(taicpu(hp1).oper[0]^,taicpu(hp1).oper[1]^)) then not(MatchOperand(taicpu(hp1).oper[0]^,taicpu(hp1).oper[1]^)) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
if not(RegUsedAfterInstruction(taicpu(hp1).oper[1]^.reg, hp1, TmpUsedRegs)) then if not(RegUsedAfterInstruction(taicpu(hp1).oper[1]^.reg, hp1, TmpUsedRegs)) then
begin begin
case taicpu(hp1).opcode of case taicpu(hp1).opcode of
@ -353,7 +352,6 @@ Implementation
RemoveCurrentP(p); RemoveCurrentP(p);
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end; end;
end; end;
A_STS: A_STS:
@ -690,14 +688,12 @@ Implementation
taicpu(hp1).loadreg(0, taicpu(hp2).oper[0]^.reg); taicpu(hp1).loadreg(0, taicpu(hp2).oper[0]^.reg);
{ life range of reg2 and reg3 is increased, fix register allocation entries } { life range of reg2 and reg3 is increased, fix register allocation entries }
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs,tai(p.Next)); UpdateUsedRegs(TmpUsedRegs,tai(p.Next));
AllocRegBetween(taicpu(hp2).oper[0]^.reg,hp1,hp2,TmpUsedRegs); AllocRegBetween(taicpu(hp2).oper[0]^.reg,hp1,hp2,TmpUsedRegs);
ReleaseUsedRegs(TmpUsedRegs);
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
AllocRegBetween(taicpu(hp3).oper[0]^.reg,p,hp3,TmpUsedRegs); AllocRegBetween(taicpu(hp3).oper[0]^.reg,p,hp3,TmpUsedRegs);
ReleaseUsedRegs(TmpUsedRegs);
IncludeRegInUsedRegs(taicpu(hp3).oper[0]^.reg,UsedRegs); IncludeRegInUsedRegs(taicpu(hp3).oper[0]^.reg,UsedRegs);
UpdateUsedRegs(tai(p.Next)); UpdateUsedRegs(tai(p.Next));
@ -750,7 +746,7 @@ Implementation
} }
if MatchOpType(taicpu(p),top_reg,top_reg) then if MatchOpType(taicpu(p),top_reg,top_reg) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs,tai(p.Next)); UpdateUsedRegs(TmpUsedRegs,tai(p.Next));
if not(RegInUsedRegs(taicpu(p).oper[0]^.reg,TmpUsedRegs)) and if not(RegInUsedRegs(taicpu(p).oper[0]^.reg,TmpUsedRegs)) and
{ reg. allocation information before calls is not perfect, so don't do this before { reg. allocation information before calls is not perfect, so don't do this before
@ -760,10 +756,8 @@ Implementation
begin begin
DebugMsg('Peephole Mov2Nop performed', p); DebugMsg('Peephole Mov2Nop performed', p);
result:=RemoveCurrentP(p); result:=RemoveCurrentP(p);
ReleaseUsedRegs(TmpUsedRegs);
exit; exit;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end; end;
{ turn { turn

View File

@ -237,7 +237,6 @@ unit aoptcpu;
function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean; function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean;
var var
next,next2: tai; next,next2: tai;
TmpUsedRegs: TAllUsedRegs;
begin begin
result:=false; result:=false;
case p.typ of case p.typ of
@ -262,7 +261,7 @@ unit aoptcpu;
{ the initial register may not be reused } { the initial register may not be reused }
(not RegUsedBetween(taicpu(p).oper[0]^.reg,next,next2)) then (not RegUsedBetween(taicpu(p).oper[0]^.reg,next,next2)) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
UpdateUsedRegs(TmpUsedRegs, tai(next.next)); UpdateUsedRegs(TmpUsedRegs, tai(next.next));
if not RegUsedAfterInstruction(taicpu(p).oper[2]^.reg,next2,TmpUsedRegs) then if not RegUsedAfterInstruction(taicpu(p).oper[2]^.reg,next2,TmpUsedRegs) then
@ -275,7 +274,6 @@ unit aoptcpu;
next.free; next.free;
p:=next2; p:=next2;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end end
else else
TryRemoveMov(p,A_MOV); TryRemoveMov(p,A_MOV);
@ -300,7 +298,7 @@ unit aoptcpu;
{ the initial register may not be reused } { the initial register may not be reused }
(not RegUsedBetween(taicpu(p).oper[0]^.reg,next,next2)) then (not RegUsedBetween(taicpu(p).oper[0]^.reg,next,next2)) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
UpdateUsedRegs(TmpUsedRegs, tai(next.next)); UpdateUsedRegs(TmpUsedRegs, tai(next.next));
if not RegUsedAfterInstruction(taicpu(p).oper[2]^.reg,next2,TmpUsedRegs) then if not RegUsedAfterInstruction(taicpu(p).oper[2]^.reg,next2,TmpUsedRegs) then
@ -313,7 +311,6 @@ unit aoptcpu;
next.free; next.free;
p:=next2; p:=next2;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end end
else else
TryRemoveMov(p,A_MOV); TryRemoveMov(p,A_MOV);
@ -388,7 +385,7 @@ unit aoptcpu;
(taicpu(next).oper[0]^.typ=top_reg) and (taicpu(next).oper[0]^.typ=top_reg) and
(taicpu(next).oper[0]^.reg=taicpu(p).oper[2]^.reg) then (taicpu(next).oper[0]^.reg=taicpu(p).oper[2]^.reg) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
if not RegUsedAfterInstruction(taicpu(p).oper[2]^.reg,next,TmpUsedRegs) then if not RegUsedAfterInstruction(taicpu(p).oper[2]^.reg,next,TmpUsedRegs) then
begin begin
@ -397,7 +394,6 @@ unit aoptcpu;
p.free; p.free;
p:=next; p:=next;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end end
else else
TryRemoveMov(p,A_MOV); TryRemoveMov(p,A_MOV);

View File

@ -583,7 +583,6 @@ unit aoptx86;
end; end;
{$endif DEBUG_AOPTCPU} {$endif DEBUG_AOPTCPU}
function TX86AsmOptimizer.Reg1WriteOverwritesReg2Entirely(reg1, reg2: tregister): boolean; function TX86AsmOptimizer.Reg1WriteOverwritesReg2Entirely(reg1, reg2: tregister): boolean;
begin begin
if not SuperRegistersEqual(reg1,reg2) then if not SuperRegistersEqual(reg1,reg2) then
@ -1032,7 +1031,6 @@ unit aoptx86;
function TX86AsmOptimizer.OptPass1MOVAP(var p : tai) : boolean; function TX86AsmOptimizer.OptPass1MOVAP(var p : tai) : boolean;
var var
TmpUsedRegs : TAllUsedRegs;
hp1,hp2 : tai; hp1,hp2 : tai;
begin begin
result:=false; result:=false;
@ -1059,7 +1057,7 @@ unit aoptx86;
addsX/subsX/... reg3,reg addsX/subsX/... reg3,reg
} }
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
UpdateUsedRegs(TmpUsedRegs, tai(hp1.next)); UpdateUsedRegs(TmpUsedRegs, tai(hp1.next));
If not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then If not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then
@ -1081,14 +1079,12 @@ unit aoptx86;
p:=hp1; p:=hp1;
result:=true; result:=true;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end end
end; end;
function TX86AsmOptimizer.OptPass1VMOVAP(var p : tai) : boolean; function TX86AsmOptimizer.OptPass1VMOVAP(var p : tai) : boolean;
var var
TmpUsedRegs : TAllUsedRegs;
hp1,hp2 : tai; hp1,hp2 : tai;
begin begin
result:=false; result:=false;
@ -1116,7 +1112,7 @@ unit aoptx86;
dealloc reg2 dealloc reg2
=> =>
vmova* reg1,reg3 } vmova* reg1,reg3 }
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp1,TmpUsedRegs)) then if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp1,TmpUsedRegs)) then
begin begin
@ -1145,7 +1141,7 @@ unit aoptx86;
MatchInstruction(hp2,A_VMOVAPD,A_VMOVAPS,[S_NO]) and MatchInstruction(hp2,A_VMOVAPD,A_VMOVAPS,[S_NO]) and
MatchOperand(taicpu(p).oper[0]^,taicpu(hp2).oper[1]^) then MatchOperand(taicpu(p).oper[0]^,taicpu(hp2).oper[1]^) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
UpdateUsedRegs(TmpUsedRegs, tai(hp1.next)); UpdateUsedRegs(TmpUsedRegs, tai(hp1.next));
if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs))
@ -1166,7 +1162,6 @@ unit aoptx86;
function TX86AsmOptimizer.OptPass1VOP(var p : tai) : boolean; function TX86AsmOptimizer.OptPass1VOP(var p : tai) : boolean;
var var
TmpUsedRegs : TAllUsedRegs;
hp1 : tai; hp1 : tai;
begin begin
result:=false; result:=false;
@ -1186,7 +1181,7 @@ unit aoptx86;
MatchOperand(taicpu(p).oper[2]^,taicpu(hp1).oper[0]^) and MatchOperand(taicpu(p).oper[2]^,taicpu(hp1).oper[0]^) and
(taicpu(hp1).oper[1]^.typ=top_reg) then (taicpu(hp1).oper[1]^.typ=top_reg) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
if not(RegUsedAfterInstruction(taicpu(hp1).oper[0]^.reg,hp1,TmpUsedRegs) if not(RegUsedAfterInstruction(taicpu(hp1).oper[0]^.reg,hp1,TmpUsedRegs)
) then ) then
@ -1204,7 +1199,6 @@ unit aoptx86;
function TX86AsmOptimizer.OptPass1MOV(var p : tai) : boolean; function TX86AsmOptimizer.OptPass1MOV(var p : tai) : boolean;
var var
hp1, hp2: tai; hp1, hp2: tai;
TmpUsedRegs : TAllUsedRegs;
GetNextInstruction_p: Boolean; GetNextInstruction_p: Boolean;
PreMessage, RegName1, RegName2, InputVal, MaskNum: string; PreMessage, RegName1, RegName2, InputVal, MaskNum: string;
NewSize: topsize; NewSize: topsize;
@ -1337,10 +1331,10 @@ unit aoptx86;
taicpu(p).oper[1]^ := taicpu(hp1).oper[1]^; taicpu(p).oper[1]^ := taicpu(hp1).oper[1]^;
{ Safeguard if "and" is followed by a conditional command } { Safeguard if "and" is followed by a conditional command }
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs,tai(hp1.next)); UpdateUsedRegs(TmpUsedRegs,tai(p.next));
if (RegUsedAfterInstruction(NR_DEFAULTFLAGS, tai(hp1.next), TmpUsedRegs)) then if (RegUsedAfterInstruction(NR_DEFAULTFLAGS, hp1, TmpUsedRegs)) then
begin begin
{ At this point, the "and" command is effectively equivalent to { At this point, the "and" command is effectively equivalent to
"test %reg,%reg". This will be handled separately by the "test %reg,%reg". This will be handled separately by the
@ -1359,8 +1353,6 @@ unit aoptx86;
end; end;
Result := True; Result := True;
ReleaseUsedRegs(TmpUsedRegs);
Exit; Exit;
end; end;
@ -1371,7 +1363,7 @@ unit aoptx86;
(taicpu(p).oper[1]^.typ = top_reg) and (taicpu(p).oper[1]^.typ = top_reg) and
MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[0]^) then MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[0]^) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.Next)); UpdateUsedRegs(TmpUsedRegs, tai(p.Next));
{ we have { we have
mov x, %treg mov x, %treg
@ -1402,7 +1394,6 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization + 'MovMov2Mov 2 done',p); DebugMsg(SPeepholeOptimization + 'MovMov2Mov 2 done',p);
asml.remove(hp1); asml.remove(hp1);
hp1.free; hp1.free;
ReleaseUsedRegs(TmpUsedRegs);
Result:=true; Result:=true;
Exit; Exit;
end; end;
@ -1425,7 +1416,6 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization + 'MovMov2Mov 5 done',p); DebugMsg(SPeepholeOptimization + 'MovMov2Mov 5 done',p);
asml.remove(hp1); asml.remove(hp1);
hp1.free; hp1.free;
ReleaseUsedRegs(TmpUsedRegs);
Result:=true; Result:=true;
Exit; Exit;
end; end;
@ -1445,12 +1435,10 @@ unit aoptx86;
DebugMsg(SPeepholeOptimization + 'MovMov2Mov 3 done',p); DebugMsg(SPeepholeOptimization + 'MovMov2Mov 3 done',p);
asml.remove(hp1); asml.remove(hp1);
hp1.free; hp1.free;
ReleaseUsedRegs(TmpUsedRegs);
Result:=true; Result:=true;
Exit; Exit;
end; end;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end end
else else
{ Change { Change
@ -1486,7 +1474,7 @@ unit aoptx86;
test/or/and %reg2, %reg2 test/or/and %reg2, %reg2
} }
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
{ reg1 will be used after the first instruction, { reg1 will be used after the first instruction,
so update the allocation info } so update the allocation info }
AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,usedregs); AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,usedregs);
@ -1512,7 +1500,6 @@ unit aoptx86;
asml.remove(p); asml.remove(p);
p.free; p.free;
p := hp1; p := hp1;
ReleaseUsedRegs(TmpUsedRegs);
Exit; Exit;
end end
else else
@ -1532,7 +1519,6 @@ unit aoptx86;
taicpu(hp1).loadoper(1,taicpu(p).oper[0]^); taicpu(hp1).loadoper(1,taicpu(p).oper[0]^);
DebugMsg(SPeepholeOptimization + 'MovTestJxx2MovTestJxx done',p); DebugMsg(SPeepholeOptimization + 'MovTestJxx2MovTestJxx done',p);
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end end
end end
else else
@ -1606,7 +1592,7 @@ unit aoptx86;
end end
else else
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(hp1.next)); UpdateUsedRegs(TmpUsedRegs, tai(hp1.next));
if (taicpu(p).oper[1]^.typ = top_ref) and if (taicpu(p).oper[1]^.typ = top_ref) and
{ mov reg1, mem1 { mov reg1, mem1
@ -1631,7 +1617,6 @@ unit aoptx86;
AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,UsedRegs); AllocRegBetween(taicpu(p).oper[0]^.reg,p,hp1,UsedRegs);
DebugMsg(SPeepholeOptimization + 'MovMovCmp2MovCmp done',hp1); DebugMsg(SPeepholeOptimization + 'MovMovCmp2MovCmp done',hp1);
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end; end;
end end
else if (taicpu(p).oper[1]^.typ=top_ref) and else if (taicpu(p).oper[1]^.typ=top_ref) and
@ -1643,7 +1628,7 @@ unit aoptx86;
end end
else else
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
if GetNextInstruction(hp1, hp2) and if GetNextInstruction(hp1, hp2) and
MatchOpType(taicpu(p),top_ref,top_reg) and MatchOpType(taicpu(p),top_ref,top_reg) and
MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[0]^) and MatchOperand(taicpu(p).oper[1]^,taicpu(hp1).oper[0]^) and
@ -1715,7 +1700,6 @@ unit aoptx86;
end end
{$endif i386} {$endif i386}
; ;
ReleaseUsedRegs(TmpUsedRegs);
end; end;
end end
(* { movl [mem1],reg1 (* { movl [mem1],reg1
@ -1801,7 +1785,7 @@ unit aoptx86;
to to
add/sub/or/... reg3/$const, reg/ref } add/sub/or/... reg3/$const, reg/ref }
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
UpdateUsedRegs(TmpUsedRegs, tai(hp1.next)); UpdateUsedRegs(TmpUsedRegs, tai(hp1.next));
If not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then If not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then
@ -1855,7 +1839,6 @@ unit aoptx86;
hp2.Free; hp2.Free;
p := hp1; p := hp1;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end end
{$ifndef x86_64} {$ifndef x86_64}
else if MatchOpType(taicpu(hp2),top_reg,top_reg) and else if MatchOpType(taicpu(hp2),top_reg,top_reg) and
@ -1875,7 +1858,7 @@ unit aoptx86;
add/sub/or/... reg3/$const, reg3 add/sub/or/... reg3/$const, reg3
} }
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
UpdateUsedRegs(TmpUsedRegs, tai(hp1.next)); UpdateUsedRegs(TmpUsedRegs, tai(hp1.next));
If not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then If not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp2,TmpUsedRegs)) then
@ -1932,7 +1915,6 @@ unit aoptx86;
hp2.Free; hp2.Free;
// p := hp1; // p := hp1;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end; end;
{$endif x86_64} {$endif x86_64}
end end
@ -1973,7 +1955,7 @@ unit aoptx86;
add reg2,ref} add reg2,ref}
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
{ reg1 may not be used afterwards } { reg1 may not be used afterwards }
if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs)) then if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs)) then
begin begin
@ -1984,7 +1966,6 @@ unit aoptx86;
p.free; p.free;
p:=hp1; p:=hp1;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end; end;
end; end;
@ -2044,7 +2025,6 @@ unit aoptx86;
function TX86AsmOptimizer.OptPass1OP(var p : tai) : boolean; function TX86AsmOptimizer.OptPass1OP(var p : tai) : boolean;
var var
TmpUsedRegs : TAllUsedRegs;
hp1 : tai; hp1 : tai;
begin begin
result:=false; result:=false;
@ -2065,7 +2045,7 @@ unit aoptx86;
MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[1]^) and MatchOperand(taicpu(p).oper[0]^,taicpu(hp1).oper[1]^) and
(taicpu(p).oper[0]^.typ=top_reg) then (taicpu(p).oper[0]^.typ=top_reg) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp1,TmpUsedRegs)) then if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp1,TmpUsedRegs)) then
begin begin
@ -2076,7 +2056,6 @@ unit aoptx86;
hp1.Free; hp1.Free;
result:=true; result:=true;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end; end;
end; end;
@ -2085,7 +2064,6 @@ unit aoptx86;
var var
hp1 : tai; hp1 : tai;
l : ASizeInt; l : ASizeInt;
TmpUsedRegs : TAllUsedRegs;
begin begin
Result:=false; Result:=false;
{ removes seg register prefixes from LEA operations, as they { removes seg register prefixes from LEA operations, as they
@ -2167,7 +2145,7 @@ unit aoptx86;
MatchOpType(Taicpu(hp1),top_reg,top_reg) and MatchOpType(Taicpu(hp1),top_reg,top_reg) and
(taicpu(p).oper[1]^.reg<>NR_STACK_POINTER_REG) then (taicpu(p).oper[1]^.reg<>NR_STACK_POINTER_REG) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp1,TmpUsedRegs)) then if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,hp1,TmpUsedRegs)) then
begin begin
@ -2177,7 +2155,6 @@ unit aoptx86;
hp1.Free; hp1.Free;
result:=true; result:=true;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end; end;
end; end;
@ -2405,7 +2382,6 @@ unit aoptx86;
function TX86AsmOptimizer.OptPass1SETcc(var p: tai): boolean; function TX86AsmOptimizer.OptPass1SETcc(var p: tai): boolean;
var var
TmpUsedRegs : TAllUsedRegs;
hp1,hp2,next: tai; SetC, JumpC: TAsmCond; hp1,hp2,next: tai; SetC, JumpC: TAsmCond;
begin begin
Result:=false; Result:=false;
@ -2432,10 +2408,9 @@ unit aoptx86;
begin begin
next := tai(p.Next); next := tai(p.Next);
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, next); UpdateUsedRegs(TmpUsedRegs, next);
UpdateUsedRegs(TmpUsedRegs, tai(hp1.next)); UpdateUsedRegs(TmpUsedRegs, tai(hp1.next));
UpdateUsedRegs(TmpUsedRegs, tai(hp2.next));
asml.Remove(hp1); asml.Remove(hp1);
hp1.Free; hp1.Free;
@ -2463,8 +2438,6 @@ unit aoptx86;
p := hp2; p := hp2;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
DebugMsg(SPeepholeOptimization + 'SETcc/TEST/Jcc -> Jcc',p); DebugMsg(SPeepholeOptimization + 'SETcc/TEST/Jcc -> Jcc',p);
end; end;
end; end;
@ -2472,7 +2445,6 @@ unit aoptx86;
function TX86AsmOptimizer.OptPass2MOV(var p : tai) : boolean; function TX86AsmOptimizer.OptPass2MOV(var p : tai) : boolean;
var var
TmpUsedRegs : TAllUsedRegs;
hp1,hp2: tai; hp1,hp2: tai;
{$ifdef x86_64} {$ifdef x86_64}
hp3: tai; hp3: tai;
@ -2497,9 +2469,8 @@ unit aoptx86;
{ Don't remove the MOV command without first checking that reg2 isn't used afterwards, { Don't remove the MOV command without first checking that reg2 isn't used afterwards,
or unless supreg(reg3) = supreg(reg2)). [Kit] } or unless supreg(reg3) = supreg(reg2)). [Kit] }
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs, tai(p.next)); UpdateUsedRegs(TmpUsedRegs, tai(p.next));
UpdateUsedRegs(TmpUsedRegs, tai(hp1.next));
if (getsupreg(taicpu(p).oper[1]^.reg) = getsupreg(taicpu(hp1).oper[1]^.reg)) or if (getsupreg(taicpu(p).oper[1]^.reg) = getsupreg(taicpu(hp1).oper[1]^.reg)) or
not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs) not RegUsedAfterInstruction(taicpu(p).oper[1]^.reg, hp1, TmpUsedRegs)
@ -2511,7 +2482,6 @@ unit aoptx86;
Result:=true; Result:=true;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
exit; exit;
end end
else if MatchOpType(taicpu(p),top_reg,top_reg) and else if MatchOpType(taicpu(p),top_reg,top_reg) and
@ -2569,7 +2539,7 @@ unit aoptx86;
MatchOperand(taicpu(hp1).oper[taicpu(hp1).ops-1]^,taicpu(hp2).oper[0]^) and MatchOperand(taicpu(hp1).oper[taicpu(hp1).ops-1]^,taicpu(hp2).oper[0]^) and
(taicpu(hp2).oper[1]^.typ = top_ref) then (taicpu(hp2).oper[1]^.typ = top_ref) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
UpdateUsedRegs(TmpUsedRegs,tai(p.next)); UpdateUsedRegs(TmpUsedRegs,tai(p.next));
UpdateUsedRegs(TmpUsedRegs,tai(hp1.next)); UpdateUsedRegs(TmpUsedRegs,tai(hp1.next));
if (RefsEqual(taicpu(hp2).oper[1]^.ref^,taicpu(p).oper[0]^.ref^) and if (RefsEqual(taicpu(hp2).oper[1]^.ref^,taicpu(p).oper[0]^.ref^) and
@ -2604,7 +2574,6 @@ unit aoptx86;
hp2.free; hp2.free;
p := hp1 p := hp1
end; end;
ReleaseUsedRegs(TmpUsedRegs);
Exit; Exit;
{$ifdef x86_64} {$ifdef x86_64}
end end
@ -2706,7 +2675,6 @@ unit aoptx86;
function TX86AsmOptimizer.OptPass2Imul(var p : tai) : boolean; function TX86AsmOptimizer.OptPass2Imul(var p : tai) : boolean;
var var
TmpUsedRegs : TAllUsedRegs;
hp1 : tai; hp1 : tai;
begin begin
Result:=false; Result:=false;
@ -2723,7 +2691,7 @@ unit aoptx86;
((taicpu(hp1).oper[1]^.reg = taicpu(p).oper[1]^.reg) or ((taicpu(hp1).oper[1]^.reg = taicpu(p).oper[1]^.reg) or
((taicpu(hp1).opsize=S_L) and (taicpu(p).opsize=S_Q) and SuperRegistersEqual(taicpu(hp1).oper[1]^.reg,taicpu(p).oper[1]^.reg))) then ((taicpu(hp1).opsize=S_L) and (taicpu(p).opsize=S_Q) and SuperRegistersEqual(taicpu(hp1).oper[1]^.reg,taicpu(p).oper[1]^.reg))) then
begin begin
CopyUsedRegs(TmpUsedRegs); TransferUsedRegs(TmpUsedRegs);
if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,p,TmpUsedRegs)) then if not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,p,TmpUsedRegs)) then
{ change { change
mov reg1,reg2 mov reg1,reg2
@ -2737,7 +2705,6 @@ unit aoptx86;
hp1.free; hp1.free;
result:=true; result:=true;
end; end;
ReleaseUsedRegs(TmpUsedRegs);
end; end;
end; end;