* Fixed register allocator. *Lots* of fixes.

This commit is contained in:
daniel 2003-07-06 15:31:20 +00:00
parent 117d6934a1
commit 268bfcf784
13 changed files with 227 additions and 153 deletions

View File

@ -297,17 +297,16 @@ interface
end;
top_symbol :
begin
AsmWrite('dword ');
asmwrite('dword ');
if assigned(o.sym) then
AsmWrite(o.sym.name);
begin
asmwrite(o.sym.name);
if o.symofs=0 then
exit;
end;
if o.symofs>0 then
AsmWrite('+'+tostr(o.symofs))
else
if o.symofs<0 then
AsmWrite(tostr(o.symofs))
else
if not(assigned(o.sym)) then
AsmWrite('0');
asmwrite('+');
asmwrite(tostr(o.symofs))
end;
top_ref :
begin
@ -926,7 +925,10 @@ initialization
end.
{
$Log$
Revision 1.35 2003-06-03 13:01:59 daniel
Revision 1.36 2003-07-06 15:31:21 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.35 2003/06/03 13:01:59 daniel
* Register allocator finished
Revision 1.34 2003/05/26 19:37:57 peter

View File

@ -378,26 +378,15 @@ interface
location_release(exprasmlist,right.location);
cg.a_paramaddr_ref(exprasmlist,right.location.reference,paramanager.getintparaloc(exprasmlist,1));
{$ifdef newra}
r.enum:=R_INTREGISTER;
for i:=first_supreg to last_supreg do
if i<>RS_FRAME_POINTER_REG then
begin
r.number:=i shl 8 or R_SUBWHOLE;
rg.getexplicitregisterint(exprasmlist,r.number);
end;
rg.allocexplicitregistersint(exprasmlist,[first_supreg..last_supreg]-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]);
{$else}
rg.saveintregvars(exprasmlist,regstopush);
rg.saveintregvars(exprasmlist,regstopush);
{$endif}
cg.a_call_name(exprasmlist,'FPC_SHORTSTR_COMPARE');
paramanager.freeintparaloc(exprasmlist,2);
paramanager.freeintparaloc(exprasmlist,1);
{$ifdef newra}
for i:=first_supreg to last_supreg do
if i<>RS_FRAME_POINTER_REG then
begin
r.number:=i shl 8 or R_SUBWHOLE;
rg.ungetregisterint(exprasmlist,r);
end;
rg.deallocexplicitregistersint(exprasmlist,[first_supreg..last_supreg]-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]);
{$else}
rg.restoreusedintregisters(exprasmlist,pushed);
{$endif}
@ -1644,7 +1633,10 @@ begin
end.
{
$Log$
Revision 1.72 2003-06-17 16:51:30 peter
Revision 1.73 2003-07-06 15:31:21 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.72 2003/06/17 16:51:30 peter
* cycle fixes
Revision 1.71 2003/06/07 18:57:04 jonas

View File

@ -756,14 +756,15 @@ implementation
(not paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
begin
{$ifndef cpu64bit}
if resulttype.def.size>sizeof(aword) then
begin
include(regs_to_push_int,RS_FUNCTION_RESULT64_LOW_REG);
include(regs_to_push_int,RS_FUNCTION_RESULT64_HIGH_REG);
end
else
if resulttype.def.deftype<>floatdef then
if resulttype.def.size>sizeof(aword) then
begin
include(regs_to_push_int,RS_FUNCTION_RESULT64_LOW_REG);
include(regs_to_push_int,RS_FUNCTION_RESULT64_HIGH_REG);
end
else
{$endif cpu64bit}
include(regs_to_push_int,RS_FUNCTION_RESULT_REG);
include(regs_to_push_int,RS_FUNCTION_RESULT_REG);
end;
rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
{$endif}
@ -787,7 +788,7 @@ implementation
begin
{No procedure is allowed to destroy ebp.}
{$ifdef newra}
regs_to_alloc:=VOLATILE_INTREGISTERS-[RS_FRAME_POINTER_REG];
regs_to_alloc:=VOLATILE_INTREGISTERS-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG];
if (not is_void(resulttype.def)) and
not(paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
begin
@ -939,12 +940,7 @@ implementation
end;
{$ifdef newra}
for i:=first_supreg to last_supreg do
if i in regs_to_alloc then
begin
r.number:=i shl 8 or R_SUBWHOLE;
rg.getexplicitregisterint(exprasmlist,r.number);
end;
rg.allocexplicitregistersint(exprasmlist,regs_to_alloc);
{$endif}
{ call method }
reference_reset_base(href,{$ifdef newra}vmtreg2{$else}vmtreg{$endif},
@ -966,12 +962,7 @@ implementation
end;
{$ifdef newra}
for i:=first_supreg to last_supreg do
if i in regs_to_alloc then
begin
r.number:=i shl 8 or R_SUBWHOLE;
rg.getexplicitregisterint(exprasmlist,r.number);
end;
rg.allocexplicitregistersint(exprasmlist,regs_to_alloc);
{$endif}
{ Calling interrupt from the same code requires some
extra code }
@ -990,14 +981,14 @@ implementation
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
begin
helpref:=right.location.reference;
if helpref.index.number<>NR_NO then
if (helpref.index.number<>NR_NO) and (helpref.index.number<>NR_FRAME_POINTER_REG) then
begin
rg.ungetregisterint(exprasmlist,helpref.index);
helpref.index:=rg.getabtregisterint(exprasmlist,OS_ADDR);
cg.a_load_reg_reg(exprasmlist,OS_ADDR,OS_ADDR,
right.location.reference.index,helpref.index);
end;
if helpref.base.number<>NR_NO then
if (helpref.base.number<>NR_NO) and (helpref.base.number<>NR_FRAME_POINTER_REG) then
begin
rg.ungetregisterint(exprasmlist,helpref.base);
helpref.base:=rg.getabtregisterint(exprasmlist,OS_ADDR);
@ -1021,12 +1012,7 @@ implementation
end;
{$ifdef newra}
for i:=first_supreg to last_supreg do
if i in regs_to_alloc then
begin
r.number:=i shl 8 or R_SUBWHOLE;
rg.getexplicitregisterint(exprasmlist,r.number);
end;
rg.allocexplicitregistersint(exprasmlist,regs_to_alloc);
{$endif}
{ Calling interrupt from the same code requires some
extra code }
@ -1097,13 +1083,7 @@ implementation
end;
end;
end;
r.enum:=R_INTREGISTER;
for i:=first_supreg to last_supreg do
if i in regs_to_free then
begin
r.number:=i shl 8 or R_SUBWHOLE;
rg.ungetregisterint(exprasmlist,r);
end;
rg.deallocexplicitregistersint(exprasmlist,regs_to_free);
{$endif}
{ handle function results }
if (not is_void(resulttype.def)) then
@ -1561,7 +1541,10 @@ begin
end.
{
$Log$
Revision 1.97 2003-07-05 20:21:26 jonas
Revision 1.98 2003-07-06 15:31:20 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.97 2003/07/05 20:21:26 jonas
* create_paraloc_info() is now called separately for the caller and
callee info
* fixed ppc cycle

View File

@ -521,13 +521,8 @@ implementation
cg.a_param_loc(exprasmlist,right.location,paramanager.getintparaloc(exprasmlist,2));
cg.a_param_loc(exprasmlist,left.location,paramanager.getintparaloc(exprasmlist,1));
{$ifdef newra}
hreg.enum:=R_INTREGISTER;
for i:=first_supreg to last_supreg do
if i<>RS_FRAME_POINTER_REG then
begin
hreg.number:=i shl 8 or R_SUBWHOLE;
rg.getexplicitregisterint(exprasmlist,hreg.number);
end;
rg.allocexplicitregistersint(exprasmlist,[first_supreg..last_supreg]-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]);
{$else}
rg.saveintregvars(exprasmlist,VOLATILE_INTREGISTERS);
{$endif}
@ -535,12 +530,7 @@ implementation
paramanager.freeintparaloc(exprasmlist,2);
paramanager.freeintparaloc(exprasmlist,1);
{$ifdef newra}
for i:=first_supreg to last_supreg do
if i<>RS_FRAME_POINTER_REG then
begin
hreg.number:=i shl 8 or R_SUBWHOLE;
rg.ungetregisterint(exprasmlist,hreg);
end;
rg.deallocexplicitregistersint(exprasmlist,[first_supreg..last_supreg]-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]);
{$else}
rg.restoreusedintregisters(exprasmlist,pushed);
{$endif}
@ -608,25 +598,14 @@ implementation
{$endif}
cg.a_param_reg(exprasmlist,OS_ADDR,location.reference.base,paramanager.getintparaloc(exprasmlist,1));
{$ifdef newra}
hreg.enum:=R_INTREGISTER;
for i:=first_supreg to last_supreg do
if i<>RS_FRAME_POINTER_REG then
begin
hreg.number:=i shl 8 or R_SUBWHOLE;
rg.getexplicitregisterint(exprasmlist,hreg.number);
end;
rg.allocexplicitregistersint(exprasmlist,[first_supreg..last_supreg]-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]);
{$else}
rg.saveintregvars(exprasmlist,VOLATILE_INTREGISTERS);
{$endif}
cg.a_call_name(exprasmlist,'FPC_'+upper(tstringdef(left.resulttype.def).stringtypname)+'_CHECKZERO');
paramanager.freeintparaloc(exprasmlist,1);
{$ifdef newra}
for i:=first_supreg to last_supreg do
if i<>RS_FRAME_POINTER_REG then
begin
hreg.number:=i shl 8 or R_SUBWHOLE;
rg.ungetregisterint(exprasmlist,hreg);
end;
rg.deallocexplicitregistersint(exprasmlist,[first_supreg..last_supreg]-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]);
{$else}
rg.restoreusedintregisters(exprasmlist,pushed);
{$endif}
@ -710,13 +689,7 @@ implementation
dec(href.offset,7);
cg.a_param_ref(exprasmlist,OS_INT,href,paramanager.getintparaloc(exprasmlist,1));
{$ifdef newra}
hreg.enum:=R_INTREGISTER;
for i:=first_supreg to last_supreg do
if i<>RS_FRAME_POINTER_REG then
begin
hreg.number:=i shl 8 or R_SUBWHOLE;
rg.getexplicitregisterint(exprasmlist,hreg.number);
end;
rg.allocexplicitregistersint(exprasmlist,[first_supreg..last_supreg]-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]);
{$else}
rg.saveintregvars(exprasmlist,VOLATILE_INTREGISTERS);
{$endif}
@ -724,12 +697,7 @@ implementation
paramanager.freeintparaloc(exprasmlist,2);
paramanager.freeintparaloc(exprasmlist,1);
{$ifdef newra}
for i:=first_supreg to last_supreg do
if i<>RS_FRAME_POINTER_REG then
begin
hreg.number:=i shl 8 or R_SUBWHOLE;
rg.ungetregisterint(exprasmlist,hreg);
end;
rg.deallocexplicitregistersint(exprasmlist,[first_supreg..last_supreg]-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]);
{$else}
rg.restoreusedintregisters(exprasmlist,pushed);
{$endif}
@ -868,13 +836,7 @@ implementation
dec(href.offset,7);
cg.a_param_ref(exprasmlist,OS_INT,href,paramanager.getintparaloc(exprasmlist,1));
{$ifdef newra}
hreg.enum:=R_INTREGISTER;
for i:=first_supreg to last_supreg do
if i<>RS_FRAME_POINTER_REG then
begin
hreg.number:=i shl 8 or R_SUBWHOLE;
rg.getexplicitregisterint(exprasmlist,hreg.number);
end;
rg.allocexplicitregistersint(exprasmlist,[first_supreg..last_supreg]-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]);
{$else}
rg.saveintregvars(exprasmlist,VOLATILE_INTREGISTERS);
{$endif}
@ -882,12 +844,7 @@ implementation
paramanager.freeintparaloc(exprasmlist,2);
paramanager.freeintparaloc(exprasmlist,1);
{$ifdef newra}
for i:=first_supreg to last_supreg do
if i<>RS_FRAME_POINTER_REG then
begin
hreg.number:=i shl 8 or R_SUBWHOLE;
rg.ungetregisterint(exprasmlist,hreg);
end;
rg.deallocexplicitregistersint(exprasmlist,[first_supreg..last_supreg]-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]);
{$else}
rg.restoreusedintregisters(exprasmlist,pushed);
{$endif}
@ -924,7 +881,10 @@ begin
end.
{
$Log$
Revision 1.64 2003-06-17 19:24:08 jonas
Revision 1.65 2003-07-06 15:31:20 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.64 2003/06/17 19:24:08 jonas
* fixed conversion of fpc_*str_unique to compilerproc
Revision 1.63 2003/06/17 16:34:44 jonas

View File

@ -401,6 +401,20 @@ implementation
end
else
begin
{$ifdef newra}
{ transformations to 32bit or smaller }
if (l.loc=LOC_REGISTER) and (l.size in [OS_64,OS_S64]) then
{ if the previous was 64bit release the high register }
begin
rg.ungetregisterint(list,l.registerhigh);
l.registerhigh.enum:=R_NO;
end;
{Do not bother to recycle the existing register. The register
allocator eliminates unnecessary moves, so it's not needed
and trying to recycle registers can cause problems because
the registers changes size and may need aditional constraints.}
hregister:=rg.getregisterint(list,dst_size);
{$else}
{ transformations to 32bit or smaller }
if l.loc=LOC_REGISTER then
begin
@ -441,8 +455,6 @@ implementation
hregister:=rg.getregisterint(list,dst_size);
end;
hregister:=rg.makeregsize(hregister,dst_size);
{$ifdef newra}
rg.add_constraints(hregister.number);
{$endif}
{ load value in new register }
case l.loc of
@ -1976,7 +1988,10 @@ implementation
end.
{
$Log$
Revision 1.128 2003-07-02 22:18:04 peter
Revision 1.129 2003-07-06 15:31:20 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.128 2003/07/02 22:18:04 peter
* paraloc splitted in callerparaloc,calleeparaloc
* sparc calling convention updates

View File

@ -119,9 +119,9 @@ interface
labsym : tlabelsym;
labsymderef : tderef;
exceptionblock : integer;
// internlab : tinterngotolabel;
{ internlab : tinterngotolabel;}
constructor create(p : tlabelsym);virtual;
// constructor createintern(g:tinterngotolabel);
{ constructor createintern(g:tinterngotolabel);}
constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
procedure ppuwrite(ppufile:tcompilerppufile);override;
procedure derefimpl;override;
@ -1429,7 +1429,10 @@ begin
end.
{
$Log$
Revision 1.78 2003-06-13 21:19:30 peter
Revision 1.79 2003-07-06 15:31:20 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.78 2003/06/13 21:19:30 peter
* current_procdef removed, use current_procinfo.procdef instead
Revision 1.77 2003/06/07 20:26:32 peter

View File

@ -205,7 +205,11 @@ implementation
Comment(V_Warning,'Location is different in secondpass: '+nodetype2str[p.nodetype]);
end;
{$ifndef newra}
{$ifdef newra}
if rg.unusedregsint*([first_supreg..last_supreg] - [RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG])<>
([first_supreg..last_supreg] - [RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG]) then
internalerror(200306171);
{$else}
{ check if all scratch registers are freed }
for i:=1 to max_scratch_regs do
if not(scratch_regs[i] in cg.unusedscratchregisters) then
@ -255,7 +259,9 @@ implementation
procedure generatecode(var p : tnode);
begin
{$ifndef newra}
rg.cleartempgen;
{$endif}
flowcontrol:=[];
{ when size optimization only count occurrence }
if cs_littlesize in aktglobalswitches then
@ -310,7 +316,10 @@ implementation
end.
{
$Log$
Revision 1.59 2003-07-06 10:18:47 jonas
Revision 1.60 2003-07-06 15:31:20 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.59 2003/07/06 10:18:47 jonas
* also generate the caller paraloc info of a procedure if it doesn't exist
yet at the start of pass_2

View File

@ -186,11 +186,14 @@ begin
exitproc:=@myexit;
{ Call the compiler with empty command, so it will take the parameters }
Halt(compiler.Compile(''));
{Halt(}compiler.Compile(''){)};
end.
{
$Log$
Revision 1.22 2003-04-22 14:33:38 peter
Revision 1.23 2003-07-06 15:31:21 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.22 2003/04/22 14:33:38 peter
* removed some notes/hints
Revision 1.21 2003/02/15 22:25:50 carl

View File

@ -595,7 +595,8 @@ implementation
{ reset the temporary memory }
rg.cleartempgen;
rg.used_in_proc_int:=[];
{ exclude(rg.unusedregsint,RS_STACK_POINTER_REG);}
rg.used_in_proc_int:=[{RS_STACK_POINTER_REG}];
rg.used_in_proc_other:=[];
{ set the start offset to the start of the temp area in the stack }
@ -1253,7 +1254,10 @@ begin
end.
{
$Log$
Revision 1.130 2003-07-05 20:15:24 jonas
Revision 1.131 2003-07-06 15:31:21 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.130 2003/07/05 20:15:24 jonas
* set pi_do_call if range/overflow checking is on
Revision 1.129 2003/06/17 16:34:44 jonas

View File

@ -34,14 +34,21 @@
Register allocator introduction.
Free Pascal uses a Chaitin style register allocator similair to the one
described in the book "Modern compiler implementation in C" by Andrew W. Appel.,
published by Cambridge University Press.
Free Pascal uses a Chaitin style register allocator. We use a variant similair
to the one described in the book "Modern compiler implementation in C" by
Andrew W. Appel., published by Cambridge University Press.
The register allocator that is described by Appel uses a much improved way
of register coalescing, called "iterated register coalescing". Instead
of doing coalescing as a prepass to the register allocation, the coalescing
is done inside the register allocator. This has the advantage that the
register allocator can coalesce very aggresively without introducing spills.
Reading this book is recommended for a complete understanding. Here is a small
introduction.
The code generator thinks it has an infinite amount of registers. Our processorhas a limited amount of registers. Therefore we must reduce the amount of
The code generator thinks it has an infinite amount of registers. Our processor
has a limited amount of registers. Therefore we must reduce the amount of
registers until there are less enough to fit into the processors registers.
Registers can interfere or not interfere. If two imaginary registers interfere
@ -68,6 +75,9 @@ Graph colouring is an NP complete problem. Therefore we use an approximation
that pushes registers to colour on to a stack. This is done in the "simplify"
procedure.
The register allocator first checks which registers are a candidate for
coalescing.
*******************************************************************************}
@ -275,6 +285,11 @@ unit rgobj;
}
function getexplicitregisterfpu(list : taasmoutput; r : Toldregister) : tregister;virtual;
{$ifdef newra}
procedure allocexplicitregistersint(list:Taasmoutput;r:Tsupregset);
procedure deallocexplicitregistersint(list:Taasmoutput;r:Tsupregset);
{$endif}
{# Deallocate any kind of register }
procedure ungetregister(list: taasmoutput; r : tregister); virtual;
@ -493,7 +508,9 @@ unit rgobj;
punusedstate = ^tunusedstate;
tunusedstate = record
{$ifndef newra}
unusedregsint : Tsupregset;
{$endif}
unusedregsaddr : Tsupregset;
unusedregsfpu : tregisterset;
unusedregsmm : tregisterset;
@ -521,7 +538,12 @@ unit rgobj;
resetusableregisters;
lastintreg:=0;
maxintreg:=first_imreg;
cpu_registers:={Acpu_registers}last_supreg-first_supreg+1;
{What madman decided to change the code like this: (??)
cpu_registers:=last_supreg-first_supreg+1;
The amount of registers available for register allocation is
allmost allways smaller than the amount of registers that exists!
Therefore: }
cpu_registers:=Acpu_registers;
{$ifdef TEMPREGDEBUG}
fillchar(reg_user,sizeof(reg_user),0);
fillchar(reg_releaser,sizeof(reg_releaser),0);
@ -763,6 +785,52 @@ unit rgobj;
getexplicitregisterint:=r2;
end;
{$ifdef newra}
procedure Trgobj.allocexplicitregistersint(list:Taasmoutput;r:Tsupregset);
var reg:Tregister;
i:Tsuperregister;
begin
if unusedregsint*r=r then
begin
unusedregsint:=unusedregsint-r;
used_in_proc_int:=used_in_proc_int+r;
for i:=first_supreg to last_supreg do
if i in r then
begin
add_edges_used(i);
reg.enum:=R_INTREGISTER;
reg.number:=i shl 8 or R_SUBWHOLE;
list.concat(Tai_regalloc.alloc(reg));
end;
end
else
internalerror(200305061);
end;
procedure Trgobj.deallocexplicitregistersint(list:Taasmoutput;r:Tsupregset);
var reg:Tregister;
i:Tsuperregister;
begin
if unusedregsint*r=[] then
begin
unusedregsint:=unusedregsint+r;
for i:=last_supreg downto first_supreg do
if i in r then
begin
reg.enum:=R_INTREGISTER;
reg.number:=i shl 8 or R_SUBWHOLE;
list.concat(Tai_regalloc.dealloc(reg));
end;
end
else
internalerror(200305062);
end;
{$endif}
{ tries to allocate the passed register, if possible }
function trgobj.getexplicitregisterfpu(list : taasmoutput; r : Toldregister) : tregister;
@ -853,9 +921,7 @@ unit rgobj;
exit;
if r.enum>lastreg then
internalerror(200301081);
if r.enum in intregs then
ungetregisterint(list,r)
else if r.enum in fpuregs then
if r.enum in fpuregs then
ungetregisterfpu(list,r,OS_NO)
else if r.enum in mmregs then
ungetregistermm(list,r)
@ -1357,7 +1423,9 @@ unit rgobj;
procedure trgobj.saveUnusedState(var state: pointer);
begin
new(punusedstate(state));
{$ifndef newra}
punusedstate(state)^.unusedregsint := unusedregsint;
{$endif}
punusedstate(state)^.unusedregsfpu := unusedregsfpu;
punusedstate(state)^.unusedregsmm := unusedregsmm;
{$ifndef newra}
@ -1370,7 +1438,9 @@ unit rgobj;
procedure trgobj.restoreUnusedState(var state: pointer);
begin
{$ifndef newra}
unusedregsint := punusedstate(state)^.unusedregsint;
{$endif}
unusedregsfpu := punusedstate(state)^.unusedregsfpu;
unusedregsmm := punusedstate(state)^.unusedregsmm;
{$ifndef newra}
@ -1643,7 +1713,9 @@ unit rgobj;
end;
end;
n:=Tsuperregister(simplifyworklist[p]);
delete(simplifyworklist,p,1);
if length(simplifyworklist)>1 then
simplifyworklist[p]:=simplifyworklist[length(simplifyworklist)];
dec(simplifyworklist[0]);
{Push it on the selectstack.}
selectstack:=selectstack+char(n);
@ -1671,7 +1743,10 @@ unit rgobj;
if not(u in [first_supreg..last_supreg]) and not move_related(u) and
(degree[u]<cpu_registers) then
begin
delete(freezeworklist,pos(char(u),freezeworklist),1);
if length(freezeworklist)>1 then
freezeworklist[pos(char(u),freezeworklist)]:=freezeworklist[length(freezeworklist)];
dec(freezeworklist[0]);
{ delete(freezeworklist,pos(char(u),freezeworklist),1);}
simplifyworklist:=simplifyworklist+char(u);
end;
end;
@ -1940,6 +2015,7 @@ unit rgobj;
if a in colourednodes then
include(adj_colours,colour[a]);
end;
include(adj_colours,RS_STACK_POINTER_REG);
{Assume a spill by default...}
spillednodes:=spillednodes+char(n);
{Search for a colour not in this list.}
@ -2246,9 +2322,8 @@ unit rgobj;
begin
if r.enum<=lastreg then
internalerror(2003010803);
internalerror(200301083);
supreg:=r.number shr 8;
{ takes much time }
include(unusedregsint,supreg);
if position=nil then
list.insert(Tai_regalloc.dealloc(r))
@ -2271,9 +2346,10 @@ unit rgobj;
spill_registers:=false;
unusedregsint:=[0..255];
fillchar(degree,sizeof(degree),0);
{ exclude(unusedregsint,RS_STACK_POINTER_REG);}
if current_procinfo.framepointer.number=NR_FRAME_POINTER_REG then
{Make sure the register allocator won't allocate registers into ebp.}
exclude(rg.unusedregsint,RS_FRAME_POINTER_REG);
exclude(unusedregsint,RS_FRAME_POINTER_REG);
new(spill_temps);
fillchar(spill_temps^,sizeof(spill_temps^),0);
regs_to_spill_set:=[];
@ -2459,7 +2535,10 @@ end.
{
$Log$
Revision 1.59 2003-07-06 15:00:47 jonas
Revision 1.60 2003-07-06 15:31:21 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.59 2003/07/06 15:00:47 jonas
* fixed my previous completely broken commit. It's not perfect though,
registers > last_supreg and < max_intreg may still be "translated"

View File

@ -3415,7 +3415,7 @@ implementation
end;
lastref:=defref;
{ first, we assume that all registers are used }
usedintregisters:=VOLATILE_INTREGISTERS-[RS_FRAME_POINTER_REG];
usedintregisters:=VOLATILE_INTREGISTERS-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG];
usedotherregisters:=ALL_REGISTERS;
forwarddef:=true;
interfacedef:=false;
@ -3557,7 +3557,7 @@ implementation
{ set all registers to used for simplified compilation PM }
if simplify_ppu then
begin
usedintregisters:=VOLATILE_INTREGISTERS-[RS_FRAME_POINTER_REG];
usedintregisters:=VOLATILE_INTREGISTERS-[RS_FRAME_POINTER_REG,RS_STACK_POINTER_REG];
usedotherregisters:=ALL_REGISTERS;
end;
@ -5838,7 +5838,10 @@ implementation
end.
{
$Log$
Revision 1.154 2003-07-02 22:18:04 peter
Revision 1.155 2003-07-06 15:31:21 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.154 2003/07/02 22:18:04 peter
* paraloc splitted in callerparaloc,calleeparaloc
* sparc calling convention updates

View File

@ -2081,7 +2081,7 @@ implementation
case ops of
1:
begin
if oper[0].typ=top_reg then
if (oper[0].typ=top_reg) and (oper[0].reg.enum=R_INTREGISTER) then
begin
supreg:=oper[0].reg.number shr 8;
if supreg in r then
@ -2109,7 +2109,7 @@ implementation
Change into:
mov r23d,[ebp-12] ; Use a help register
push [r23d+4*r22d] ; Replace register by helpregister }
push [r23d+4*r22d] ; Replace register by helpregister }
subreg:=oper[0].ref^.base.number and $ff;
if oper[0].ref^.index.number=NR_NO then
pos:=Tai(previous)
@ -2156,7 +2156,7 @@ implementation
end;
2:
begin
if oper[0].typ=top_reg then
if (oper[0].typ=top_reg) and (oper[0].reg.enum=R_INTREGISTER) then
begin
supreg:=oper[0].reg.number shr 8;
subreg:=oper[0].reg.number and $ff;
@ -2196,7 +2196,7 @@ implementation
oper[0].ref^:=spilltemplist[supreg];
end;
end;
if oper[1].typ=top_reg then
if (oper[1].typ=top_reg) and (oper[1].reg.enum=R_INTREGISTER) then
begin
supreg:=oper[1].reg.number shr 8;
subreg:=oper[1].reg.number and $ff;
@ -2246,6 +2246,23 @@ implementation
Change into:
add [ebp-12],r21d ; Replace register by reference }
if (opcode=A_MOVZX) or (opcode=A_MOVSX) then
begin
{Because 'movzx memory,register' does not exist...}
spill_registers:=true;
op:=opcode;
opcode:=A_MOV;
opsize:=reg2opsize(oper[1].reg);
pos:=get_insert_pos(Tai(previous),oper[0].reg.number,0,0);
rgget(list,pos,subreg,helpreg);
helpins:=Taicpu.op_reg_reg(op,hopsize,oper[0].reg,helpreg);
if pos=nil then
list.insertafter(helpins,list.first)
else
list.insertafter(helpins,pos.next);
rgunget(list,helpins,helpreg);
forward_allocation(Tai(helpins.next));
end;
oper[1].typ:=top_ref;
new(oper[1].ref);
oper[1].ref^:=spilltemplist[supreg];
@ -2396,7 +2413,10 @@ implementation
end.
{
$Log$
Revision 1.6 2003-06-14 14:53:50 jonas
Revision 1.7 2003-07-06 15:31:21 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.6 2003/06/14 14:53:50 jonas
* fixed newra cycle for x86
* added constants for indicating source and destination operands of the
"move reg,reg" instruction to aasmcpu (and use those in rgobj)

View File

@ -146,11 +146,9 @@ interface
function gas_regnum_search(const s:string):Tnewregister;
implementation
implementation
uses
cutils,systems,
verbose;
uses cutils;
function gas_regnum_search(const s:string):Tnewregister;
@ -178,7 +176,10 @@ interface
end.
{
$Log$
Revision 1.1 2003-05-22 21:33:08 peter
Revision 1.2 2003-07-06 15:31:21 daniel
* Fixed register allocator. *Lots* of fixes.
Revision 1.1 2003/05/22 21:33:08 peter
* i386 att instruction table moved to separate unit
}