Procedure-saved registers are now recorded for peephole optimizers to use

This commit is contained in:
J. Gareth "Curious Kit" Moreton 2021-12-25 21:12:35 +00:00 committed by FPK
parent 307c284f6a
commit 30166f8eb7
3 changed files with 33 additions and 12 deletions

View File

@ -2698,6 +2698,7 @@ implementation
for r:=low(regs_to_save_int) to high(regs_to_save_int) do for r:=low(regs_to_save_int) to high(regs_to_save_int) do
if regs_to_save_int[r] in rg[R_INTREGISTER].used_in_proc then if regs_to_save_int[r] in rg[R_INTREGISTER].used_in_proc then
inc(size,sizeof(aint)); inc(size,sizeof(aint));
if uses_registers(R_ADDRESSREGISTER) then if uses_registers(R_ADDRESSREGISTER) then
for r:=low(regs_to_save_int) to high(regs_to_save_int) do for r:=low(regs_to_save_int) to high(regs_to_save_int) do
if regs_to_save_int[r] in rg[R_ADDRESSREGISTER].used_in_proc then if regs_to_save_int[r] in rg[R_ADDRESSREGISTER].used_in_proc then
@ -2713,7 +2714,9 @@ implementation
for r:=low(regs_to_save_mm) to high(regs_to_save_mm) do for r:=low(regs_to_save_mm) to high(regs_to_save_mm) do
if regs_to_save_mm[r] in rg[R_MMREGISTER].used_in_proc then if regs_to_save_mm[r] in rg[R_MMREGISTER].used_in_proc then
inc(size,tcgsize2size[OS_VECTOR]); begin
inc(size,tcgsize2size[OS_VECTOR]);
end;
end; end;
if size>0 then if size>0 then
@ -2732,17 +2735,22 @@ implementation
end; end;
include(rg[R_INTREGISTER].preserved_by_proc,regs_to_save_int[r]); include(rg[R_INTREGISTER].preserved_by_proc,regs_to_save_int[r]);
end; end;
current_procinfo.saved_regs_int := rg[R_INTREGISTER].preserved_by_proc;
if uses_registers(R_ADDRESSREGISTER) then if uses_registers(R_ADDRESSREGISTER) then
for r:=low(regs_to_save_address) to high(regs_to_save_address) do begin
begin for r:=low(regs_to_save_address) to high(regs_to_save_address) do
if regs_to_save_address[r] in rg[R_ADDRESSREGISTER].used_in_proc then begin
begin if regs_to_save_address[r] in rg[R_ADDRESSREGISTER].used_in_proc then
a_load_reg_ref(list,OS_ADDR,OS_ADDR,newreg(R_ADDRESSREGISTER,regs_to_save_address[r],R_SUBWHOLE),href); begin
inc(href.offset,sizeof(aint)); a_load_reg_ref(list,OS_ADDR,OS_ADDR,newreg(R_ADDRESSREGISTER,regs_to_save_address[r],R_SUBWHOLE),href);
end; inc(href.offset,sizeof(aint));
include(rg[R_ADDRESSREGISTER].preserved_by_proc,regs_to_save_address[r]); end;
end; include(rg[R_ADDRESSREGISTER].preserved_by_proc,regs_to_save_address[r]);
end;
current_procinfo.saved_regs_mm := rg[R_MMREGISTER].preserved_by_proc;
end;
if uses_registers(R_MMREGISTER) then if uses_registers(R_MMREGISTER) then
begin begin
@ -2765,6 +2773,8 @@ implementation
include(rg[R_MMREGISTER].preserved_by_proc,regs_to_save_mm[r]); include(rg[R_MMREGISTER].preserved_by_proc,regs_to_save_mm[r]);
end; end;
end; end;
current_procinfo.saved_regs_mm := rg[R_MMREGISTER].preserved_by_proc;
end; end;
end; end;
end; end;

View File

@ -145,6 +145,11 @@ unit procinfo;
localrefsyms : tfpobjectlist; localrefsyms : tfpobjectlist;
localrefdefs : tfpobjectlist; localrefdefs : tfpobjectlist;
{ Registers saved by the current procedure - useful for peephole optimizers }
saved_regs_int,
saved_regs_address,
saved_regs_mm: TCPURegisterSet;
constructor create(aparent:tprocinfo);virtual; constructor create(aparent:tprocinfo);virtual;
destructor destroy;override; destructor destroy;override;

View File

@ -1070,7 +1070,10 @@ unit aoptx86;
begin begin
{ TODO: Currently, only the volatile registers are checked - can this be extended to use any register the procedure has preserved? } { TODO: Currently, only the volatile registers are checked - can this be extended to use any register the procedure has preserved? }
Result := NR_NO; Result := NR_NO;
RegSet := paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption); RegSet :=
paramanager.get_volatile_registers_int(current_procinfo.procdef.proccalloption) +
current_procinfo.saved_regs_int;
for CurrentSuperReg in RegSet do for CurrentSuperReg in RegSet do
begin begin
CurrentReg := newreg(R_INTREGISTER, TSuperRegister(CurrentSuperReg), RegSize); CurrentReg := newreg(R_INTREGISTER, TSuperRegister(CurrentSuperReg), RegSize);
@ -1141,7 +1144,10 @@ unit aoptx86;
begin begin
{ TODO: Currently, only the volatile registers are checked - can this be extended to use any register the procedure has preserved? } { TODO: Currently, only the volatile registers are checked - can this be extended to use any register the procedure has preserved? }
Result := NR_NO; Result := NR_NO;
RegSet := paramanager.get_volatile_registers_mm(current_procinfo.procdef.proccalloption); RegSet :=
paramanager.get_volatile_registers_mm(current_procinfo.procdef.proccalloption) +
current_procinfo.saved_regs_mm;
for CurrentSuperReg in RegSet do for CurrentSuperReg in RegSet do
begin begin
CurrentReg := newreg(R_MMREGISTER, TSuperRegister(CurrentSuperReg), RegSize); CurrentReg := newreg(R_MMREGISTER, TSuperRegister(CurrentSuperReg), RegSize);