mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 06:49:13 +02:00
* CSE of constant loading in regs works properly again
+ if a constant is stored into memory using "mov const, ref" and there is a reg that contains this const, it is changed into "mov reg, ref"
This commit is contained in:
parent
514f0f9879
commit
8272526892
@ -486,7 +486,10 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
Procedure ClearRegContentsFrom(reg: TRegister; p: pai);
|
Procedure ClearRegContentsFrom(reg: TRegister; p: pai);
|
||||||
var hp: pai;
|
var
|
||||||
|
{$ifdef replaceregdebug}
|
||||||
|
hp: pai;
|
||||||
|
{$endif replaceregdebug}
|
||||||
tmpState: byte;
|
tmpState: byte;
|
||||||
begin
|
begin
|
||||||
tmpState := PPaiProp(p^.optInfo)^.Regs[reg].wState;
|
tmpState := PPaiProp(p^.optInfo)^.Regs[reg].wState;
|
||||||
@ -756,6 +759,39 @@ begin
|
|||||||
End;
|
End;
|
||||||
{$endif replacereg}
|
{$endif replacereg}
|
||||||
|
|
||||||
|
{$ifdef arithopt}
|
||||||
|
Function FindRegWithConst(p: Pai; size: topsize; l: longint; Var Res: TRegister): Boolean;
|
||||||
|
{Finds a register which contains the constant l}
|
||||||
|
Var Counter: TRegister;
|
||||||
|
{$ifdef testing}
|
||||||
|
hp: pai;
|
||||||
|
{$endif testing}
|
||||||
|
tmpresult: boolean;
|
||||||
|
Begin
|
||||||
|
Counter := R_NO;
|
||||||
|
repeat
|
||||||
|
inc(counter);
|
||||||
|
tmpresult := (PPaiProp(p^.OptInfo)^.Regs[Counter].Typ = Con_Const) and
|
||||||
|
(paicpu(PPaiProp(p^.OptInfo)^.Regs[Counter].StartMod)^.opsize = size) and
|
||||||
|
(paicpu(PPaiProp(p^.OptInfo)^.Regs[Counter].StartMod)^.oper[0].val = l);
|
||||||
|
{$ifdef testing}
|
||||||
|
if (PPaiProp(p^.OptInfo)^.Regs[Counter].Typ = Con_Const) then
|
||||||
|
begin
|
||||||
|
hp := new(pai_asm_comment,init(strpnew(
|
||||||
|
'checking const load of '+tostr(l)+' here...')));
|
||||||
|
hp^.next := PPaiProp(p^.OptInfo)^.Regs[Counter].StartMod;
|
||||||
|
hp^.previous := PPaiProp(p^.OptInfo)^.Regs[Counter].StartMod^.previous;
|
||||||
|
PPaiProp(p^.OptInfo)^.Regs[Counter].StartMod^.previous := hp;
|
||||||
|
if assigned(hp^.previous) then
|
||||||
|
hp^.previous^.next := hp;
|
||||||
|
end;
|
||||||
|
{$endif testing}
|
||||||
|
until tmpresult or (Counter = R_EDI);
|
||||||
|
res := counter;
|
||||||
|
FindRegWithConst := tmpResult;
|
||||||
|
End;
|
||||||
|
{$endif arithopt}
|
||||||
|
|
||||||
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
|
||||||
@ -980,10 +1016,16 @@ Begin
|
|||||||
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[Reg32(Paicpu(p)^.oper[1].reg)] Do
|
||||||
If (Typ = Con_Const) And
|
If (Typ = Con_Const) And
|
||||||
(StartMod = p) Then
|
(paicpu(startMod)^.opsize >= paicpu(p)^.opsize) and
|
||||||
|
(paicpu(StartMod)^.oper[0].val = paicpu(p)^.oper[0].val) Then
|
||||||
PPaiProp(p^.OptInfo)^.CanBeRemoved := True;
|
PPaiProp(p^.OptInfo)^.CanBeRemoved := True;
|
||||||
End;
|
End;
|
||||||
{ Top_Ref:;}
|
{$ifdef arithopt}
|
||||||
|
Top_Ref:
|
||||||
|
if getLastInstruction(p,hp1) and
|
||||||
|
findRegWithConst(hp1,paicpu(p)^.opsize,paicpu(p)^.oper[0].val,regCounter) then
|
||||||
|
paicpu(p)^.loadreg(0,regCounter);
|
||||||
|
{$endif arithopt}
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
@ -991,16 +1033,6 @@ Begin
|
|||||||
A_STD: If GetLastInstruction(p, hp1) And
|
A_STD: If GetLastInstruction(p, hp1) And
|
||||||
(PPaiProp(hp1^.OptInfo)^.DirFlag = F_Set) Then
|
(PPaiProp(hp1^.OptInfo)^.DirFlag = F_Set) Then
|
||||||
PPaiProp(Pai(p)^.OptInfo)^.CanBeRemoved := True;
|
PPaiProp(Pai(p)^.OptInfo)^.CanBeRemoved := True;
|
||||||
A_XOR:
|
|
||||||
Begin
|
|
||||||
If (Paicpu(p)^.oper[0].typ = top_reg) And
|
|
||||||
(Paicpu(p)^.oper[0].typ = top_reg) And
|
|
||||||
(Paicpu(p)^.oper[1].reg = Paicpu(p)^.oper[1].reg) And
|
|
||||||
GetLastInstruction(p, hp1) And
|
|
||||||
(PPaiProp(hp1^.OptInfo)^.Regs[Reg32(Paicpu(p)^.oper[1].reg)].typ = con_const) And
|
|
||||||
(PPaiProp(hp1^.OptInfo)^.Regs[Reg32(Paicpu(p)^.oper[1].reg)].StartMod = nil)
|
|
||||||
Then PPaiProp(p^.OptInfo)^.CanBeRemoved := True
|
|
||||||
End
|
|
||||||
End
|
End
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
@ -1061,7 +1093,13 @@ End.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.35 1999-12-02 11:26:41 peter
|
Revision 1.36 1999-12-05 16:48:43 jonas
|
||||||
|
* CSE of constant loading in regs works properly again
|
||||||
|
+ if a constant is stored into memory using "mov const, ref" and
|
||||||
|
there is a reg that contains this const, it is changed into
|
||||||
|
"mov reg, ref"
|
||||||
|
|
||||||
|
Revision 1.35 1999/12/02 11:26:41 peter
|
||||||
* newoptimizations define added
|
* newoptimizations define added
|
||||||
|
|
||||||
Revision 1.34 1999/11/21 13:09:41 jonas
|
Revision 1.34 1999/11/21 13:09:41 jonas
|
||||||
|
@ -115,8 +115,7 @@ type
|
|||||||
|
|
||||||
TContent = Packed Record
|
TContent = Packed Record
|
||||||
{start and end of block instructions that defines the
|
{start and end of block instructions that defines the
|
||||||
content of this register. If Typ = con_const, then
|
content of this register.}
|
||||||
Longint(StartMod) = value of the constant)}
|
|
||||||
StartMod: pai;
|
StartMod: pai;
|
||||||
{starts at 0, gets increased everytime the register is written to}
|
{starts at 0, gets increased everytime the register is written to}
|
||||||
WState: Byte;
|
WState: Byte;
|
||||||
@ -818,23 +817,6 @@ Begin
|
|||||||
Not(Pai_Label(p)^.l^.is_used)));
|
Not(Pai_Label(p)^.l^.is_used)));
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
|
||||||
(*Function FindZeroreg(p: Pai; Var Result: TRegister): Boolean;
|
|
||||||
{Finds a register which contains the constant zero}
|
|
||||||
Var Counter: TRegister;
|
|
||||||
Begin
|
|
||||||
Counter := R_EAX;
|
|
||||||
FindZeroReg := True;
|
|
||||||
While (Counter <= R_EDI) And
|
|
||||||
((PPaiProp(p^.OptInfo)^.Regs[Counter].Typ <> Con_Const) or
|
|
||||||
(PPaiProp(p^.OptInfo)^.Regs[Counter].StartMod <> Pointer(0))) Do
|
|
||||||
Inc(Byte(Counter));
|
|
||||||
If (PPaiProp(p^.OptInfo)^.Regs[Counter].Typ = Con_Const) And
|
|
||||||
(PPaiProp(p^.OptInfo)^.Regs[Counter].StartMod = Pointer(0))
|
|
||||||
Then Result := Counter
|
|
||||||
Else FindZeroReg := False;
|
|
||||||
End;*)
|
|
||||||
|
|
||||||
Procedure IncState(Var S: Byte);
|
Procedure IncState(Var S: Byte);
|
||||||
{Increases S by 1, wraps around at $ffff to 0 (so we won't get overflow
|
{Increases S by 1, wraps around at $ffff to 0 (so we won't get overflow
|
||||||
errors}
|
errors}
|
||||||
@ -1744,22 +1726,15 @@ Begin
|
|||||||
DestroyOp(p, Paicpu(p)^.oper[2]);
|
DestroyOp(p, Paicpu(p)^.oper[2]);
|
||||||
{$endif arithopt}
|
{$endif arithopt}
|
||||||
End;
|
End;
|
||||||
A_XOR:
|
{$ifdef arithopt}
|
||||||
Begin
|
A_LEA:
|
||||||
ReadOp(CurProp, Paicpu(p)^.oper[0]);
|
begin
|
||||||
ReadOp(CurProp, Paicpu(p)^.oper[1]);
|
readop(curprop,paicpu(p)^.oper[0]);
|
||||||
If (Paicpu(p)^.oper[0].typ = top_reg) And
|
if reginref(paicpu(p)^.oper[1].reg,paicpu(p)^.oper[0].ref^) then
|
||||||
(Paicpu(p)^.oper[1].typ = top_reg) And
|
AddInstr2RegContents(paicpu(p), paicpu(p)^.oper[1].reg)
|
||||||
(Paicpu(p)^.oper[0].reg = Paicpu(p)^.oper[1].reg)
|
else destroyreg(curprop,paicpu(p)^.oper[1].reg,true);
|
||||||
Then
|
end;
|
||||||
Begin
|
{$endif arithopt}
|
||||||
DestroyReg(CurProp, Paicpu(p)^.oper[0].reg, true);
|
|
||||||
CurProp^.Regs[Reg32(Paicpu(p)^.oper[0].reg)].typ := Con_Const;
|
|
||||||
CurProp^.Regs[Reg32(Paicpu(p)^.oper[0].reg)].StartMod := Pointer(0)
|
|
||||||
End
|
|
||||||
Else
|
|
||||||
DestroyOp(p, Paicpu(p)^.oper[1]);
|
|
||||||
End
|
|
||||||
Else
|
Else
|
||||||
Begin
|
Begin
|
||||||
Cnt := 1;
|
Cnt := 1;
|
||||||
@ -1943,7 +1918,13 @@ End.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.74 1999-12-02 11:26:41 peter
|
Revision 1.75 1999-12-05 16:48:43 jonas
|
||||||
|
* CSE of constant loading in regs works properly again
|
||||||
|
+ if a constant is stored into memory using "mov const, ref" and
|
||||||
|
there is a reg that contains this const, it is changed into
|
||||||
|
"mov reg, ref"
|
||||||
|
|
||||||
|
Revision 1.74 1999/12/02 11:26:41 peter
|
||||||
* newoptimizations define added
|
* newoptimizations define added
|
||||||
|
|
||||||
Revision 1.73 1999/11/27 23:45:43 jonas
|
Revision 1.73 1999/11/27 23:45:43 jonas
|
||||||
|
@ -1061,15 +1061,6 @@ Begin
|
|||||||
Paicpu(p)^.LoadReg(1,Paicpu(hp1)^.oper[0].reg);
|
Paicpu(p)^.LoadReg(1,Paicpu(hp1)^.oper[0].reg);
|
||||||
End
|
End
|
||||||
End;
|
End;
|
||||||
{changes "mov $0, %reg" into "xor %reg, %reg"}
|
|
||||||
If (Paicpu(p)^.oper[0].typ = Top_Const) And
|
|
||||||
(Paicpu(p)^.oper[0].val = 0) And
|
|
||||||
(Paicpu(p)^.oper[1].typ = Top_Reg)
|
|
||||||
Then
|
|
||||||
Begin
|
|
||||||
Paicpu(p)^.opcode := A_XOR;
|
|
||||||
Paicpu(p)^.LoadReg(0,Paicpu(p)^.oper[1].reg);
|
|
||||||
End;
|
|
||||||
End;
|
End;
|
||||||
A_MOVZX:
|
A_MOVZX:
|
||||||
Begin
|
Begin
|
||||||
@ -1545,9 +1536,17 @@ Begin
|
|||||||
End
|
End
|
||||||
End
|
End
|
||||||
Else
|
Else
|
||||||
|
|
||||||
|
|
||||||
End;
|
End;
|
||||||
|
A_XOR:
|
||||||
|
If (Paicpu(p)^.oper[0].typ = top_reg) And
|
||||||
|
(Paicpu(p)^.oper[1].typ = top_reg) And
|
||||||
|
(Paicpu(p)^.oper[0].reg = Paicpu(p)^.oper[1].reg) then
|
||||||
|
{ temporarily change this to 'mov reg,0' to make it easier }
|
||||||
|
{ for the CSE. Will be changed back in pass 2 }
|
||||||
|
begin
|
||||||
|
paicpu(p)^.opcode := A_MOV;
|
||||||
|
paicpu(p)^.loadconst(0,0);
|
||||||
|
end;
|
||||||
End;
|
End;
|
||||||
end; { if is_jmp }
|
end; { if is_jmp }
|
||||||
End;
|
End;
|
||||||
@ -1674,8 +1673,16 @@ Begin
|
|||||||
Dispose(hp2,Done);
|
Dispose(hp2,Done);
|
||||||
p := hp1
|
p := hp1
|
||||||
End;
|
End;
|
||||||
End;
|
End
|
||||||
{$endif foldArithOps}
|
{$endif foldArithOps}
|
||||||
|
else if (Paicpu(p)^.oper[0].typ = Top_Const) And
|
||||||
|
(Paicpu(p)^.oper[0].val = 0) And
|
||||||
|
(Paicpu(p)^.oper[1].typ = Top_Reg) Then
|
||||||
|
{ change "mov $0, %reg" into "xor %reg, %reg" }
|
||||||
|
Begin
|
||||||
|
Paicpu(p)^.opcode := A_XOR;
|
||||||
|
Paicpu(p)^.LoadReg(0,Paicpu(p)^.oper[1].reg);
|
||||||
|
End
|
||||||
End;
|
End;
|
||||||
A_MOVZX:
|
A_MOVZX:
|
||||||
Begin
|
Begin
|
||||||
@ -1735,7 +1742,13 @@ End.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.73 1999-12-02 11:26:41 peter
|
Revision 1.74 1999-12-05 16:48:43 jonas
|
||||||
|
* CSE of constant loading in regs works properly again
|
||||||
|
+ if a constant is stored into memory using "mov const, ref" and
|
||||||
|
there is a reg that contains this const, it is changed into
|
||||||
|
"mov reg, ref"
|
||||||
|
|
||||||
|
Revision 1.73 1999/12/02 11:26:41 peter
|
||||||
* newoptimizations define added
|
* newoptimizations define added
|
||||||
|
|
||||||
Revision 1.72 1999/11/30 10:40:45 peter
|
Revision 1.72 1999/11/30 10:40:45 peter
|
||||||
|
Loading…
Reference in New Issue
Block a user