mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-25 03:58:30 +02:00
* Added some code to keep track of move instructions in register
allocator
This commit is contained in:
parent
9ee89e71d7
commit
0c93e261e7
@ -152,10 +152,20 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure emit_reg_reg(i : tasmop;s : topsize;reg1,reg2 : tregister);
|
procedure emit_reg_reg(i : tasmop;s : topsize;reg1,reg2 : tregister);
|
||||||
|
|
||||||
|
var instr:Taicpu;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if not ((reg1.enum=R_INTREGISTER) and (reg2.enum<>R_INTREGISTER) and
|
if not ((reg1.enum=R_INTREGISTER) and (reg2.enum=R_INTREGISTER) and
|
||||||
(reg1.number=reg2.number) and (i=A_MOV)) then
|
(reg1.number=reg2.number) and (i=A_MOV)) then
|
||||||
exprasmlist.concat(Taicpu.op_reg_reg(i,s,reg1,reg2));
|
begin
|
||||||
|
instr:=Taicpu.op_reg_reg(i,s,reg1,reg2);
|
||||||
|
exprasmlist.concat(instr);
|
||||||
|
{$ifdef newra}
|
||||||
|
if i=A_MOV then
|
||||||
|
rg.add_move_instruction(instr);
|
||||||
|
{$endif newra}
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure emit_const_reg_reg(i : tasmop;s : topsize;c : longint;reg1,reg2 : tregister);
|
procedure emit_const_reg_reg(i : tasmop;s : topsize;c : longint;reg1,reg2 : tregister);
|
||||||
@ -176,7 +186,11 @@ implementation
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.37 2003-03-08 08:59:07 daniel
|
Revision 1.38 2003-04-17 16:48:21 daniel
|
||||||
|
* Added some code to keep track of move instructions in register
|
||||||
|
allocator
|
||||||
|
|
||||||
|
Revision 1.37 2003/03/08 08:59:07 daniel
|
||||||
+ $define newra will enable new register allocator
|
+ $define newra will enable new register allocator
|
||||||
+ getregisterint will return imaginary registers with $newra
|
+ getregisterint will return imaginary registers with $newra
|
||||||
+ -sr switch added, will skip register allocation so you can see
|
+ -sr switch added, will skip register allocation so you can see
|
||||||
|
@ -108,6 +108,13 @@ unit rgobj;
|
|||||||
end;
|
end;
|
||||||
Pinterferencegraph=^Tinterferencegraph;
|
Pinterferencegraph=^Tinterferencegraph;
|
||||||
|
|
||||||
|
Tmoveset=(ms_coalesced_moves,ms_constrained_moves,ms_frozen_moves,
|
||||||
|
ms_worklist_moves,ms_activemoves);
|
||||||
|
Tmoveins=class(Tlinkedlistitem)
|
||||||
|
moveset:Tmoveset;
|
||||||
|
instruction:Taicpu;
|
||||||
|
end;
|
||||||
|
|
||||||
{#
|
{#
|
||||||
This class implements the abstract register allocator
|
This class implements the abstract register allocator
|
||||||
It is used by the code generator to allocate and free
|
It is used by the code generator to allocate and free
|
||||||
@ -291,6 +298,8 @@ unit rgobj;
|
|||||||
protected
|
protected
|
||||||
{$ifdef newra}
|
{$ifdef newra}
|
||||||
igraph:Tinterferencegraph;
|
igraph:Tinterferencegraph;
|
||||||
|
movelist:array[Tsuperregister] of Tlinkedlist;
|
||||||
|
worklistmoves:Tlinkedlist;
|
||||||
{$endif}
|
{$endif}
|
||||||
{ the following two contain the common (generic) code for all }
|
{ the following two contain the common (generic) code for all }
|
||||||
{ get- and ungetregisterxxx functions/procedures }
|
{ get- and ungetregisterxxx functions/procedures }
|
||||||
@ -414,6 +423,8 @@ unit rgobj;
|
|||||||
{$endif TEMPREGDEBUG}
|
{$endif TEMPREGDEBUG}
|
||||||
{$ifdef newra}
|
{$ifdef newra}
|
||||||
fillchar(igraph,sizeof(igraph),0);
|
fillchar(igraph,sizeof(igraph),0);
|
||||||
|
fillchar(movelist,sizeof(movelist),0);
|
||||||
|
worklistmoves.create;
|
||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -741,9 +752,14 @@ unit rgobj;
|
|||||||
unusedregsmm:=usableregsmm;
|
unusedregsmm:=usableregsmm;
|
||||||
{$ifdef newra}
|
{$ifdef newra}
|
||||||
for i:=low(Tsuperregister) to high(Tsuperregister) do
|
for i:=low(Tsuperregister) to high(Tsuperregister) do
|
||||||
|
begin
|
||||||
if igraph.adjlist[i]<>nil then
|
if igraph.adjlist[i]<>nil then
|
||||||
dispose(igraph.adjlist[i]);
|
dispose(igraph.adjlist[i]);
|
||||||
|
if movelist[i]<>nil then
|
||||||
|
movelist[i].destroy;
|
||||||
|
end;
|
||||||
fillchar(igraph,sizeof(igraph),0);
|
fillchar(igraph,sizeof(igraph),0);
|
||||||
|
worklistmoves.destroy;
|
||||||
{$endif}
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1381,7 +1397,11 @@ end.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.33 2003-04-17 07:50:24 daniel
|
Revision 1.34 2003-04-17 16:48:21 daniel
|
||||||
|
* Added some code to keep track of move instructions in register
|
||||||
|
allocator
|
||||||
|
|
||||||
|
Revision 1.33 2003/04/17 07:50:24 daniel
|
||||||
* Some work on interference graph construction
|
* Some work on interference graph construction
|
||||||
|
|
||||||
Revision 1.32 2003/03/28 19:16:57 peter
|
Revision 1.32 2003/03/28 19:16:57 peter
|
||||||
|
@ -479,6 +479,7 @@ unit cgx86;
|
|||||||
op: tasmop;
|
op: tasmop;
|
||||||
s: topsize;
|
s: topsize;
|
||||||
eq:boolean;
|
eq:boolean;
|
||||||
|
instr:Taicpu;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if (reg1.enum=R_INTREGISTER) and (reg2.enum=R_INTREGISTER) then
|
if (reg1.enum=R_INTREGISTER) and (reg2.enum=R_INTREGISTER) then
|
||||||
@ -493,24 +494,14 @@ unit cgx86;
|
|||||||
{ "mov reg1, reg1" doesn't make sense }
|
{ "mov reg1, reg1" doesn't make sense }
|
||||||
if op = A_MOV then
|
if op = A_MOV then
|
||||||
exit;
|
exit;
|
||||||
{ optimize movzx with "and ffff,<reg>" operation }
|
|
||||||
if (op = A_MOVZX) then
|
|
||||||
begin
|
|
||||||
case fromsize of
|
|
||||||
OS_8:
|
|
||||||
begin
|
|
||||||
list.concat(taicpu.op_const_reg(A_AND,reg2opsize(reg2),255,reg2));
|
|
||||||
exit;
|
|
||||||
end;
|
end;
|
||||||
OS_16:
|
instr:=taicpu.op_reg_reg(op,s,reg1,reg2);
|
||||||
begin
|
{Notify the register allocator that we have written a move instruction so
|
||||||
list.concat(taicpu.op_const_reg(A_AND,reg2opsize(reg2),65535,reg2));
|
it can try to eliminate it.}
|
||||||
exit;
|
{$ifdef newra}
|
||||||
end;
|
rg.add_move_instruction(instr);
|
||||||
end;
|
{$endif}
|
||||||
end;
|
list.concat(instr);
|
||||||
end;
|
|
||||||
list.concat(taicpu.op_reg_reg(op,s,reg1,reg2));
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -791,6 +782,7 @@ unit cgx86;
|
|||||||
tmpreg : tregister;
|
tmpreg : tregister;
|
||||||
popecx : boolean;
|
popecx : boolean;
|
||||||
r:Tregister;
|
r:Tregister;
|
||||||
|
instr:Taicpu;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
if src.enum<>R_INTREGISTER then
|
if src.enum<>R_INTREGISTER then
|
||||||
@ -875,8 +867,12 @@ unit cgx86;
|
|||||||
begin
|
begin
|
||||||
if reg2opsize(src) <> dstsize then
|
if reg2opsize(src) <> dstsize then
|
||||||
internalerror(200109226);
|
internalerror(200109226);
|
||||||
list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,
|
instr:=taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,src,dst);
|
||||||
src,dst));
|
{$ifdef newra}
|
||||||
|
if op in [_MOV,_XCHG] then
|
||||||
|
rg.add_move_instruction(instr);
|
||||||
|
{$endif newra}
|
||||||
|
list.concat(instr);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1441,7 +1437,7 @@ unit cgx86;
|
|||||||
{ align stack on 4 bytes }
|
{ align stack on 4 bytes }
|
||||||
list.concat(Taicpu.op_const_reg(A_AND,S_L,$fffffff4,rsp));
|
list.concat(Taicpu.op_const_reg(A_AND,S_L,$fffffff4,rsp));
|
||||||
{ load destination }
|
{ load destination }
|
||||||
list.concat(Taicpu.op_reg_reg(A_MOV,S_L,rsp,r));
|
a_load_reg_reg(list,OS_INT,OS_INT,rsp,r);
|
||||||
|
|
||||||
{ don't destroy the registers! }
|
{ don't destroy the registers! }
|
||||||
r2.number:=NR_ECX;
|
r2.number:=NR_ECX;
|
||||||
@ -1451,11 +1447,11 @@ unit cgx86;
|
|||||||
|
|
||||||
{ load count }
|
{ load count }
|
||||||
r2.number:=NR_ECX;
|
r2.number:=NR_ECX;
|
||||||
list.concat(Taicpu.op_ref_reg(A_MOV,S_L,lenref,r2));
|
a_load_ref_reg(list,OS_INT,lenref,r2);
|
||||||
|
|
||||||
{ load source }
|
{ load source }
|
||||||
r2.number:=NR_ESI;
|
r2.number:=NR_ESI;
|
||||||
list.concat(Taicpu.op_ref_reg(A_MOV,S_L,ref,r2));
|
a_load_ref_reg(list,OS_INT,ref,r2);
|
||||||
|
|
||||||
{ scheduled .... }
|
{ scheduled .... }
|
||||||
r2.number:=NR_ECX;
|
r2.number:=NR_ECX;
|
||||||
@ -1493,7 +1489,7 @@ unit cgx86;
|
|||||||
list.concat(Taicpu.op_reg(A_POP,S_L,r2));
|
list.concat(Taicpu.op_reg(A_POP,S_L,r2));
|
||||||
|
|
||||||
{ patch the new address }
|
{ patch the new address }
|
||||||
list.concat(Taicpu.op_reg_ref(A_MOV,S_L,rsp,ref));
|
a_load_reg_ref(list,OS_INT,rsp,ref);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1843,7 +1839,11 @@ unit cgx86;
|
|||||||
end.
|
end.
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.37 2003-03-28 19:16:57 peter
|
Revision 1.38 2003-04-17 16:48:21 daniel
|
||||||
|
* Added some code to keep track of move instructions in register
|
||||||
|
allocator
|
||||||
|
|
||||||
|
Revision 1.37 2003/03/28 19:16:57 peter
|
||||||
* generic constructor working for i386
|
* generic constructor working for i386
|
||||||
* remove fixed self register
|
* remove fixed self register
|
||||||
* esi added as address register for i386
|
* esi added as address register for i386
|
||||||
|
Loading…
Reference in New Issue
Block a user