* 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,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

View File

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

View File

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