* Do not set pi_needs_got in current_procinfo.flags at the node level, since the GOT usage can only be estimated there. Instead set the pi_needs_got flag at places where the GOT register is accessed during the code generation. This eliminates generation of the unneeded initialization of the GOT register and fixes linker errors when the _GLOBAL_OFFSET_TABLE_ symbol is referenced but no actual GOT references are present.

git-svn-id: trunk@41460 -
This commit is contained in:
yury 2019-02-25 13:35:40 +00:00
parent ab92dcd162
commit e5c2d13671
13 changed files with 3 additions and 72 deletions

View File

@ -261,10 +261,6 @@ unit cgcpu;
reference_reset_symbol(tmpref,dirref.symbol,0,sizeof(pint),[]); reference_reset_symbol(tmpref,dirref.symbol,0,sizeof(pint),[]);
tmpref.refaddr:=addr_pic; tmpref.refaddr:=addr_pic;
tmpref.base:=current_procinfo.got; tmpref.base:=current_procinfo.got;
{$ifdef EXTDEBUG}
if not (pi_needs_got in current_procinfo.flags) then
Comment(V_warning,'pi_needs_got not included');
{$endif EXTDEBUG}
include(current_procinfo.flags,pi_needs_got); include(current_procinfo.flags,pi_needs_got);
list.concat(taicpu.op_ref(A_PUSH,S_L,tmpref)); list.concat(taicpu.op_ref(A_PUSH,S_L,tmpref));
end end

View File

@ -198,6 +198,7 @@ implementation
{ Alloc EBX } { Alloc EBX }
getcpuregister(list, NR_PIC_OFFSET_REG); getcpuregister(list, NR_PIC_OFFSET_REG);
list.concat(taicpu.op_reg_reg(A_MOV,S_L,current_procinfo.got,NR_PIC_OFFSET_REG)); list.concat(taicpu.op_reg_reg(A_MOV,S_L,current_procinfo.got,NR_PIC_OFFSET_REG));
include(current_procinfo.flags,pi_needs_got);
end; end;
Result:=inherited a_call_name(list, pd, s, paras, forceresdef, weak); Result:=inherited a_call_name(list, pd, s, paras, forceresdef, weak);
{ Free EBX } { Free EBX }

View File

@ -1093,10 +1093,6 @@ implementation
{ temps which are immutable do not need to be initialized/finalized } { temps which are immutable do not need to be initialized/finalized }
if (tempinfo^.typedef.needs_inittable) and not(ti_const in tempflags) then if (tempinfo^.typedef.needs_inittable) and not(ti_const in tempflags) then
include(current_procinfo.flags,pi_needs_implicit_finally); include(current_procinfo.flags,pi_needs_implicit_finally);
if (cs_create_pic in current_settings.moduleswitches) and
(tf_pic_uses_got in target_info.flags) and
is_rtti_managed_type(tempinfo^.typedef) then
include(current_procinfo.flags,pi_needs_got);
if assigned(tempinfo^.withnode) then if assigned(tempinfo^.withnode) then
firstpass(tempinfo^.withnode); firstpass(tempinfo^.withnode);
if assigned(tempinfo^.tempinitcode) then if assigned(tempinfo^.tempinitcode) then

View File

@ -1086,19 +1086,6 @@ implementation
aktcallnode.procdefinition.proccalloption) then aktcallnode.procdefinition.proccalloption) then
copy_value_by_ref_para; copy_value_by_ref_para;
{ does it need to load RTTI? }
if assigned(parasym) and (parasym.varspez=vs_out) and
(cs_create_pic in current_settings.moduleswitches) and
(
is_rtti_managed_type(left.resultdef) or
(
is_open_array(resultdef) and
is_managed_type(tarraydef(resultdef).elementdef)
)
) and
not(target_info.system in systems_garbage_collected_managed_types) then
include(current_procinfo.flags,pi_needs_got);
if assigned(fparainit) then if assigned(fparainit) then
firstpass(fparainit); firstpass(fparainit);
firstpass(left); firstpass(left);
@ -4382,11 +4369,6 @@ implementation
([cnf_member_call,cnf_inherited] * callnodeflags <> []) then ([cnf_member_call,cnf_inherited] * callnodeflags <> []) then
current_procinfo.ConstructorCallingConstructor:=true; current_procinfo.ConstructorCallingConstructor:=true;
{ object check helper will load VMT -> needs GOT }
if (cs_check_object in current_settings.localswitches) and
(cs_create_pic in current_settings.moduleswitches) then
include(current_procinfo.flags,pi_needs_got);
{ Continue with checking a normal call or generate the inlined code } { Continue with checking a normal call or generate the inlined code }
if cnf_do_inline in callnodeflags then if cnf_do_inline in callnodeflags then
result:=pass1_inline result:=pass1_inline

