mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2026-01-06 07:30:53 +01:00
+ keep (certain) arrays in registers if they are used with constants indices only
git-svn-id: trunk@42239 -
This commit is contained in:
parent
fbbf1f4f1c
commit
749c4d4e47
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -3255,6 +3255,7 @@ implementation
|
||||
|
||||
begin
|
||||
first_array_to_pointer:=nil;
|
||||
make_not_regable(left,[ra_addr_regable]);
|
||||
expectloc:=LOC_REGISTER;
|
||||
end;
|
||||
|
||||
|
||||
@ -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]);
|
||||
|
||||
@ -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}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user