mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-08 02:07:53 +02:00
* Count the number of interferences with real registers.
* Do not coalesce registers 'u' and 'v' if 'u' is the last usable real register available for imaginary register 'n' which also interferences with 'v'. This prevents endless spilling in some cases for constrained CPUs such as AVR. Resolves issue #37421. Also this reduces the number of spilled registers in some cases and even eliminates spilling completely for some simple routines for i386 and AVR. * Added a debug output of the number of spilled registers for each routine. This allows to easily compare results after changes in spilling algorithms. git-svn-id: trunk@45987 -
This commit is contained in:
parent
ef099b2075
commit
4964f5cf76
@ -116,6 +116,7 @@ unit rgobj;
|
||||
{$endif llvm}
|
||||
count_uses : longint;
|
||||
total_interferences : longint;
|
||||
real_reg_interferences: word;
|
||||
end;
|
||||
Preginfo=^TReginfo;
|
||||
|
||||
@ -605,7 +606,7 @@ unit rgobj;
|
||||
rtindex : longint = 0;
|
||||
procedure trgobj.do_register_allocation(list:TAsmList;headertai:tai);
|
||||
var
|
||||
spillingcounter:byte;
|
||||
spillingcounter:longint;
|
||||
endspill:boolean;
|
||||
i : Longint;
|
||||
begin
|
||||
@ -645,6 +646,15 @@ unit rgobj;
|
||||
|
||||
translate_registers(list);
|
||||
|
||||
{$ifdef DEBUG_SPILLCOALESCE}
|
||||
spillingcounter:=0;
|
||||
for i:=0 to High(spillinfo) do
|
||||
if spillinfo[i].spilled then
|
||||
inc(spillingcounter);
|
||||
if spillingcounter>0 then
|
||||
writeln(current_procinfo.procdef.mangledname, ': spilled regs: ',spillingcounter);
|
||||
{$endif DEBUG_SPILLCOALESCE}
|
||||
|
||||
{ we need the translation table for debugging info and verbose assembler output,
|
||||
so not dispose them yet (FK)
|
||||
}
|
||||
@ -677,6 +687,8 @@ unit rgobj;
|
||||
if adjlist=nil then
|
||||
new(adjlist,init);
|
||||
adjlist^.add(v);
|
||||
if v<first_imaginary then
|
||||
inc(real_reg_interferences);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -1233,6 +1245,16 @@ unit rgobj;
|
||||
for i:=1 to adj^.length do
|
||||
begin
|
||||
n:=adj^.buf^[i-1];
|
||||
if (u<first_imaginary) and
|
||||
(n>=first_imaginary) and
|
||||
not ibitmap[u,n] and
|
||||
(usable_registers_cnt-reginfo[n].real_reg_interferences<=1) then
|
||||
begin
|
||||
{ Do not coalesce if 'u' is the last usable real register available
|
||||
for imaginary register 'n'. }
|
||||
conservative:=false;
|
||||
exit;
|
||||
end;
|
||||
if not supregset_in(done,n) and
|
||||
(reginfo[n].degree>=usable_registers_cnt) and
|
||||
(reginfo[n].flags*[ri_coalesced,ri_selected]=[]) then
|
||||
|
Loading…
Reference in New Issue
Block a user