* reg allocations for imaginary register are now inserted just

before reg allocation
  * tregister changed to enum to allow compile time check
  * fixed several tregister-tsuperregister errors
This commit is contained in:
peter 2003-12-15 21:25:48 +00:00
parent e60da116b0
commit 1367e342db
16 changed files with 517 additions and 316 deletions

View File

@ -447,6 +447,7 @@ interface
Taasmoutput=class; Taasmoutput=class;
tadd_reg_instruction_proc=procedure(instr:Tai;r:tregister) of object;
Trggetproc=procedure(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister) of object; Trggetproc=procedure(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister) of object;
Trgungetproc=procedure(list:Taasmoutput;position:Tai;r:Tregister) of object; Trgungetproc=procedure(list:Taasmoutput;position:Tai;r:Tregister) of object;
@ -491,7 +492,7 @@ interface
procedure loadoper(opidx:longint;o:toper); procedure loadoper(opidx:longint;o:toper);
procedure clearop(opidx:longint); procedure clearop(opidx:longint);
function is_nop:boolean;virtual;abstract; function is_nop:boolean;virtual;abstract;
function is_move:boolean;virtual;abstract; function is_reg_move:boolean;virtual;abstract;
{ register allocator } { register allocator }
function get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister;var live_registers_int:Tsuperregisterworklist):Tai; function get_insert_pos(p:Tai;huntfor1,huntfor2,huntfor3:Tsuperregister;var live_registers_int:Tsuperregisterworklist):Tai;
procedure forward_allocation(p:Tai;var {unusedregsint:tsuperregisterset}live_registers_int:Tsuperregisterworklist); procedure forward_allocation(p:Tai;var {unusedregsint:tsuperregisterset}live_registers_int:Tsuperregisterworklist);
@ -542,6 +543,9 @@ interface
{ label when the result is true or false } { label when the result is true or false }
truelabel,falselabel : tasmlabel; truelabel,falselabel : tasmlabel;
{ hook to notify uses of registers }
add_reg_instruction_hook : tadd_reg_instruction_proc;
{ default lists } { default lists }
datasegment,codesegment,bsssegment, datasegment,codesegment,bsssegment,
debuglist,withdebuglist,consts, debuglist,withdebuglist,consts,
@ -1677,6 +1681,8 @@ implementation
segprefix:=ref^.segment; segprefix:=ref^.segment;
{$endif} {$endif}
typ:=top_ref; typ:=top_ref;
add_reg_instruction_hook(self,ref^.base);
add_reg_instruction_hook(self,ref^.index);
{ mark symbol as used } { mark symbol as used }
if assigned(ref^.symbol) then if assigned(ref^.symbol) then
ref^.symbol.increfs; ref^.symbol.increfs;
@ -1694,6 +1700,7 @@ implementation
reg:=r; reg:=r;
typ:=top_reg; typ:=top_reg;
end; end;
add_reg_instruction_hook(self,r);
{$ifdef ARM} {$ifdef ARM}
{ R15 is the PC on the ARM thus moves to R15 are jumps. { R15 is the PC on the ARM thus moves to R15 are jumps.
Due to speed considerations we don't use a virtual overridden method here. Due to speed considerations we don't use a virtual overridden method here.
@ -1714,10 +1721,14 @@ implementation
with oper[opidx]^ do with oper[opidx]^ do
begin begin
case typ of case typ of
top_reg:
add_reg_instruction_hook(self,reg);
top_ref: top_ref:
begin begin
new(ref); new(ref);
ref^:=o.ref^; ref^:=o.ref^;
add_reg_instruction_hook(self,ref^.base);
add_reg_instruction_hook(self,ref^.index);
end; end;
{$ifdef ARM} {$ifdef ARM}
top_shifterop: top_shifterop:
@ -2202,7 +2213,13 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.60 2003-12-14 20:24:28 daniel Revision 1.61 2003-12-15 21:25:48 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.60 2003/12/14 20:24:28 daniel
* Register allocator speed optimizations * Register allocator speed optimizations
- Worklist no longer a ringbuffer - Worklist no longer a ringbuffer
- No find operations are left - No find operations are left

View File

@ -133,12 +133,17 @@ interface
{ {
The new register coding: The new register coding:
SuperRegister (bits 0..7) SuperRegister (bits 0..15)
Unused (bits 8..15)
Subregister (bits 16..23) Subregister (bits 16..23)
Register type (bits 24..31) Register type (bits 24..31)
TRegister is defined as an enum to make it incompatible
with TSuperRegister to avoid mixing them
} }
TRegister = type cardinal; TRegister = (
TRegisterLowEnum := $80000000,
TRegisterHighEnum := $7fffffff
);
TRegisterRec=packed record TRegisterRec=packed record
{$ifdef FPC_BIG_ENDIAN} {$ifdef FPC_BIG_ENDIAN}
regtype : Tregistertype; regtype : Tregistertype;
@ -316,7 +321,7 @@ implementation
end; end;
destructor tsuperregisterworklist.done; destructor tsuperregisterworklist.done;
begin begin
if assigned(buf) then if assigned(buf) then
freemem(buf); freemem(buf);
@ -324,7 +329,7 @@ implementation
procedure tsuperregisterworklist.add(s:tsuperregister); procedure tsuperregisterworklist.add(s:tsuperregister);
begin begin
inc(length); inc(length);
{ Need to increase buffer length? } { Need to increase buffer length? }
@ -341,14 +346,14 @@ implementation
procedure tsuperregisterworklist.clear; procedure tsuperregisterworklist.clear;
begin begin
length:=0; length:=0;
end; end;
procedure tsuperregisterworklist.deleteidx(i:word); procedure tsuperregisterworklist.deleteidx(i:word);
begin begin
if length=0 then if length=0 then
internalerror(200310144); internalerror(200310144);
@ -358,7 +363,7 @@ implementation
function tsuperregisterworklist.get:tsuperregister; function tsuperregisterworklist.get:tsuperregister;
begin begin
if length=0 then if length=0 then
internalerror(200310142); internalerror(200310142);
@ -369,9 +374,9 @@ implementation
function tsuperregisterworklist.delete(s:tsuperregister):boolean; function tsuperregisterworklist.delete(s:tsuperregister):boolean;
var i:word; var i:word;
begin begin
delete:=false; delete:=false;
for i:=1 to length do for i:=1 to length do
@ -569,7 +574,13 @@ finalization
end. end.
{ {
$Log$ $Log$
Revision 1.78 2003-12-14 20:24:28 daniel Revision 1.79 2003-12-15 21:25:48 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.78 2003/12/14 20:24:28 daniel
* Register allocator speed optimizations * Register allocator speed optimizations
- Worklist no longer a ringbuffer - Worklist no longer a ringbuffer
- No find operations are left - No find operations are left

View File

@ -84,6 +84,7 @@ unit cgobj;
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual; procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;
procedure ungetreference(list:Taasmoutput;const r:Treference);virtual; procedure ungetreference(list:Taasmoutput;const r:Treference);virtual;
procedure add_reg_instruction(instr:Tai;r:tregister);virtual;
procedure add_move_instruction(instr:Taicpu);virtual; procedure add_move_instruction(instr:Taicpu);virtual;
function uses_registers(rt:Tregistertype):boolean;virtual; function uses_registers(rt:Tregistertype):boolean;virtual;
@ -553,6 +554,7 @@ implementation
constructor tcg.create; constructor tcg.create;
begin begin
add_reg_instruction_hook:={$ifdef FPCPROCVAR}@{$endif}add_reg_instruction;
end; end;
@ -627,6 +629,8 @@ implementation
begin begin
if r.base<>NR_NO then if r.base<>NR_NO then
ungetregister(list,r.base); ungetregister(list,r.base);
if r.index<>NR_NO then
ungetregister(list,r.index);
end; end;
@ -657,6 +661,19 @@ implementation
end; end;
procedure tcg.add_reg_instruction(instr:Tai;r:tregister);
var
rt : tregistertype;
begin
rt:=getregtype(r);
{ Only add it when a register allocator is configured.
No IE can be generated, because the VMT is written
without a valid rg[] }
if assigned(rg[rt]) then
rg[rt].add_reg_instruction(instr,r);
end;
procedure tcg.add_move_instruction(instr:Taicpu); procedure tcg.add_move_instruction(instr:Taicpu);
var var
rt : tregistertype; rt : tregistertype;
@ -676,11 +693,7 @@ implementation
for rt:=low(tregistertype) to high(tregistertype) do for rt:=low(tregistertype) to high(tregistertype) do
begin begin
if assigned(rg[rt]) then if assigned(rg[rt]) then
begin rg[rt].do_register_allocation(list,headertai);
rg[rt].check_unreleasedregs;
rg[rt].do_register_allocation(list,headertai);
rg[rt].translate_registers(list);
end;
end; end;
end; end;
@ -1941,7 +1954,13 @@ finalization
end. end.
{ {
$Log$ $Log$
Revision 1.138 2003-12-12 17:16:17 peter Revision 1.139 2003-12-15 21:25:48 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.138 2003/12/12 17:16:17 peter
* rg[tregistertype] added in tcg * rg[tregistertype] added in tcg
Revision 1.137 2003/12/06 22:11:47 jonas Revision 1.137 2003/12/06 22:11:47 jonas

View File

@ -178,7 +178,7 @@ begin
tmpRef.base := NR_EDI; tmpRef.base := NR_EDI;
tmpRef.index := NR_EDI; tmpRef.index := NR_EDI;
for regCounter := RS_EAX to RS_EDI do for regCounter := RS_EAX to RS_EDI do
if writeToMemDestroysContents(NR_NO,tmpRef,regCounter,c[regCounter],dummy) then if writeToMemDestroysContents(RS_INVALID,tmpRef,regCounter,c[regCounter],dummy) then
begin begin
exclude(regsStillValid,regCounter); exclude(regsStillValid,regCounter);
modifiesConflictingMemLocation := not(supreg in regsStillValid); modifiesConflictingMemLocation := not(supreg in regsStillValid);
@ -1954,7 +1954,7 @@ begin
if (memreg <> NR_NO) and if (memreg <> NR_NO) and
(not getNextInstruction(p,hp1) or (not getNextInstruction(p,hp1) or
(RegLoadedWithNewValue(getsupreg(memreg),false,hp1) or (RegLoadedWithNewValue(getsupreg(memreg),false,hp1) or
FindRegDealloc(getsupreg(regcounter),hp1))) then FindRegDealloc(regcounter,hp1))) then
begin begin
hp1 := Tai_Marker.Create(NoPropInfoEnd); hp1 := Tai_Marker.Create(NoPropInfoEnd);
insertllitem(asml,p,p.next,hp1); insertllitem(asml,p,p.next,hp1);
@ -2074,7 +2074,13 @@ end.
{ {
$Log$ $Log$
Revision 1.57 2003-12-15 16:08:15 jonas Revision 1.58 2003-12-15 21:25:49 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.57 2003/12/15 16:08:15 jonas
- disable removal of dead loads before a call, because register - disable removal of dead loads before a call, because register
parameters are released before a call parameters are released before a call
* fix storeback of registers in case of different sizes (e.g., first * fix storeback of registers in case of different sizes (e.g., first

View File

@ -1785,7 +1785,7 @@ begin
(typ in [con_ref,con_noRemoveRef]) and (typ in [con_ref,con_noRemoveRef]) and
(not(cs_UncertainOpts in aktglobalswitches) or (not(cs_UncertainOpts in aktglobalswitches) or
{ for movsl } { for movsl }
((ref.base = RS_EDI) and (ref.index = RS_EDI)) or ((ref.base = NR_EDI) and (ref.index = NR_EDI)) or
{ don't destroy if reg contains a parameter, local or global variable } { don't destroy if reg contains a parameter, local or global variable }
containsPointerLoad(c) containsPointerLoad(c)
); );
@ -1963,7 +1963,7 @@ var
p, prev: tai; p, prev: tai;
hp1, hp2: tai; hp1, hp2: tai;
{$ifdef i386} {$ifdef i386}
regcounter: tregister; regcounter,
supreg : tsuperregister; supreg : tsuperregister;
{$endif i386} {$endif i386}
usedregs, nodeallocregs: tregset; usedregs, nodeallocregs: tregset;
@ -2052,7 +2052,7 @@ begin
usedRegs := usedRegs - noDeallocRegs; usedRegs := usedRegs - noDeallocRegs;
for regCounter := RS_EAX to RS_EDI do for regCounter := RS_EAX to RS_EDI do
if regCounter in usedRegs then if regCounter in usedRegs then
addRegDeallocFor(list,regCounter,prev); addRegDeallocFor(list,newreg(R_INTREGISTER,regCounter,R_SUBWHOLE),prev);
{$endif i386} {$endif i386}
end; end;
@ -2714,7 +2714,13 @@ end.
{ {
$Log$ $Log$
Revision 1.60 2003-12-15 15:58:58 peter Revision 1.61 2003-12-15 21:25:49 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.60 2003/12/15 15:58:58 peter
* fix statedebug compile * fix statedebug compile
Revision 1.59 2003/12/14 22:42:14 peter Revision 1.59 2003/12/14 22:42:14 peter

View File

@ -1808,7 +1808,7 @@ begin
TmpUsedRegs := UsedRegs; TmpUsedRegs := UsedRegs;
UpdateUsedRegs(TmpUsedRegs,tai(hp1.next)); UpdateUsedRegs(TmpUsedRegs,tai(hp1.next));
if (RefsEqual(taicpu(hp2).oper[1]^.ref^, taicpu(p).oper[0]^.ref^) and if (RefsEqual(taicpu(hp2).oper[1]^.ref^, taicpu(p).oper[0]^.ref^) and
not(RegUsedAfterInstruction(getsupreg(taicpu(p).oper[1]^.reg), not(RegUsedAfterInstruction(taicpu(p).oper[1]^.reg,
hp2, TmpUsedRegs))) then hp2, TmpUsedRegs))) then
{ change mov (ref), reg } { change mov (ref), reg }
{ add/sub/or/... reg2/$const, reg } { add/sub/or/... reg2/$const, reg }
@ -1996,7 +1996,13 @@ end.
{ {
$Log$ $Log$
Revision 1.52 2003-12-14 22:42:14 peter Revision 1.53 2003-12-15 21:25:49 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.52 2003/12/14 22:42:14 peter
* fixed csdebug * fixed csdebug
Revision 1.51 2003/12/13 15:48:47 jonas Revision 1.51 2003/12/13 15:48:47 jonas

View File

@ -1,72 +1,72 @@
{ don't edit, this file is generated from x86reg.dat } { don't edit, this file is generated from x86reg.dat }
NR_NO = $00000000; NR_NO = tregister($00000000);
NR_AL = $01010000; NR_AL = tregister($01010000);
NR_AH = $01020000; NR_AH = tregister($01020000);
NR_AX = $01030000; NR_AX = tregister($01030000);
NR_EAX = $01040000; NR_EAX = tregister($01040000);
NR_CL = $01010001; NR_CL = tregister($01010001);
NR_CH = $01020001; NR_CH = tregister($01020001);
NR_CX = $01030001; NR_CX = tregister($01030001);
NR_ECX = $01040001; NR_ECX = tregister($01040001);
NR_DL = $01010002; NR_DL = tregister($01010002);
NR_DH = $01020002; NR_DH = tregister($01020002);
NR_DX = $01030002; NR_DX = tregister($01030002);
NR_EDX = $01040002; NR_EDX = tregister($01040002);
NR_BL = $01010003; NR_BL = tregister($01010003);
NR_BH = $01020003; NR_BH = tregister($01020003);
NR_BX = $01030003; NR_BX = tregister($01030003);
NR_EBX = $01040003; NR_EBX = tregister($01040003);
NR_SI = $01030004; NR_SI = tregister($01030004);
NR_ESI = $01040004; NR_ESI = tregister($01040004);
NR_DI = $01030005; NR_DI = tregister($01030005);
NR_EDI = $01040005; NR_EDI = tregister($01040005);
NR_BP = $01030006; NR_BP = tregister($01030006);
NR_EBP = $01040006; NR_EBP = tregister($01040006);
NR_SP = $01030007; NR_SP = tregister($01030007);
NR_ESP = $01040007; NR_ESP = tregister($01040007);
NR_CS = $05000001; NR_CS = tregister($05000001);
NR_DS = $05000002; NR_DS = tregister($05000002);
NR_ES = $05000003; NR_ES = tregister($05000003);
NR_SS = $05000004; NR_SS = tregister($05000004);
NR_FS = $05000005; NR_FS = tregister($05000005);
NR_GS = $05000006; NR_GS = tregister($05000006);
NR_DR0 = $05000007; NR_DR0 = tregister($05000007);
NR_DR1 = $05000008; NR_DR1 = tregister($05000008);
NR_DR2 = $05000009; NR_DR2 = tregister($05000009);
NR_DR3 = $0500000a; NR_DR3 = tregister($0500000a);
NR_DR6 = $0500000b; NR_DR6 = tregister($0500000b);
NR_DR7 = $0500000c; NR_DR7 = tregister($0500000c);
NR_CR0 = $0500000d; NR_CR0 = tregister($0500000d);
NR_CR2 = $0500000e; NR_CR2 = tregister($0500000e);
NR_CR3 = $0500000f; NR_CR3 = tregister($0500000f);
NR_CR4 = $05000010; NR_CR4 = tregister($05000010);
NR_TR3 = $05000011; NR_TR3 = tregister($05000011);
NR_TR4 = $05000012; NR_TR4 = tregister($05000012);
NR_TR5 = $05000013; NR_TR5 = tregister($05000013);
NR_TR6 = $05000014; NR_TR6 = tregister($05000014);
NR_TR7 = $05000015; NR_TR7 = tregister($05000015);
NR_ST0 = $02000000; NR_ST0 = tregister($02000000);
NR_ST1 = $02000001; NR_ST1 = tregister($02000001);
NR_ST2 = $02000002; NR_ST2 = tregister($02000002);
NR_ST3 = $02000003; NR_ST3 = tregister($02000003);
NR_ST4 = $02000004; NR_ST4 = tregister($02000004);
NR_ST5 = $02000005; NR_ST5 = tregister($02000005);
NR_ST6 = $02000006; NR_ST6 = tregister($02000006);
NR_ST7 = $02000007; NR_ST7 = tregister($02000007);
NR_ST = $02000008; NR_ST = tregister($02000008);
NR_MM0 = $03000000; NR_MM0 = tregister($03000000);
NR_MM1 = $03000001; NR_MM1 = tregister($03000001);
NR_MM2 = $03000002; NR_MM2 = tregister($03000002);
NR_MM3 = $03000003; NR_MM3 = tregister($03000003);
NR_MM4 = $03000004; NR_MM4 = tregister($03000004);
NR_MM5 = $03000005; NR_MM5 = tregister($03000005);
NR_MM6 = $03000006; NR_MM6 = tregister($03000006);
NR_MM7 = $03000007; NR_MM7 = tregister($03000007);
NR_XMM0 = $04000000; NR_XMM0 = tregister($04000000);
NR_XMM1 = $04000001; NR_XMM1 = tregister($04000001);
NR_XMM2 = $04000002; NR_XMM2 = tregister($04000002);
NR_XMM3 = $04000003; NR_XMM3 = tregister($04000003);
NR_XMM4 = $04000004; NR_XMM4 = tregister($04000004);
NR_XMM5 = $04000005; NR_XMM5 = tregister($04000005);
NR_XMM6 = $04000006; NR_XMM6 = tregister($04000006);
NR_XMM7 = $04000007; NR_XMM7 = tregister($04000007);

View File

@ -1,72 +1,72 @@
{ don't edit, this file is generated from x86reg.dat } { don't edit, this file is generated from x86reg.dat }
$00000000, tregister($00000000),
$01010000, tregister($01010000),
$01020000, tregister($01020000),
$01030000, tregister($01030000),
$01040000, tregister($01040000),
$01010001, tregister($01010001),
$01020001, tregister($01020001),
$01030001, tregister($01030001),
$01040001, tregister($01040001),
$01010002, tregister($01010002),
$01020002, tregister($01020002),
$01030002, tregister($01030002),
$01040002, tregister($01040002),
$01010003, tregister($01010003),
$01020003, tregister($01020003),
$01030003, tregister($01030003),
$01040003, tregister($01040003),
$01030004, tregister($01030004),
$01040004, tregister($01040004),
$01030005, tregister($01030005),
$01040005, tregister($01040005),
$01030006, tregister($01030006),
$01040006, tregister($01040006),
$01030007, tregister($01030007),
$01040007, tregister($01040007),
$05000001, tregister($05000001),
$05000002, tregister($05000002),
$05000003, tregister($05000003),
$05000004, tregister($05000004),
$05000005, tregister($05000005),
$05000006, tregister($05000006),
$05000007, tregister($05000007),
$05000008, tregister($05000008),
$05000009, tregister($05000009),
$0500000a, tregister($0500000a),
$0500000b, tregister($0500000b),
$0500000c, tregister($0500000c),
$0500000d, tregister($0500000d),
$0500000e, tregister($0500000e),
$0500000f, tregister($0500000f),
$05000010, tregister($05000010),
$05000011, tregister($05000011),
$05000012, tregister($05000012),
$05000013, tregister($05000013),
$05000014, tregister($05000014),
$05000015, tregister($05000015),
$02000000, tregister($02000000),
$02000001, tregister($02000001),
$02000002, tregister($02000002),
$02000003, tregister($02000003),
$02000004, tregister($02000004),
$02000005, tregister($02000005),
$02000006, tregister($02000006),
$02000007, tregister($02000007),
$02000008, tregister($02000008),
$03000000, tregister($03000000),
$03000001, tregister($03000001),
$03000002, tregister($03000002),
$03000003, tregister($03000003),
$03000004, tregister($03000004),
$03000005, tregister($03000005),
$03000006, tregister($03000006),
$03000007, tregister($03000007),
$04000000, tregister($04000000),
$04000001, tregister($04000001),
$04000002, tregister($04000002),
$04000003, tregister($04000003),
$04000004, tregister($04000004),
$04000005, tregister($04000005),
$04000006, tregister($04000006),
$04000007 tregister($04000007)

View File

@ -113,7 +113,7 @@ implementation
if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then if not(left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]) then
internalerror(200304235); internalerror(200304235);
location_release(exprasmlist,left.location); location_release(exprasmlist,left.location);
allocate_tempparaloc; // allocate_tempparaloc;
cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc); cg.a_paramaddr_ref(exprasmlist,left.location.reference,tempparaloc);
inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE); inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
end; end;
@ -137,7 +137,7 @@ implementation
if left.resulttype.def.deftype=floatdef then if left.resulttype.def.deftype=floatdef then
begin begin
location_release(exprasmlist,left.location); location_release(exprasmlist,left.location);
allocate_tempparaloc; // allocate_tempparaloc;
{$ifdef i386} {$ifdef i386}
if tempparaloc.loc<>LOC_REFERENCE then if tempparaloc.loc<>LOC_REFERENCE then
internalerror(200309291); internalerror(200309291);
@ -215,7 +215,6 @@ implementation
aktcallnode.procdefinition.proccalloption) then aktcallnode.procdefinition.proccalloption) then
begin begin
location_release(exprasmlist,left.location); location_release(exprasmlist,left.location);
allocate_tempparaloc;
{$ifdef i386} {$ifdef i386}
if tempparaloc.loc<>LOC_REFERENCE then if tempparaloc.loc<>LOC_REFERENCE then
internalerror(200309292); internalerror(200309292);
@ -249,14 +248,14 @@ implementation
if cgsize in [OS_64,OS_S64] then if cgsize in [OS_64,OS_S64] then
begin begin
inc(tcgcallnode(aktcallnode).pushedparasize,8); inc(tcgcallnode(aktcallnode).pushedparasize,8);
allocate_tempparaloc; // allocate_tempparaloc;
cg64.a_param64_loc(exprasmlist,left.location,tempparaloc); cg64.a_param64_loc(exprasmlist,left.location,tempparaloc);
location_release(exprasmlist,left.location); location_release(exprasmlist,left.location);
end end
else else
begin begin
location_release(exprasmlist,left.location); location_release(exprasmlist,left.location);
allocate_tempparaloc; // allocate_tempparaloc;
inc(tcgcallnode(aktcallnode).pushedparasize,align(tcgsize2size[tempparaloc.size],tempparaloc.alignment)); inc(tcgcallnode(aktcallnode).pushedparasize,align(tcgsize2size[tempparaloc.size],tempparaloc.alignment));
cg.a_param_loc(exprasmlist,left.location,tempparaloc); cg.a_param_loc(exprasmlist,left.location,tempparaloc);
end; end;
@ -266,7 +265,7 @@ implementation
LOC_CMMXREGISTER: LOC_CMMXREGISTER:
begin begin
location_release(exprasmlist,left.location); location_release(exprasmlist,left.location);
allocate_tempparaloc; // allocate_tempparaloc;
inc(tcgcallnode(aktcallnode).pushedparasize,8); inc(tcgcallnode(aktcallnode).pushedparasize,8);
cg.a_parammm_reg(exprasmlist,left.location.register); cg.a_parammm_reg(exprasmlist,left.location.register);
end; end;
@ -301,6 +300,8 @@ implementation
objectlibrary.getlabel(falselabel); objectlibrary.getlabel(falselabel);
secondpass(left); secondpass(left);
allocate_tempparaloc;
{ handle varargs first, because paraitem.parasym is not valid } { handle varargs first, because paraitem.parasym is not valid }
if (nf_varargs_para in flags) then if (nf_varargs_para in flags) then
begin begin
@ -337,7 +338,7 @@ implementation
begin begin
inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE); inc(tcgcallnode(aktcallnode).pushedparasize,POINTER_SIZE);
location_release(exprasmlist,left.location); location_release(exprasmlist,left.location);
allocate_tempparaloc; // allocate_tempparaloc;
cg.a_param_loc(exprasmlist,left.location,tempparaloc); cg.a_param_loc(exprasmlist,left.location,tempparaloc);
end end
else else
@ -1129,7 +1130,13 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.145 2003-12-07 12:41:32 jonas Revision 1.146 2003-12-15 21:25:48 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.145 2003/12/07 12:41:32 jonas
* fixed ansistring/widestring results: deallocate result reg only after * fixed ansistring/widestring results: deallocate result reg only after
it has been stored to memory, as the storing itself may require extra it has been stored to memory, as the storing itself may require extra
results (e.g. on ppc) results (e.g. on ppc)

View File

@ -526,26 +526,32 @@ implementation
tt.def.needs_inittable) then tt.def.needs_inittable) then
generate_inittable(newtype); generate_inittable(newtype);
{ Always generate RTTI info for all types. This is to have typeinfo() return
the same pointer }
generate_rtti(newtype);
{ for objects we should write the vmt and interfaces. { for objects we should write the vmt and interfaces.
This need to be done after the rtti has been written, because This need to be done after the rtti has been written, because
it can contain a reference to that data (PFV) it can contain a reference to that data (PFV)
This is not for forward classes } This is not for forward classes }
if (tt.def.deftype=objectdef) and if (tt.def.deftype=objectdef) then
not(oo_is_forward in tobjectdef(tt.def).objectoptions) then
begin begin
ch:=cclassheader.create(tobjectdef(tt.def)); if not(oo_is_forward in tobjectdef(tt.def).objectoptions) then
{ generate and check virtual methods, must be done begin
before RTTI is written } ch:=cclassheader.create(tobjectdef(tt.def));
ch.genvmt; { generate and check virtual methods, must be done
if is_interface(tobjectdef(tt.def)) then before RTTI is written }
ch.writeinterfaceids; ch.genvmt;
if (oo_has_vmt in tobjectdef(tt.def).objectoptions) then { Generate RTTI for class }
ch.writevmt; generate_rtti(newtype);
ch.free; if is_interface(tobjectdef(tt.def)) then
ch.writeinterfaceids;
if (oo_has_vmt in tobjectdef(tt.def).objectoptions) then
ch.writevmt;
ch.free;
end;
end
else
begin
{ Always generate RTTI info for all types. This is to have typeinfo() return
the same pointer }
generate_rtti(newtype);
end; end;
aktfilepos:=oldfilepos; aktfilepos:=oldfilepos;
@ -656,7 +662,13 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.74 2003-12-12 12:09:40 marco Revision 1.75 2003-12-15 21:25:48 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.74 2003/12/12 12:09:40 marco
* always generate RTTI patch from peter * always generate RTTI patch from peter
Revision 1.73 2003/12/10 16:37:01 peter Revision 1.73 2003/12/10 16:37:01 peter

View File

@ -749,10 +749,7 @@ implementation
{ The procedure body is finished, we can now { The procedure body is finished, we can now
allocate the registers } allocate the registers }
if not(cs_no_regalloc in aktglobalswitches) then cg.do_register_allocation(aktproccode,headertai);
begin
cg.do_register_allocation(aktproccode,headertai);
end;
{ Add save and restore of used registers } { Add save and restore of used registers }
aktfilepos:=entrypos; aktfilepos:=entrypos;
@ -1333,7 +1330,13 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.176 2003-12-10 16:37:01 peter Revision 1.177 2003-12-15 21:25:48 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.176 2003/12/10 16:37:01 peter
* global property support for fpc modes * global property support for fpc modes
Revision 1.175 2003/12/03 23:13:20 peter Revision 1.175 2003/12/03 23:13:20 peter

View File

@ -146,6 +146,9 @@ unit rgobj;
Treginfoflagset=set of Treginfoflag; Treginfoflagset=set of Treginfoflag;
Treginfo=record Treginfo=record
live_start,
live_end : Tai;
subreg : tsubregister;
alias : Tsuperregister; alias : Tsuperregister;
{ The register allocator assigns each register a colour } { The register allocator assigns each register a colour }
colour : Tsuperregister; colour : Tsuperregister;
@ -156,21 +159,6 @@ unit rgobj;
end; end;
Preginfo=^TReginfo; Preginfo=^TReginfo;
{ This is the base class used for a register allocator. }
trgbase=class
function getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;virtual;abstract;
{# Get the register specified.}
procedure getexplicitregister(list:Taasmoutput;r:Tregister);virtual;abstract;
{# Get multiple registers specified.}
procedure allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);virtual;abstract;
{# Free multiple registers specified.}
procedure deallocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);virtual;abstract;
function uses_registers:boolean;virtual;abstract;
{# Deallocate any kind of register }
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;abstract;
end;
{#------------------------------------------------------------------ {#------------------------------------------------------------------
This class implements the default register allocator. It is used by the This class implements the default register allocator. It is used by the
@ -181,7 +169,7 @@ unit rgobj;
by cpu-specific implementations. by cpu-specific implementations.
--------------------------------------------------------------------} --------------------------------------------------------------------}
trgobj=class(trgbase) trgobj=class
preserved_by_proc : tcpuregisterset; preserved_by_proc : tcpuregisterset;
used_in_proc : tcpuregisterset; used_in_proc : tcpuregisterset;
// is_reg_var : Tsuperregisterset; {old regvars} // is_reg_var : Tsuperregisterset; {old regvars}
@ -206,37 +194,18 @@ unit rgobj;
function uses_registers:boolean;virtual; function uses_registers:boolean;virtual;
{# Deallocate any kind of register } {# Deallocate any kind of register }
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual; procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;
procedure add_constraints(reg:Tregister);virtual; procedure add_reg_instruction(instr:Tai;r:tregister);
procedure add_move_instruction(instr:Taicpu);
{# Do the register allocation.} {# Do the register allocation.}
procedure do_register_allocation(list:Taasmoutput;headertai:tai);virtual; procedure do_register_allocation(list:Taasmoutput;headertai:tai);virtual;
{ procedure resetusableregisters;virtual;}
{ procedure makeregvar(reg:Tsuperregister);}
{$ifdef EXTDEBUG}
procedure writegraph(loopidx:longint);
{$endif EXTDEBUG}
procedure add_move_instruction(instr:Taicpu);
{# Prepare the register colouring.}
procedure prepare_colouring;
{# Clean up after register colouring.}
procedure epilogue_colouring;
{# Colour the registers; that is do the register allocation.}
procedure colour_registers;
{# Spills certain registers in the specified assembler list.}
function spill_registers(list:Taasmoutput;headertai:tai):boolean;
procedure translate_registers(list:Taasmoutput);
{# Adds an interference edge.}
procedure add_edge(u,v:Tsuperregister);
procedure check_unreleasedregs;
protected protected
regtype : Tregistertype; regtype : Tregistertype;
{ default subregister used } { default subregister used }
defaultsub : tsubregister; defaultsub : tsubregister;
{# Adds an interference edge.}
procedure add_edge(u,v:Tsuperregister);
procedure add_constraints(reg:Tregister);virtual;
private
{# First imaginary register.} {# First imaginary register.}
first_imaginary : Tsuperregister; first_imaginary : Tsuperregister;
{# Highest register allocated until now.} {# Highest register allocated until now.}
@ -259,7 +228,21 @@ unit rgobj;
coalesced_moves, coalesced_moves,
constrained_moves : Tlinkedlist; constrained_moves : Tlinkedlist;
live_registers:Tsuperregisterworklist; live_registers:Tsuperregisterworklist;
function getnewreg:tsuperregister; {$ifdef EXTDEBUG}
procedure writegraph(loopidx:longint);
{$endif EXTDEBUG}
{# Prepare the register colouring.}
procedure prepare_colouring;
{# Clean up after register colouring.}
procedure epilogue_colouring;
{# Colour the registers; that is do the register allocation.}
procedure colour_registers;
{# Spills certain registers in the specified assembler list.}
procedure insert_regalloc_info(list:Taasmoutput;headertai:tai);
procedure generate_interference_graph(list:Taasmoutput;headertai:tai);
procedure translate_registers(list:Taasmoutput);
function spill_registers(list:Taasmoutput;headertai:tai):boolean;
function getnewreg(subreg:tsubregister):tsuperregister;
procedure getregisterinline(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister); procedure getregisterinline(list:Taasmoutput;position:Tai;subreg:Tsubregister;var result:Tregister);
procedure ungetregisterinline(list:Taasmoutput;position:Tai;r:Tregister); procedure ungetregisterinline(list:Taasmoutput;position:Tai;r:Tregister);
procedure add_edges_used(u:Tsuperregister); procedure add_edges_used(u:Tsuperregister);
@ -429,7 +412,7 @@ implementation
end; end;
function trgobj.getnewreg:tsuperregister; function trgobj.getnewreg(subreg:tsubregister):tsuperregister;
var var
oldmaxreginfo : tsuperregister; oldmaxreginfo : tsuperregister;
begin begin
@ -447,24 +430,16 @@ implementation
{ Do we really need it to clear it ? At least for 1.0.x (PFV) } { Do we really need it to clear it ? At least for 1.0.x (PFV) }
fillchar(reginfo[oldmaxreginfo],(maxreginfo-oldmaxreginfo)*sizeof(treginfo),0); fillchar(reginfo[oldmaxreginfo],(maxreginfo-oldmaxreginfo)*sizeof(treginfo),0);
end; end;
reginfo[result].subreg:=subreg;
end; end;
function trgobj.getregister(list:Taasmoutput;subreg:Tsubregister):Tregister; function trgobj.getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;
var
p : Tsuperregister;
r : Tregister;
begin begin
p:=getnewreg;
live_registers.add(p);
if defaultsub=R_SUBNONE then if defaultsub=R_SUBNONE then
r:=newreg(regtype,p,R_SUBNONE) result:=newreg(regtype,getnewreg(R_SUBNONE),R_SUBNONE)
else else
r:=newreg(regtype,p,subreg); result:=newreg(regtype,getnewreg(subreg),subreg);
list.concat(Tai_regalloc.alloc(r));
add_edges_used(p);
add_constraints(r);
result:=r;
end; end;
@ -475,29 +450,23 @@ implementation
procedure trgobj.ungetregister(list:Taasmoutput;r:Tregister); procedure trgobj.ungetregister(list:Taasmoutput;r:Tregister);
begin
var supreg:Tsuperregister; { Only explicit allocs insert regalloc info }
if getsupreg(r)<first_imaginary then
begin list.concat(Tai_regalloc.dealloc(r));
supreg:=getsupreg(r); end;
if live_registers.delete(supreg) then
list.concat(Tai_regalloc.dealloc(r));
end;
procedure trgobj.getexplicitregister(list:Taasmoutput;r:Tregister); procedure trgobj.getexplicitregister(list:Taasmoutput;r:Tregister);
var
var supreg:Tsuperregister; supreg:Tsuperregister;
begin
begin supreg:=getsupreg(r);
supreg:=getsupreg(r); if supreg>=first_imaginary then
live_registers.add(supreg); internalerror(2003121503);
if supreg<first_imaginary then
include(used_in_proc,supreg); include(used_in_proc,supreg);
list.concat(Tai_regalloc.alloc(r)); list.concat(Tai_regalloc.alloc(r));
add_edges_used(supreg); end;
add_constraints(r);
end;
procedure trgobj.allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset); procedure trgobj.allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);
@ -507,7 +476,7 @@ implementation
begin begin
for i:=0 to first_imaginary-1 do for i:=0 to first_imaginary-1 do
if i in r then if i in r then
getexplicitregister(list,i); getexplicitregister(list,newreg(regtype,i,defaultsub));
end; end;
@ -518,7 +487,7 @@ implementation
begin begin
for i:=0 to first_imaginary-1 do for i:=0 to first_imaginary-1 do
if i in r then if i in r then
ungetregister(list,i); ungetregister(list,newreg(regtype,i,defaultsub));
end; end;
@ -527,6 +496,12 @@ implementation
spillingcounter:byte; spillingcounter:byte;
endspill:boolean; endspill:boolean;
begin begin
{ Insert regalloc info for imaginary registers }
insert_regalloc_info(list,headertai);
generate_interference_graph(list,headertai);
{ Don't do the real allocation when -sr is passed }
if (cs_no_regalloc in aktglobalswitches) then
exit;
{Do register allocation.} {Do register allocation.}
spillingcounter:=0; spillingcounter:=0;
repeat repeat
@ -542,6 +517,7 @@ implementation
endspill:=not spill_registers(list,headertai); endspill:=not spill_registers(list,headertai);
end; end;
until endspill; until endspill;
translate_registers(list);
end; end;
@ -588,8 +564,9 @@ implementation
var i:word; var i:word;
begin begin
for i:=0 to live_registers.length-1 do if live_registers.length>0 then
add_edge(u,live_registers.buf[i]); for i:=0 to live_registers.length-1 do
add_edge(u,live_registers.buf[i]);
end; end;
{$ifdef EXTDEBUG} {$ifdef EXTDEBUG}
@ -644,6 +621,21 @@ implementation
inc(reginfo[u].movelist^.count); inc(reginfo[u].movelist^.count);
end; end;
procedure trgobj.add_reg_instruction(instr:Tai;r:tregister);
var
supreg : tsuperregister;
begin
supreg:=getsupreg(r);
if supreg>=first_imaginary then
begin
if not assigned(reginfo[supreg].live_start) then
reginfo[supreg].live_start:=instr;
reginfo[supreg].live_end:=instr;
end;
end;
procedure trgobj.add_move_instruction(instr:Taicpu); procedure trgobj.add_move_instruction(instr:Taicpu);
{This procedure notifies a certain as a move instruction so the {This procedure notifies a certain as a move instruction so the
@ -827,8 +819,8 @@ implementation
procedure trgobj.simplify; procedure trgobj.simplify;
var adj : Psuperregisterworklist; var adj : Psuperregisterworklist;
p,n : Tsuperregister; n : Tsuperregister;
min,i:word; i : word;
begin begin
{We take the element with the least interferences out of the {We take the element with the least interferences out of the
simplifyworklist. Since the simplifyworklist is now sorted, we simplifyworklist. Since the simplifyworklist is now sorted, we
@ -1367,7 +1359,7 @@ implementation
var p:Tsuperregister; var p:Tsuperregister;
r:Tregister; r:Tregister;
begin begin
p:=getnewreg; p:=getnewreg(subreg);
live_registers.add(p); live_registers.add(p);
r:=newreg(regtype,p,subreg); r:=newreg(regtype,p,subreg);
if position=nil then if position=nil then
@ -1395,6 +1387,105 @@ implementation
end; end;
procedure trgobj.insert_regalloc_info(list:Taasmoutput;headertai:tai);
var
supreg : tsuperregister;
p : tai;
r : tregister;
begin
{ Insert regallocs for all imaginary registers }
for supreg:=first_imaginary to maxreg-1 do
begin
r:=newreg(regtype,supreg,reginfo[supreg].subreg);
if assigned(reginfo[supreg].live_start) then
begin
{$ifdef EXTDEBUG}
if reginfo[supreg].live_start=reginfo[supreg].live_end then
Comment(V_Warning,'Register '+std_regname(r)+' is only used once');
{$endif EXTDEBUG}
list.insertbefore(Tai_regalloc.alloc(r),reginfo[supreg].live_start);
{ Insert live end deallocation before reg allocations
to reduce conflicts }
p:=reginfo[supreg].live_end;
while assigned(p) and
assigned(p.previous) and
(tai(p.previous).typ=ait_regalloc) and
tai_regalloc(p.previous).allocation do
p:=tai(p.previous);
list.insertbefore(Tai_regalloc.dealloc(r),p);
end
{$ifdef EXTDEBUG}
else
Comment(V_Warning,'Register '+std_regname(r)+' not used');
{$endif EXTDEBUG}
end;
end;
procedure trgobj.generate_interference_graph(list:Taasmoutput;headertai:tai);
var
p : tai;
i : integer;
supreg : tsuperregister;
begin
{ All allocations are available. Now we can generate the
interference graph. Walk through all instructions, we can
start with the headertai, because before the header tai is
only symbols. }
live_registers.clear;
p:=headertai;
while assigned(p) do
begin
case p.typ of
ait_regalloc:
begin
if (getregtype(Tai_regalloc(p).reg)=regtype) then
begin
supreg:=getsupreg(Tai_regalloc(p).reg);
if Tai_regalloc(p).allocation then
live_registers.add(supreg)
else
live_registers.delete(supreg);
add_edges_used(supreg);
add_constraints(Tai_regalloc(p).reg);
end;
end;
{ ait_instruction:
begin
aktfilepos:=Taicpu_abstract(p).fileinfo;
for i:=0 to Taicpu_abstract(p).ops-1 do
with Taicpu_abstract(p).oper[i]^ do
begin
case typ of
top_reg :
begin
add_edges_used(getsupreg(reg));
add_constraints(reg);
end;
top_ref :
begin
add_edges_used(getsupreg(ref^.base));
add_constraints(ref^.base);
add_edges_used(getsupreg(ref^.index));
add_constraints(ref^.index);
end;
end;
end;
end; }
end;
p:=Tai(p.next);
end;
{$ifdef EXTDEBUG}
if live_registers.length>0 then
begin
for i:=0 to live_registers.length-1 do
Comment(V_Warning,'Register '+std_regname(newreg(R_INTREGISTER,live_registers.buf[i],defaultsub))+' not released');
end;
{$endif}
end;
function trgobj.spill_registers(list:Taasmoutput;headertai:tai):boolean; function trgobj.spill_registers(list:Taasmoutput;headertai:tai):boolean;
{Returns true if any help registers have been used.} {Returns true if any help registers have been used.}
@ -1473,8 +1564,7 @@ implementation
live_registers, live_registers,
spill_temps^) then spill_temps^) then
spill_registers:=true; spill_registers:=true;
if Taicpu_abstract(p).is_reg_move then
if Taicpu_abstract(p).is_move then
add_move_instruction(Taicpu(p)); add_move_instruction(Taicpu(p));
end; end;
end; end;
@ -1579,15 +1669,16 @@ implementation
end; end;
procedure Trgobj.check_unreleasedregs;
begin
end;
end. end.
{ {
$Log$ $Log$
Revision 1.102 2003-12-15 16:37:47 daniel Revision 1.103 2003-12-15 21:25:49 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.102 2003/12/15 16:37:47 daniel
* More microoptimizations * More microoptimizations
Revision 1.101 2003/12/15 15:58:58 peter Revision 1.101 2003/12/15 15:58:58 peter

View File

@ -13,6 +13,7 @@
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**********************************************************************} **********************************************************************}
{$mode objfpc}
{$i+} {$i+}
program mkx86reg; program mkx86reg;
@ -383,8 +384,8 @@ begin
end end
else else
first:=false; first:=false;
writeln(confile,names[i],' = ',numbers[i],';'); writeln(confile,names[i],' = ','tregister(',numbers[i],')',';');
write(numfile,numbers[i]); write(numfile,'tregister(',numbers[i],')');
write(stdfile,'''',stdnames[i],''''); write(stdfile,'''',stdnames[i],'''');
write(attfile,'''',attnames[i],''''); write(attfile,'''',attnames[i],'''');
if not(x86_64) then if not(x86_64) then
@ -457,7 +458,13 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.3 2003-09-24 17:11:33 florian Revision 1.4 2003-12-15 21:25:49 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.3 2003/09/24 17:11:33 florian
* x86_64 support; turn on by passing x86_64 * x86_64 support; turn on by passing x86_64
Revision 1.2 2003/09/03 15:55:02 peter Revision 1.2 2003/09/03 15:55:02 peter

View File

@ -201,7 +201,7 @@ interface
procedure Pass2(sec:TAsmObjectdata);virtual; procedure Pass2(sec:TAsmObjectdata);virtual;
procedure SetOperandOrder(order:TOperandOrder); procedure SetOperandOrder(order:TOperandOrder);
function is_nop:boolean;override; function is_nop:boolean;override;
function is_move:boolean;override; function is_reg_move:boolean;override;
function spill_registers(list:Taasmoutput; function spill_registers(list:Taasmoutput;
rgget:Trggetproc; rgget:Trggetproc;
rgunget:Trgungetproc; rgunget:Trgungetproc;
@ -1904,7 +1904,7 @@ implementation
(opcode=A_XCHG) and (oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg) and (oper[0]^.reg=oper[1]^.reg); (opcode=A_XCHG) and (oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg) and (oper[0]^.reg=oper[1]^.reg);
end; end;
function Taicpu.is_move:boolean; function Taicpu.is_reg_move:boolean;
begin begin
{We do not check the number of operands; we assume that nobody constructs {We do not check the number of operands; we assume that nobody constructs
@ -1912,7 +1912,7 @@ implementation
a move between a reference and a register is not a move that is of a move between a reference and a register is not a move that is of
interrest to the register allocation, therefore we only return true interrest to the register allocation, therefore we only return true
for a move between two registers. (DM)} for a move between two registers. (DM)}
is_move:=((opcode=A_MOV) or (opcode=A_MOVZX) or (opcode=A_MOVSX)) and result:=((opcode=A_MOV) or (opcode=A_MOVZX) or (opcode=A_MOVSX)) and
((oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg)); ((oper[0]^.typ=top_reg) and (oper[1]^.typ=top_reg));
end; end;
@ -2344,7 +2344,13 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.39 2003-12-14 20:24:28 daniel Revision 1.40 2003-12-15 21:25:49 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.39 2003/12/14 20:24:28 daniel
* Register allocator speed optimizations * Register allocator speed optimizations
- Worklist no longer a ringbuffer - Worklist no longer a ringbuffer
- No find operations are left - No find operations are left

View File

@ -43,10 +43,10 @@ unit cgx86;
function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override; function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
procedure getexplicitregister(list:Taasmoutput;r:Tregister);override; procedure getexplicitregister(list:Taasmoutput;r:Tregister);override;
procedure ungetregister(list:Taasmoutput;r:Tregister);override; procedure ungetregister(list:Taasmoutput;r:Tregister);override;
procedure ungetreference(list:Taasmoutput;const r:Treference);override;
procedure allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override; procedure allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
procedure deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override; procedure deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
function uses_registers(rt:Tregistertype):boolean;override; function uses_registers(rt:Tregistertype):boolean;override;
procedure add_reg_instruction(instr:Tai;r:tregister);override;
procedure dec_fpu_stack; procedure dec_fpu_stack;
procedure inc_fpu_stack; procedure inc_fpu_stack;
@ -211,15 +211,6 @@ unit cgx86;
end; end;
procedure tcgx86.ungetreference(list:Taasmoutput;const r:Treference);
begin
if r.base<>NR_NO then
ungetregister(list,r.base);
if r.index<>NR_NO then
ungetregister(list,r.index);
end;
procedure Tcgx86.allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset); procedure Tcgx86.allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
begin begin
if rt<>R_FPUREGISTER then if rt<>R_FPUREGISTER then
@ -243,6 +234,13 @@ unit cgx86;
end; end;
procedure tcgx86.add_reg_instruction(instr:Tai;r:tregister);
begin
if getregtype(r)<>R_FPUREGISTER then
inherited add_reg_instruction(instr,r);
end;
procedure tcgx86.dec_fpu_stack; procedure tcgx86.dec_fpu_stack;
begin begin
dec(rgfpu.fpuvaroffset); dec(rgfpu.fpuvaroffset);
@ -1426,18 +1424,18 @@ unit cgx86;
system_i386_win32, system_i386_win32,
{$endif} {$endif}
system_i386_freebsd, system_i386_freebsd,
system_i386_netbsd, system_i386_netbsd,
// system_i386_openbsd, // system_i386_openbsd,
system_i386_wdosx, system_i386_wdosx,
system_i386_linux: system_i386_linux:
begin begin
Case target_info.system Of Case target_info.system Of
system_i386_freebsd : mcountprefix:='.'; system_i386_freebsd : mcountprefix:='.';
system_i386_netbsd : mcountprefix:='__'; system_i386_netbsd : mcountprefix:='__';
// system_i386_openbsd : mcountprefix:='.'; // system_i386_openbsd : mcountprefix:='.';
else else
mcountPrefix:=''; mcountPrefix:='';
end; end;
objectlibrary.getaddrlabel(pl); objectlibrary.getaddrlabel(pl);
list.concat(Tai_section.Create(sec_data)); list.concat(Tai_section.Create(sec_data));
list.concat(Tai_align.Create(4)); list.concat(Tai_align.Create(4));
@ -1684,7 +1682,13 @@ unit cgx86;
end. end.
{ {
$Log$ $Log$
Revision 1.90 2003-12-12 17:16:18 peter Revision 1.91 2003-12-15 21:25:49 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.90 2003/12/12 17:16:18 peter
* rg[tregistertype] added in tcg * rg[tregistertype] added in tcg
Revision 1.89 2003/12/06 01:15:23 florian Revision 1.89 2003/12/06 01:15:23 florian

View File

@ -176,7 +176,7 @@ uses
{$endif x86_64} {$endif x86_64}
); );
regstabs_table : array[tregisterindex] of tregister = ( regstabs_table : array[tregisterindex] of shortint = (
{$ifdef x86_64} {$ifdef x86_64}
{$i r8664stab.inc} {$i r8664stab.inc}
{$else x86_64} {$else x86_64}
@ -526,7 +526,13 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.30 2003-10-31 09:22:55 mazen Revision 1.31 2003-12-15 21:25:49 peter
* reg allocations for imaginary register are now inserted just
before reg allocation
* tregister changed to enum to allow compile time check
* fixed several tregister-tsuperregister errors
Revision 1.30 2003/10/31 09:22:55 mazen
* using findreg_by_<name|number>_table directly to decrease heap overheading * using findreg_by_<name|number>_table directly to decrease heap overheading
Revision 1.29 2003/10/30 17:13:18 peter Revision 1.29 2003/10/30 17:13:18 peter