mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-31 10:42:33 +02:00
* Added some code to keep track of move instructions in register
allocator
This commit is contained in:
parent
9ee89e71d7
commit
0c93e261e7
@ -152,11 +152,21 @@ implementation
|
||||
end;
|
||||
|
||||
procedure emit_reg_reg(i : tasmop;s : topsize;reg1,reg2 : tregister);
|
||||
begin
|
||||
if not ((reg1.enum=R_INTREGISTER) and (reg2.enum<>R_INTREGISTER) and
|
||||
(reg1.number=reg2.number) and (i=A_MOV)) then
|
||||
exprasmlist.concat(Taicpu.op_reg_reg(i,s,reg1,reg2));
|
||||
end;
|
||||
|
||||
var instr:Taicpu;
|
||||
|
||||
begin
|
||||
if not ((reg1.enum=R_INTREGISTER) and (reg2.enum=R_INTREGISTER) and
|
||||
(reg1.number=reg2.number) and (i=A_MOV)) then
|
||||
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;
|
||||
|
||||
procedure emit_const_reg_reg(i : tasmop;s : topsize;c : longint;reg1,reg2 : tregister);
|
||||
begin
|
||||
@ -176,7 +186,11 @@ implementation
|
||||
end.
|
||||
{
|
||||
$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
|
||||
+ getregisterint will return imaginary registers with $newra
|
||||
+ -sr switch added, will skip register allocation so you can see
|
||||
|
@ -108,6 +108,13 @@ unit rgobj;
|
||||
end;
|
||||
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
|
||||
It is used by the code generator to allocate and free
|
||||
@ -291,6 +298,8 @@ unit rgobj;
|
||||
protected
|
||||
{$ifdef newra}
|
||||
igraph:Tinterferencegraph;
|
||||
movelist:array[Tsuperregister] of Tlinkedlist;
|
||||
worklistmoves:Tlinkedlist;
|
||||
{$endif}
|
||||
{ the following two contain the common (generic) code for all }
|
||||
{ get- and ungetregisterxxx functions/procedures }
|
||||
@ -414,6 +423,8 @@ unit rgobj;
|
||||
{$endif TEMPREGDEBUG}
|
||||
{$ifdef newra}
|
||||
fillchar(igraph,sizeof(igraph),0);
|
||||
fillchar(movelist,sizeof(movelist),0);
|
||||
worklistmoves.create;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
@ -741,9 +752,14 @@ unit rgobj;
|
||||
unusedregsmm:=usableregsmm;
|
||||
{$ifdef newra}
|
||||
for i:=low(Tsuperregister) to high(Tsuperregister) do
|
||||
if igraph.adjlist[i]<>nil then
|
||||
dispose(igraph.adjlist[i]);
|
||||
begin
|
||||
if igraph.adjlist[i]<>nil then
|
||||
dispose(igraph.adjlist[i]);
|
||||
if movelist[i]<>nil then
|
||||
movelist[i].destroy;
|
||||
end;
|
||||
fillchar(igraph,sizeof(igraph),0);
|
||||
worklistmoves.destroy;
|
||||
{$endif}
|
||||
end;
|
||||
|
||||
@ -1381,7 +1397,11 @@ end.
|
||||
|
||||
{
|
||||
$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
|
||||
|
||||
Revision 1.32 2003/03/28 19:16:57 peter
|
||||
|
@ -479,6 +479,7 @@ unit cgx86;
|
||||
op: tasmop;
|
||||
s: topsize;
|
||||
eq:boolean;
|
||||
instr:Taicpu;
|
||||
|
||||
begin
|
||||
if (reg1.enum=R_INTREGISTER) and (reg2.enum=R_INTREGISTER) then
|
||||
@ -493,24 +494,14 @@ unit cgx86;
|
||||
{ "mov reg1, reg1" doesn't make sense }
|
||||
if op = A_MOV then
|
||||
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;
|
||||
OS_16:
|
||||
begin
|
||||
list.concat(taicpu.op_const_reg(A_AND,reg2opsize(reg2),65535,reg2));
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
list.concat(taicpu.op_reg_reg(op,s,reg1,reg2));
|
||||
instr:=taicpu.op_reg_reg(op,s,reg1,reg2);
|
||||
{Notify the register allocator that we have written a move instruction so
|
||||
it can try to eliminate it.}
|
||||
{$ifdef newra}
|
||||
rg.add_move_instruction(instr);
|
||||
{$endif}
|
||||
list.concat(instr);
|
||||
end;
|
||||
|
||||
|
||||
@ -791,6 +782,7 @@ unit cgx86;
|
||||
tmpreg : tregister;
|
||||
popecx : boolean;
|
||||
r:Tregister;
|
||||
instr:Taicpu;
|
||||
|
||||
begin
|
||||
if src.enum<>R_INTREGISTER then
|
||||
@ -875,8 +867,12 @@ unit cgx86;
|
||||
begin
|
||||
if reg2opsize(src) <> dstsize then
|
||||
internalerror(200109226);
|
||||
list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,
|
||||
src,dst));
|
||||
instr:=taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,src,dst);
|
||||
{$ifdef newra}
|
||||
if op in [_MOV,_XCHG] then
|
||||
rg.add_move_instruction(instr);
|
||||
{$endif newra}
|
||||
list.concat(instr);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -1441,7 +1437,7 @@ unit cgx86;
|
||||
{ align stack on 4 bytes }
|
||||
list.concat(Taicpu.op_const_reg(A_AND,S_L,$fffffff4,rsp));
|
||||
{ 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! }
|
||||
r2.number:=NR_ECX;
|
||||
@ -1451,11 +1447,11 @@ unit cgx86;
|
||||
|
||||
{ load count }
|
||||
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 }
|
||||
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 .... }
|
||||
r2.number:=NR_ECX;
|
||||
@ -1493,7 +1489,7 @@ unit cgx86;
|
||||
list.concat(Taicpu.op_reg(A_POP,S_L,r2));
|
||||
|
||||
{ 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;
|
||||
|
||||
|
||||
@ -1843,7 +1839,11 @@ unit cgx86;
|
||||
end.
|
||||
{
|
||||
$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
|
||||
* remove fixed self register
|
||||
* esi added as address register for i386
|
||||
|
Loading…
Reference in New Issue
Block a user