View File

@ -2022,9 +2022,6 @@ implementation
begin begin
s:=def.rtti_mangledname(rt)+suffix; s:=def.rtti_mangledname(rt)+suffix;
result:=current_asmdata.RefAsmSymbol(s,AT_DATA,indirect); result:=current_asmdata.RefAsmSymbol(s,AT_DATA,indirect);
if (cs_create_pic in current_settings.moduleswitches) and
assigned(current_procinfo) then
include(current_procinfo.flags,pi_needs_got);
if def.owner.moduleid<>current_module.moduleid then if def.owner.moduleid<>current_module.moduleid then
current_module.add_extern_asmsym(s,AB_EXTERNAL,AT_DATA); current_module.add_extern_asmsym(s,AB_EXTERNAL,AT_DATA);
end; end;

View File

@ -3177,9 +3177,6 @@ implementation
begin begin
result:=nil; result:=nil;
expectloc:=LOC_REGISTER; expectloc:=LOC_REGISTER;
{ Use of FPC_EMPTYCHAR label requires setting pi_needs_got flag }
if (cs_create_pic in current_settings.moduleswitches) then
include(current_procinfo.flags,pi_needs_got);
end; end;
@ -3604,9 +3601,6 @@ implementation
begin begin
first_ansistring_to_pchar:=nil; first_ansistring_to_pchar:=nil;
expectloc:=LOC_REGISTER; expectloc:=LOC_REGISTER;
{ Use of FPC_EMPTYCHAR label requires setting pi_needs_got flag }
if (cs_create_pic in current_settings.moduleswitches) then
include(current_procinfo.flags,pi_needs_got);
end; end;

View File

@ -465,8 +465,6 @@ implementation
begin begin
result:=nil; result:=nil;
expectloc:=LOC_CREFERENCE; expectloc:=LOC_CREFERENCE;
if (cs_create_pic in current_settings.moduleswitches) then
include(current_procinfo.flags,pi_needs_got);
end; end;
@ -868,9 +866,6 @@ implementation
end end
else else
expectloc:=LOC_CREFERENCE; expectloc:=LOC_CREFERENCE;
if (cs_create_pic in current_settings.moduleswitches) and
(expectloc <> LOC_CONSTANT) then
include(current_procinfo.flags,pi_needs_got);
end; end;
@ -1160,9 +1155,6 @@ implementation
expectloc:=LOC_CONSTANT expectloc:=LOC_CONSTANT
else else
expectloc:=LOC_CREFERENCE; expectloc:=LOC_CREFERENCE;
if (cs_create_pic in current_settings.moduleswitches) and
(expectloc <> LOC_CONSTANT) then
include(current_procinfo.flags,pi_needs_got);
end; end;
@ -1254,9 +1246,6 @@ implementation
begin begin
result:=nil; result:=nil;
expectloc:=LOC_CREFERENCE; expectloc:=LOC_CREFERENCE;
if (cs_create_pic in current_settings.moduleswitches) and
(tf_pic_uses_got in target_info.flags) then
include(current_procinfo.flags,pi_needs_got);
end; end;

View File

@ -2416,11 +2416,6 @@ implementation
begin begin
result:=nil; result:=nil;
include(current_procinfo.flags,pi_do_call); include(current_procinfo.flags,pi_do_call);
{ Loads exception class VMT, therefore may need GOT
(generic code only; descendants may need to avoid this check) }
if (cs_create_pic in current_settings.moduleswitches) and
(tf_pic_uses_got in target_info.flags) then
include(current_procinfo.flags,pi_needs_got);
expectloc:=LOC_VOID; expectloc:=LOC_VOID;
if assigned(left) then if assigned(left) then
firstpass(left); firstpass(left);

View File

