+ keep (certain) arrays in registers if they are used with constants indices only

git-svn-id: trunk@42239 -
This commit is contained in:
florian 2019-06-16 21:29:48 +00:00
parent fbbf1f4f1c
commit 749c4d4e47
6 changed files with 84 additions and 15 deletions

View File

@ -156,6 +156,9 @@ interface
}
function is_special_array(p : tdef) : boolean;
{# Returns true, if p points to a normal array, bitpacked arrays are included }
function is_normal_array(p : tdef) : boolean;
{# Returns true if p is a bitpacked array }
function is_packed_array(p: tdef) : boolean;
@ -752,6 +755,14 @@ implementation
);
end;
{ true, if p points to a normal array, bitpacked arrays are included }
function is_normal_array(p : tdef) : boolean;
begin
result:=(p.typ=arraydef) and
((tarraydef(p).arrayoptions * [ado_IsVariant,ado_IsArrayOfConst,ado_IsConstructor,ado_IsDynamicArray])=[]) and
not(is_open_array(p));
end;
{ true if p is an ansi string def }
function is_ansistring(p : tdef) : boolean;
begin

View File

@ -823,9 +823,13 @@ implementation
objectdef,
procvardef,
procdef,
arraydef,
formaldef:
result:=R_ADDRESSREGISTER;
arraydef:
if tstoreddef(def).is_intregable then
result:=R_INTREGISTER
else
result:=R_ADDRESSREGISTER;
floatdef:
if use_vectorfpu(def) then
result:=R_MMREGISTER

View File

@ -855,7 +855,9 @@ implementation
paraloc2 : tcgpara;
subsetref : tsubsetreference;
temp : longint;
hreg : tregister;
indexdef : tdef;
i : Integer;
begin
paraloc1.init;
paraloc2.init;
@ -936,19 +938,29 @@ implementation
end
else
begin
{ may happen in case of function results }
case left.location.loc of
LOC_CSUBSETREG,
LOC_CREGISTER,
LOC_CMMREGISTER,
LOC_SUBSETREG,
LOC_REGISTER,
LOC_MMREGISTER:
hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
else
;
end;
location_copy(location,left.location);
{ may happen in case of function results }
case left.location.loc of
LOC_CREGISTER,
LOC_REGISTER:
begin
if not(is_constnode(right)) or (tarraydef(left.resultdef).elementdef.size<>alusinttype.size) then
hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
{ we use location here only to get the right offset }
location_reset_ref(location,LOC_REFERENCE,OS_NO,1,[]);
end;
LOC_CSUBSETREG,
LOC_CMMREGISTER,
LOC_SUBSETREG,
LOC_MMREGISTER:
begin
hlcg.location_force_mem(current_asmdata.CurrAsmList,left.location,left.resultdef);
location_copy(location,left.location);
end;
LOC_INVALID:
Internalerror(2019061101);
else
location_copy(location,left.location);
end;
end;
{ location must be memory }
@ -994,6 +1006,37 @@ implementation
update_reference_offset(location.reference,extraoffset,bytemulsize);
{ adjust alignment after this change }
location.reference.alignment:=newalignment(location.reference.alignment,extraoffset*bytemulsize);
{ actually an array in a register? }
if (left.location.loc in [LOC_CREGISTER,LOC_REGISTER]) and
is_normal_array(left.resultdef) then
begin
{$if defined(cpu64bitalu)}
hreg:=left.location.register;
{$else defined(cpu64bitalu}}
if target_info.endian=endian_little then
begin
if location.reference.offset>3 then
hreg:=left.location.register64.reghi
else
hreg:=left.location.register64.reglo;
end
else
begin
if location.reference.offset>3 then
hreg:=left.location.register64.reglo
else
hreg:=left.location.register64.reghi;
end;
{$endif defined(cpu64bitalu)}
{$if defined(cpu8bitalu) or defined(cpu16bitalu)}
{ we support only the case that one element fills at least one register }
for i:=1 to location.reference.offset mod 4 do
hreg:=cg.GetNextReg(hreg);
{$endif defined(cpu8bitalu) or defined(cpu16bitalu)}
location_reset(location,left.location.loc,def_cgsize(tarraydef(left.resultdef).elementdef));
location.register:=hreg;
end;
end
else
begin

View File

@ -3255,6 +3255,7 @@ implementation
begin
first_array_to_pointer:=nil;
make_not_regable(left,[ra_addr_regable]);
expectloc:=LOC_REGISTER;
end;

View File

@ -1054,7 +1054,9 @@ implementation
that has a field of one of these types -> in that case the record
can't be a regvar either }
if ((left.resultdef.typ=arraydef) and
not is_special_array(left.resultdef)) or
not is_special_array(left.resultdef) and
{ arrays with elements equal to the alu size and with a constant index can be kept in register }
not(is_constnode(right) and (tarraydef(left.resultdef).elementdef.size=alusinttype.size))) or
((left.resultdef.typ=stringdef) and
(tstringdef(left.resultdef).stringtype in [st_shortstring,st_longstring])) then
make_not_regable(left,[ra_addr_regable]);

View File

@ -2225,6 +2225,14 @@ implementation
is_intregable:=(is_implicit_pointer_object_type(self)) and not needs_inittable;
setdef:
is_intregable:=is_smallset(self);
arraydef:
is_intregable:=not(is_special_array(self)) and
(tarraydef(self).size in [1,2,4,8]) and tstoreddef(tarraydef(self).elementdef).is_intregable
{$ifdef SUPPORT_MMX}
and not((cs_mmx in current_settings.localswitches) and
is_mmx_able_array(self))
{$endif SUPPORT_MMX}
;
recorddef:
begin
{$ifdef llvm}