* Added some code to keep track of move instructions in register

allocator
This commit is contained in:
daniel 2003-04-17 16:48:21 +00:00
parent 9ee89e71d7
commit 0c93e261e7
3 changed files with 67 additions and 33 deletions

View File

@ -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

View File

@ -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

View File

@ -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