@ -400,9 +400,6 @@ implementation
begin begin
result:=nil; result:=nil;
expectloc:=LOC_REFERENCE; expectloc:=LOC_REFERENCE;
if (cs_create_pic in current_settings.moduleswitches) and
not(symtableentry.typ in [paravarsym,localvarsym]) then
include(current_procinfo.flags,pi_needs_got);
case symtableentry.typ of case symtableentry.typ of
absolutevarsym : absolutevarsym :
@ -424,9 +421,6 @@ implementation
else else
if (tabstractvarsym(symtableentry).varspez=vs_const) then if (tabstractvarsym(symtableentry).varspez=vs_const) then
expectloc:=LOC_CREFERENCE; expectloc:=LOC_CREFERENCE;
if (target_info.system=system_powerpc_darwin) and
([vo_is_dll_var,vo_is_external] * tabstractvarsym(symtableentry).varoptions <> []) then
include(current_procinfo.flags,pi_needs_got);
{ call to get address of threadvar } { call to get address of threadvar }
if (vo_is_thread_var in tabstractvarsym(symtableentry).varoptions) then if (vo_is_thread_var in tabstractvarsym(symtableentry).varoptions) then
begin begin
@ -1383,9 +1377,6 @@ implementation
begin begin
result:=nil; result:=nil;
expectloc:=LOC_CREFERENCE; expectloc:=LOC_CREFERENCE;
if (cs_create_pic in current_settings.moduleswitches) and
(tf_pic_uses_got in target_info.flags) then
include(current_procinfo.flags,pi_needs_got);
end; end;

View File

@ -242,9 +242,6 @@ implementation
begin begin
result:=nil; result:=nil;
expectloc:=LOC_REGISTER; expectloc:=LOC_REGISTER;
if (left.nodetype=typen) and
(cs_create_pic in current_settings.moduleswitches) then
include(current_procinfo.flags,pi_needs_got);
if left.nodetype<>typen then if left.nodetype<>typen then
begin begin
if (is_objc_class_or_protocol(left.resultdef) or if (is_objc_class_or_protocol(left.resultdef) or

View File

@ -297,11 +297,6 @@ implementation
include(current_procinfo.flags,pi_needs_implicit_finally); include(current_procinfo.flags,pi_needs_implicit_finally);
include(current_procinfo.flags,pi_do_call); include(current_procinfo.flags,pi_do_call);
end; end;
if (tparavarsym(p).varspez in [vs_value,vs_out]) and
(cs_create_pic in current_settings.moduleswitches) and
(tf_pic_uses_got in target_info.flags) and
is_rtti_managed_type(tparavarsym(p).vardef) then
include(current_procinfo.flags,pi_needs_got);
end; end;
end; end;
@ -316,10 +311,6 @@ implementation
begin begin
include(current_procinfo.flags,pi_needs_implicit_finally); include(current_procinfo.flags,pi_needs_implicit_finally);
include(current_procinfo.flags,pi_do_call); include(current_procinfo.flags,pi_do_call);
if is_rtti_managed_type(tlocalvarsym(p).vardef) and
(cs_create_pic in current_settings.moduleswitches) and
(tf_pic_uses_got in target_info.flags) then
include(current_procinfo.flags,pi_needs_got);
end; end;
end; end;

View File

@ -102,6 +102,7 @@ implementation
begin begin
if not(cs_create_pic in current_settings.moduleswitches) then if not(cs_create_pic in current_settings.moduleswitches) then
Internalerror(2018110701); Internalerror(2018110701);
include(current_procinfo.flags,pi_needs_got);
reference_reset(href,0,[]); reference_reset(href,0,[]);
location.reference.index:=current_procinfo.got; location.reference.index:=current_procinfo.got;
location.reference.scalefactor:=1; location.reference.scalefactor:=1;

View File

@ -176,6 +176,7 @@ implementation
cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,jumpreg); cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,href,jumpreg);
cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_ADDR,current_procinfo.got,jumpreg); cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_ADD,OS_ADDR,current_procinfo.got,jumpreg);
emit_reg(A_JMP,S_NO,jumpreg); emit_reg(A_JMP,S_NO,jumpreg);
include(current_procinfo.flags,pi_needs_got);
end end
else else
emit_ref(A_JMP,S_NO,href); emit_ref(A_JMP,S_NO,href);