Load global variables and typed constants from different units using indirect references if necessary.

ncgld.pas, tcgloadnode:
  + new method use_indirect_symbol to determine whether using an indirect reference is necessary at all
  * generate_threadvar_access & pass_generate_code: pass result of use_indirect_code() to RefAsmSymbol() for using an indirect access if needed

git-svn-id: trunk@33282 -
This commit is contained in:
svenbarth 2016-03-18 22:27:28 +00:00
parent 86b9381673
commit e4feacf29d

View File

@ -38,6 +38,7 @@ interface
procedure generate_nested_access(vs: tsym);virtual;
procedure generate_absaddr_access(vs: tabsolutevarsym); virtual;
procedure generate_threadvar_access(gvs: tstaticvarsym); virtual;
function use_indirect_symbol(gvs: tstaticvarsym): boolean;
public
procedure pass_generate_code;override;
procedure changereflocation(const ref: treference);
@ -68,7 +69,7 @@ implementation
uses
cutils,
systems,
verbose,globals,constexp,
verbose,globals,constexp,fmodule,
nutils,
symtable,symconst,symdef,defutil,paramgr,ncon,nbas,ncgrtti,
aasmbase,
@ -273,9 +274,9 @@ implementation
begin
if gvs.localloc.loc=LOC_INVALID then
if not(vo_is_weak_external in gvs.varoptions) then
reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname),0,location.reference.alignment)
reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname,AT_DATA,use_indirect_symbol(gvs)),0,location.reference.alignment)
else
reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,location.reference.alignment)
reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA),0,location.reference.alignment)
else
location:=gvs.localloc;
end
@ -305,9 +306,9 @@ implementation
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,pvd,OC_EQ,0,hregister,norelocatelab);
{ no, call it with the index of the threadvar as parameter }
if not(vo_is_weak_external in gvs.varoptions) then
reference_reset_symbol(tvref,current_asmdata.RefAsmSymbol(gvs.mangledname),0,sizeof(pint))
reference_reset_symbol(tvref,current_asmdata.RefAsmSymbol(gvs.mangledname,AT_DATA,use_indirect_symbol(gvs)),0,sizeof(pint))
else
reference_reset_symbol(tvref,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,sizeof(pint));
reference_reset_symbol(tvref,current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA),0,sizeof(pint));
href:=tvref;
hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,
tv_rec,
@ -347,6 +348,26 @@ implementation
end;
function tcgloadnode.use_indirect_symbol(gvs:tstaticvarsym):boolean;
begin
{ we are using a direct reference if any of the following is true:
- the target does not support packages
- the target does not use indirect references
- the variable is declared as (weak) external
- G- is set
- the variable is located inside the same unit }
result:=(tf_supports_packages in target_info.flags) and
(target_info.system in systems_indirect_var_imports) and
(gvs.varoptions*[vo_is_external,vo_is_weak_external]=[]) and
(gvs.owner.symtabletype in [globalsymtable,staticsymtable]) and
(cs_imported_data in current_settings.localswitches) and
not sym_is_owned_by(gvs,current_module.globalsymtable) and
(
(current_module.globalsymtable=current_module.localsymtable) or
not sym_is_owned_by(gvs,current_module.localsymtable)
);
end;
procedure tcgloadnode.pass_generate_code;
var
hregister : tregister;
@ -414,10 +435,12 @@ implementation
else
begin
if gvs.localloc.loc=LOC_INVALID then
if not(vo_is_weak_external in gvs.varoptions) then
reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname),0,location.reference.alignment)
else
reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,location.reference.alignment)
begin
if not(vo_is_weak_external in gvs.varoptions) then
reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname,AT_DATA,use_indirect_symbol(gvs)),0,location.reference.alignment)
else
reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA),0,location.reference.alignment)
end
else
location:=gvs.localloc;
end;