* made worklists dynamic in size

This commit is contained in:
peter 2003-10-18 15:41:26 +00:00
parent 42f14d3bfd
commit 9f54e1b7c5
4 changed files with 126 additions and 123 deletions

View File

@ -390,13 +390,6 @@ interface
function docompare(p : tnode) : boolean;override;
end;
{$ifdef tempregdebug}
type
pptree = ^tnode;
var
curptree: pptree;
{$endif tempregdebug}
var
{ array with all class types for tnodes }
nodeclass : tnodeclassarray;
@ -976,7 +969,10 @@ implementation
end.
{
$Log$
Revision 1.70 2003-10-17 01:22:08 florian
Revision 1.71 2003-10-18 15:41:26 peter
* made worklists dynamic in size
Revision 1.70 2003/10/17 01:22:08 florian
* compilation of the powerpc compiler fixed
Revision 1.69 2003/10/08 19:19:45 peter

View File

@ -159,11 +159,6 @@ implementation
oldcodegenerror : boolean;
oldlocalswitches : tlocalswitches;
oldpos : tfileposinfo;
{$ifdef TEMPREGDEBUG}
prevp : pptree;
{$endif TEMPREGDEBUG}
{$ifdef EXTDEBUG}
{$endif EXTDEBUG}
begin
if not assigned(p) then
internalerror(200208221);
@ -195,31 +190,12 @@ implementation
else if (p.location.loc<>p.expectloc) then
Comment(V_Warning,'Location is different in secondpass: '+nodetype2str[p.nodetype]);
end;
{$ifdef i386}
{
if cg.rgint.unusedregsint*([first_int_supreg..last_int_supreg] - [RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG])<>
([first_int_supreg..last_int_supreg] - [RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]) then
internalerror(200306171);
}
{$endif i386}
{$endif EXTDEBUG}
if codegenerror then
include(p.flags,nf_error);
codegenerror:=codegenerror or oldcodegenerror;
aktlocalswitches:=oldlocalswitches;
aktfilepos:=oldpos;
{$ifdef TEMPREGDEBUG}
curptree:=prevp;
{$endif TEMPREGDEBUG}
{$ifdef EXTTEMPREGDEBUG}
if p.usableregs-usablereg32>p.reallyusedregs then
p.reallyusedregs:=p.usableregs-usablereg32;
if p.reallyusedregs<p.registers32 then
Comment(V_Debug,'registers32 overestimated '+tostr(p^.registers32)+
'>'+tostr(p^.reallyusedregs));
{$endif EXTTEMPREGDEBUG}
end
else
codegenerror:=true;
@ -302,7 +278,10 @@ implementation
end.
{
$Log$
Revision 1.70 2003-10-17 15:08:34 peter
Revision 1.71 2003-10-18 15:41:26 peter
* made worklists dynamic in size
Revision 1.70 2003/10/17 15:08:34 peter
* commented out more obsolete constants
Revision 1.69 2003/10/10 17:48:13 peter

View File

@ -91,9 +91,6 @@ unit rgobj;
cpuinfo
;
const
maxworklist = 4096;
type
{
regvarother_longintarray = array[tregisterindex] of longint;
@ -104,12 +101,15 @@ unit rgobj;
tsuperregisterworklist=object
buflength,
buflengthinc,
length,
head,
tail : integer;
buf : array[0..maxworklist-1] of tsuperregister;
buf : ^tsuperregister;
constructor init;
destructor done;
procedure clear;
procedure next(var i:integer);
procedure add(s:tsuperregister);
function get:tsuperregister;
function getlast:tsuperregister;
@ -169,8 +169,8 @@ unit rgobj;
{ The register allocator assigns each register a colour }
colour : Tsuperregister;
movelist : Pmovelist;
degree : byte;
adjlist : Psuperregisterworklist;
degree : byte;
end;
Preginfo=^TReginfo;
@ -186,11 +186,9 @@ unit rgobj;
--------------------------------------------------------------------}
trgobj=class
preserved_by_proc : tcpuregisterset;
used_in_proc : Tsuperregisterset;
used_in_proc : tcpuregisterset;
// is_reg_var : Tsuperregisterset; {old regvars}
// reg_var_loaded:Tsuperregisterset; {old regvars}
reginfo : PReginfo;
spillednodes : tsuperregisterworklist;
constructor create(Aregtype:Tregistertype;
Adefaultsub:Tsubregister;
@ -235,22 +233,22 @@ unit rgobj;
{# Adds an interference edge.}
procedure add_edge(u,v:Tsuperregister);
unusedregs,usableregs:Tsuperregisterset;
protected
regtype : Tregistertype;
{ default subregister used }
defaultsub : tsubregister;
unusedregs : Tsuperregisterset;
{# First imaginary register.}
first_imaginary,
{# Last register allocated.}
lastused,
first_imaginary : Tsuperregister;
{# Highest register allocated until now.}
reginfo : PReginfo;
maxreginfo,
maxreginfoinc,
maxreg : Tsuperregister;
usable_registers_cnt : integer;
usable_registers : array[0..maxcpuregister-1] of tsuperregister;
ibitmap : Tinterferencebitmap;
spillednodes,
simplifyworklist,
freezeworklist,
spillworklist,
@ -303,9 +301,11 @@ implementation
constructor tsuperregisterworklist.init;
begin
length:=0;
buflength:=0;
buflengthinc:=16;
head:=0;
tail:=0;
fillchar(buf,sizeof(buf),0);
buf:=nil;
end;
@ -315,14 +315,54 @@ implementation
procedure tsuperregisterworklist.add(s:tsuperregister);
var
oldbuflength : integer;
newbuf : ^tsuperregister;
begin
if length>=maxworklist then
internalerror(200310141);
inc(length);
{ Need to increase buffer length? }
if length>=buflength then
begin
oldbuflength:=buflength;
inc(buflength,buflengthinc);
buflengthinc:=buflengthinc*2;
if buflengthinc>256 then
buflengthinc:=256;
{ We need to allocate a new block and move data around when the
tail is wrapped around }
if tail<head then
begin
Getmem(newbuf,buflength*sizeof(tsuperregister));
move(buf[0],newbuf[oldbuflength-head],tail*sizeof(tsuperregister));
move(buf[head],newbuf[0],(oldbuflength-head)*sizeof(tsuperregister));
Freemem(buf);
buf:=newbuf;
head:=0;
tail:=oldbuflength-1;
end
else
Reallocmem(buf,buflength*sizeof(tsuperregister));
end;
buf[tail]:=s;
inc(tail);
if tail>=maxworklist then
if tail>=buflength then
tail:=0;
inc(length);
end;
procedure tsuperregisterworklist.clear;
begin
length:=0;
tail:=0;
head:=0;
end;
procedure tsuperregisterworklist.next(var i:integer);
begin
inc(i);
if i>=buflength then
i:=0;
end;
@ -338,7 +378,7 @@ implementation
internalerror(200310144);
buf[i]:=buf[head];
inc(head);
if head>=maxworklist then
if head>=buflength then
head:=0;
dec(length);
end;
@ -350,7 +390,7 @@ implementation
internalerror(200310142);
result:=buf[head];
inc(head);
if head>=maxworklist then
if head>=buflength then
head:=0;
dec(length);
end;
@ -362,7 +402,7 @@ implementation
internalerror(200310143);
dec(tail);
if tail<0 then
tail:=maxworklist-1;
tail:=buflength-1;
result:=buf[tail];
dec(length);
end;
@ -383,7 +423,7 @@ implementation
exit;
end;
inc(i);
if i>=maxworklist then
if i>=buflength then
i:=0;
end;
end;
@ -403,7 +443,7 @@ implementation
exit;
end;
inc(i);
if i>=maxworklist then
if i>=buflength then
i:=0;
end;
end;
@ -465,13 +505,12 @@ implementation
var
i : Tsuperregister;
begin
lastused:=0;
first_imaginary:=Afirst_imaginary;
maxreg:=Afirst_imaginary;
regtype:=Aregtype;
defaultsub:=Adefaultsub;
preserved_by_proc:=Apreserved_by_proc;
supregset_reset(used_in_proc,false);
used_in_proc:=[];
supregset_reset(unusedregs,true);
{ RS_INVALID can't be used }
supregset_exclude(unusedregs,RS_INVALID);
@ -479,7 +518,7 @@ implementation
{ Get reginfo for CPU registers }
reginfo:=allocmem(first_imaginary*sizeof(treginfo));
maxreginfo:=first_imaginary;
maxreginfoinc:=32;
maxreginfoinc:=16;
for i:=0 to first_imaginary-1 do
reginfo[i].degree:=255;
worklist_moves:=Tlinkedlist.create;
@ -489,6 +528,13 @@ implementation
for i:=low(Ausable) to high(Ausable) do
usable_registers[i]:=Ausable[i];
usable_registers_cnt:=high(Ausable)+1;
{ Initialize Worklists }
spillednodes.init;
simplifyworklist.init;
freezeworklist.init;
spillworklist.init;
coalescednodes.init;
selectstack.init;
end;
destructor trgobj.destroy;
@ -496,6 +542,12 @@ implementation
var i:Tsuperregister;
begin
spillednodes.done;
simplifyworklist.done;
freezeworklist.done;
spillworklist.done;
coalescednodes.done;
selectstack.done;
for i:=0 to maxreg-1 do
begin
if reginfo[i].adjlist<>nil then
@ -522,7 +574,7 @@ implementation
oldmaxreginfo:=maxreginfo;
inc(maxreginfo,maxreginfoinc);
if maxreginfoinc<256 then
inc(maxreginfoinc,64);
maxreginfoinc:=maxreginfoinc*2;
reallocmem(reginfo,maxreginfo*sizeof(treginfo));
{ Do we really need it to clear it ? At least for 1.0.x (PFV) }
fillchar(reginfo[oldmaxreginfo],(maxreginfo-oldmaxreginfo)*sizeof(treginfo),0);
@ -536,7 +588,6 @@ implementation
begin
p:=getnewreg;
supregset_exclude(unusedregs,p);
supregset_include(used_in_proc,p);
r:=newreg(regtype,p,subreg);
list.concat(Tai_regalloc.alloc(r));
add_edges_used(p);
@ -576,7 +627,8 @@ implementation
if supregset_in(unusedregs,supreg) then
begin
supregset_exclude(unusedregs,supreg);
supregset_include(used_in_proc,supreg);
if supreg<first_imaginary then
include(used_in_proc,supreg);
list.concat(Tai_regalloc.alloc(r));
add_edges_used(supreg);
add_constraints(r);
@ -598,7 +650,7 @@ implementation
if unusedregs[0]*r=r then
begin
unusedregs[0]:=unusedregs[0]-r;
used_in_proc[0]:=used_in_proc[0]+r;
used_in_proc:=used_in_proc+r;
for i:=0 to first_imaginary-1 do
if i in r then
begin
@ -825,8 +877,8 @@ implementation
constrained_moves:=Tlinkedlist.create;
for i:=0 to maxreg-1 do
reginfo[i].alias:=RS_INVALID;
coalescednodes.init;
selectstack.init;
coalescednodes.clear;
selectstack.clear;
end;
procedure trgobj.enable_moves(n:Tsuperregister);
@ -877,9 +929,7 @@ implementation
if selectstack.find(n) or
coalescednodes.find(n) then
enable_moves(n);
inc(i);
if i>=maxworklist then
i:=0;
adj^.next(i);
end;
end;
{Remove the node from the spillworklist.}
@ -923,9 +973,7 @@ implementation
if min=0 then
break; {We won't find smaller ones.}
end;
inc(i);
if i>=maxworklist then
i:=0;
simplifyworklist.next(i);
end;
n:=simplifyworklist.getidx(p);
simplifyworklist.deleteidx(p);
@ -943,9 +991,7 @@ implementation
not(selectstack.find(n) or
coalescednodes.find(n)) then
decrement_degree(n);
inc(i);
if i>=maxworklist then
i:=0;
adj^.next(i);
end;
end;
end;
@ -1003,9 +1049,7 @@ implementation
adjacent_ok:=false;
break;
end;
inc(i);
if i>=maxworklist then
i:=0;
adj^.next(i);
end;
end;
end;
@ -1034,9 +1078,7 @@ implementation
if reginfo[n].degree>=usable_registers_cnt then
inc(k);
end;
inc(i);
if i>=maxworklist then
i:=0;
adj^.next(i);
end;
end;
adj:=reginfo[v].adjlist;
@ -1051,9 +1093,7 @@ implementation
not(selectstack.find(n) or
coalescednodes.find(n)) then
inc(k);
inc(i);
if i>=maxworklist then
i:=0;
adj^.next(i);
end;
end;
conservative:=(k<usable_registers_cnt);
@ -1115,9 +1155,7 @@ implementation
(reginfo[t].degree>0) then
dec(reginfo[t].degree);
end;
inc(i);
if i>=maxworklist then
i:=0;
adj^.next(i);
end;
end;
if (reginfo[u].degree>=usable_registers_cnt) and
@ -1253,9 +1291,7 @@ implementation
p:=i;
max:=adj^.length;
end;
inc(i);
if i>=maxworklist then
i:=0;
spillworklist.next(i);
end;
n:=spillworklist.getidx(p);
spillworklist.deleteidx(p);
@ -1275,7 +1311,7 @@ implementation
colourednodes : Tsuperregisterset;
found : boolean;
begin
spillednodes.init;
spillednodes.clear;
{Reset colours}
for n:=0 to maxreg-1 do
reginfo[n].colour:=n;
@ -1298,9 +1334,7 @@ implementation
a:=get_alias(adj^.buf[j]);
if supregset_in(colourednodes,a) then
supregset_include(adj_colours,reginfo[a].colour);
inc(j);
if j>=maxworklist then
j:=0;
adj^.next(j);
end;
supregset_include(adj_colours,RS_STACK_POINTER_REG);
end;
@ -1315,8 +1349,7 @@ implementation
reginfo[n].colour:=c;
found:=true;
supregset_include(colourednodes,n);
if supregset_in(used_in_proc,n) then
supregset_include(used_in_proc,c);
include(used_in_proc,c);
break;
end;
end;
@ -1330,11 +1363,8 @@ implementation
n:=coalescednodes.buf[i];
k:=get_alias(n);
reginfo[n].colour:=reginfo[k].colour;
if supregset_in(used_in_proc,n) then
supregset_include(used_in_proc,reginfo[k].colour);
inc(i);
if i>=maxworklist then
i:=0;
include(used_in_proc,reginfo[k].colour);
coalescednodes.next(i);
end;
{$ifdef ra_debug}
if aktfilepos.line=51 then
@ -1446,9 +1476,7 @@ implementation
reginfo[v].adjlist:=nil;
end;
end;
inc(i);
if i>=maxworklist then
i:=0;
adj^.next(i);
end;
{Remove ( u,* ) from adjacency list.}
dispose(adj,done);
@ -1520,7 +1548,6 @@ implementation
begin
p:=getnewreg;
supregset_exclude(unusedregs,p);
supregset_include(used_in_proc,p);
r:=newreg(regtype,p,subreg);
if position=nil then
list.insert(Tai_regalloc.alloc(r))
@ -1573,8 +1600,7 @@ implementation
if current_procinfo.framepointer=NR_FRAME_POINTER_REG then
{Make sure the register allocator won't allocate registers into ebp.}
supregset_exclude(unusedregs,RS_FRAME_POINTER_REG);
getmem(spill_temps,sizeof(treference)*maxreg);
fillchar(spill_temps^,sizeof(treference)*maxreg,0);
spill_temps:=allocmem(sizeof(treference)*maxreg);
supregset_reset(regs_to_spill_set,false);
{ Allocate temps and insert in front of the list }
templist:=taasmoutput.create;
@ -1588,9 +1614,7 @@ implementation
clear_interferences(t);
{Get a temp for the spilled register}
tg.gettemp(templist,4,tt_noreuse,spill_temps^[t]);
inc(i);
if i>=maxworklist then
i:=0;
spillednodes.next(i);
end;
list.insertlistafter(headertai,templist);
templist.free;
@ -1642,9 +1666,7 @@ end;
while (i<>spillednodes.tail) do
begin
tg.ungettemp(list,spill_temps^[spillednodes.buf[i]]);
inc(i);
if i>=maxworklist then
i:=0;
spillednodes.next(i);
end;
freemem(spill_temps);
end;
@ -1743,7 +1765,10 @@ end;
end.
{
$Log$
Revision 1.87 2003-10-17 16:16:08 peter
Revision 1.88 2003-10-18 15:41:26 peter
* made worklists dynamic in size
Revision 1.87 2003/10/17 16:16:08 peter
* fixed last commit
Revision 1.86 2003/10/17 15:25:18 florian

View File

@ -1508,7 +1508,7 @@ unit cgx86;
list.concat(Tai_section.Create(sec_code));
list.concat(Taicpu.Op_sym_ofs_reg(A_MOV,S_L,pl,0,NR_EDX));
a_call_name(list,target_info.Cprefix+'mcount');
supregset_include(rgint.used_in_proc,RS_EDX);
include(rgint.used_in_proc,RS_EDX);
end;
system_i386_go32v2,system_i386_watcom:
@ -1628,28 +1628,28 @@ unit cgx86;
begin
{ Get temp }
size:=0;
if supregset_in(rgint.used_in_proc,RS_EBX) then
if RS_EBX in rgint.used_in_proc then
inc(size,POINTER_SIZE);
if supregset_in(rgint.used_in_proc,RS_ESI) then
if RS_ESI in rgint.used_in_proc then
inc(size,POINTER_SIZE);
if supregset_in(rgint.used_in_proc,RS_EDI) then
if RS_EDI in rgint.used_in_proc then
inc(size,POINTER_SIZE);
if size>0 then
begin
tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref);
{ Copy registers to temp }
href:=current_procinfo.save_regs_ref;
if supregset_in(rgint.used_in_proc,RS_EBX) then
if RS_EBX in rgint.used_in_proc then
begin
a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_EBX,href);
inc(href.offset,POINTER_SIZE);
end;
if supregset_in(rgint.used_in_proc,RS_ESI) then
if RS_ESI in rgint.used_in_proc then
begin
a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_ESI,href);
inc(href.offset,POINTER_SIZE);
end;
if supregset_in(rgint.used_in_proc,RS_EDI) then
if RS_EDI in rgint.used_in_proc then
begin
a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_EDI,href);
inc(href.offset,POINTER_SIZE);
@ -1667,17 +1667,17 @@ unit cgx86;
begin
{ Copy registers from temp }
href:=current_procinfo.save_regs_ref;
if supregset_in(rgint.used_in_proc,RS_EBX) then
if RS_EBX in rgint.used_in_proc then
begin
a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EBX);
inc(href.offset,POINTER_SIZE);
end;
if supregset_in(rgint.used_in_proc,RS_ESI) then
if RS_ESI in rgint.used_in_proc then
begin
a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_ESI);
inc(href.offset,POINTER_SIZE);
end;
if supregset_in(rgint.used_in_proc,RS_EDI) then
if RS_EDI in rgint.used_in_proc then
begin
a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EDI);
inc(href.offset,POINTER_SIZE);
@ -1746,7 +1746,10 @@ unit cgx86;
end.
{
$Log$
Revision 1.81 2003-10-17 15:25:18 florian
Revision 1.82 2003-10-18 15:41:26 peter
* made worklists dynamic in size
Revision 1.81 2003/10/17 15:25:18 florian
* fixed more ppc stuff
Revision 1.80 2003/10/17 14:38:32 peter