소스 검색

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 -
svenbarth 9 년 전
부모
커밋
e4feacf29d
1개의 변경된 파일32개의 추가작업 그리고 9개의 파일을 삭제
  1. 32 9
      compiler/ncgld.pas

+ 32 - 9
compiler/ncgld.pas

@@ -38,6 +38,7 @@ interface
           procedure generate_nested_access(vs: tsym);virtual;
           procedure generate_nested_access(vs: tsym);virtual;
           procedure generate_absaddr_access(vs: tabsolutevarsym); virtual;
           procedure generate_absaddr_access(vs: tabsolutevarsym); virtual;
           procedure generate_threadvar_access(gvs: tstaticvarsym); virtual;
           procedure generate_threadvar_access(gvs: tstaticvarsym); virtual;
+          function use_indirect_symbol(gvs: tstaticvarsym): boolean;
          public
          public
           procedure pass_generate_code;override;
           procedure pass_generate_code;override;
           procedure changereflocation(const ref: treference);
           procedure changereflocation(const ref: treference);
@@ -68,7 +69,7 @@ implementation
     uses
     uses
       cutils,
       cutils,
       systems,
       systems,
-      verbose,globals,constexp,
+      verbose,globals,constexp,fmodule,
       nutils,
       nutils,
       symtable,symconst,symdef,defutil,paramgr,ncon,nbas,ncgrtti,
       symtable,symconst,symdef,defutil,paramgr,ncon,nbas,ncgrtti,
       aasmbase,
       aasmbase,
@@ -273,9 +274,9 @@ implementation
            begin
            begin
              if gvs.localloc.loc=LOC_INVALID then
              if gvs.localloc.loc=LOC_INVALID then
                if not(vo_is_weak_external in gvs.varoptions) 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
                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
              else
                location:=gvs.localloc;
                location:=gvs.localloc;
            end
            end
@@ -305,9 +306,9 @@ implementation
              hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,pvd,OC_EQ,0,hregister,norelocatelab);
              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 }
              { no, call it with the index of the threadvar as parameter }
              if not(vo_is_weak_external in gvs.varoptions) then
              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
              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;
              href:=tvref;
              hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,
              hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,
                tv_rec,
                tv_rec,
@@ -347,6 +348,26 @@ implementation
        end;
        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;
     procedure tcgloadnode.pass_generate_code;
       var
       var
         hregister : tregister;
         hregister : tregister;
@@ -414,10 +435,12 @@ implementation
                else
                else
                  begin
                  begin
                    if gvs.localloc.loc=LOC_INVALID then
                    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
                    else
                      location:=gvs.localloc;
                      location:=gvs.localloc;
                  end;
                  end;