mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 12:10:14 +02:00
+ support for handling the tcalo_no_dead_strip flag when targeting LLVM:
add such symbols to the pseudo-arrays llvm.compiler.used or llvm.used depending on their nature (fixes compiling Objective-C programs with optimization, and keeps the FPC ident in the linked binary) git-svn-id: trunk@35041 -
This commit is contained in:
parent
e62cb7917e
commit
db40e1575d
@ -147,6 +147,8 @@ interface
|
|||||||
procaddrdefs : THashSet; { list of procvardefs created when getting the address of a procdef (not saved/restored) }
|
procaddrdefs : THashSet; { list of procvardefs created when getting the address of a procdef (not saved/restored) }
|
||||||
{$ifdef llvm}
|
{$ifdef llvm}
|
||||||
llvmdefs : THashSet; { defs added for llvm-specific reasons (not saved/restored) }
|
llvmdefs : THashSet; { defs added for llvm-specific reasons (not saved/restored) }
|
||||||
|
llvmusedsyms : TFPObjectList; { a list of tllvmdecls of all symbols that need to be added to llvm.used (so they're not removed by llvm optimisation passes nor by the linker) }
|
||||||
|
llvmcompilerusedsyms : TFPObjectList; { a list of tllvmdecls of all symbols that need to be added to llvm.compiler.used (so they're not removed by llvm optimisation passes) }
|
||||||
{$endif llvm}
|
{$endif llvm}
|
||||||
ansistrdef : tobject; { an ansistring def redefined for the current module }
|
ansistrdef : tobject; { an ansistring def redefined for the current module }
|
||||||
wpoinfo : tunitwpoinfobase; { whole program optimization-related information that is generated during the current run for this unit }
|
wpoinfo : tunitwpoinfobase; { whole program optimization-related information that is generated during the current run for this unit }
|
||||||
@ -588,6 +590,8 @@ implementation
|
|||||||
procaddrdefs:=THashSet.Create(64,true,false);
|
procaddrdefs:=THashSet.Create(64,true,false);
|
||||||
{$ifdef llvm}
|
{$ifdef llvm}
|
||||||
llvmdefs:=THashSet.Create(64,true,false);
|
llvmdefs:=THashSet.Create(64,true,false);
|
||||||
|
llvmusedsyms:=TFPObjectList.Create(false);
|
||||||
|
llvmcompilerusedsyms:=TFPObjectList.Create(false);
|
||||||
{$endif llvm}
|
{$endif llvm}
|
||||||
ansistrdef:=nil;
|
ansistrdef:=nil;
|
||||||
wpoinfo:=nil;
|
wpoinfo:=nil;
|
||||||
@ -714,6 +718,8 @@ implementation
|
|||||||
procaddrdefs.free;
|
procaddrdefs.free;
|
||||||
{$ifdef llvm}
|
{$ifdef llvm}
|
||||||
llvmdefs.free;
|
llvmdefs.free;
|
||||||
|
llvmusedsyms.free;
|
||||||
|
llvmcompilerusedsyms.free;
|
||||||
{$endif llvm}
|
{$endif llvm}
|
||||||
ansistrdef:=nil;
|
ansistrdef:=nil;
|
||||||
wpoinfo.free;
|
wpoinfo.free;
|
||||||
@ -784,6 +790,10 @@ implementation
|
|||||||
{$ifdef llvm}
|
{$ifdef llvm}
|
||||||
llvmdefs.free;
|
llvmdefs.free;
|
||||||
llvmdefs:=THashSet.Create(64,true,false);
|
llvmdefs:=THashSet.Create(64,true,false);
|
||||||
|
llvmusedsyms.free;
|
||||||
|
llvmusedsyms:=TFPObjectList.Create(false);
|
||||||
|
llvmcompilerusedsyms.free;
|
||||||
|
llvmcompilerusedsyms:=TFPObjectList.Create(false);
|
||||||
{$endif llvm}
|
{$endif llvm}
|
||||||
wpoinfo.free;
|
wpoinfo.free;
|
||||||
wpoinfo:=nil;
|
wpoinfo:=nil;
|
||||||
|
@ -124,7 +124,7 @@ interface
|
|||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
verbose,systems,
|
verbose,systems,fmodule,
|
||||||
aasmdata,
|
aasmdata,
|
||||||
cpubase,cpuinfo,llvmbase,
|
cpubase,cpuinfo,llvmbase,
|
||||||
symtable,llvmdef,defutil,defcmp;
|
symtable,llvmdef,defutil,defcmp;
|
||||||
@ -202,7 +202,18 @@ implementation
|
|||||||
include(decl.flags,ldf_vectorized);
|
include(decl.flags,ldf_vectorized);
|
||||||
if tcalo_weak in options then
|
if tcalo_weak in options then
|
||||||
include(decl.flags,ldf_weak);
|
include(decl.flags,ldf_weak);
|
||||||
{ TODO: tcalo_no_dead_strip: add to @llvm.user meta-variable }
|
if tcalo_no_dead_strip in options then
|
||||||
|
{ Objective-C section declarations already contain "no_dead_strip"
|
||||||
|
attributes if none of their symbols need to be stripped -> only
|
||||||
|
add the symbols to llvm.compiler.used (only affects compiler
|
||||||
|
optimisations) and not to llvm.used (also affects linker -- which in
|
||||||
|
this case is already taken care of by the section attribute; not sure
|
||||||
|
why it's done like this, but this is how Clang does it) }
|
||||||
|
if (target_info.system in systems_darwin) and
|
||||||
|
(section in [low(TObjCAsmSectionType)..high(TObjCAsmSectionType)]) then
|
||||||
|
current_module.llvmcompilerusedsyms.add(decl)
|
||||||
|
else
|
||||||
|
current_module.llvmusedsyms.add(decl);
|
||||||
newasmlist.concat(decl);
|
newasmlist.concat(decl);
|
||||||
fasmlist:=newasmlist;
|
fasmlist:=newasmlist;
|
||||||
end;
|
end;
|
||||||
|
@ -26,7 +26,7 @@ unit nllvmutil;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
globtype,
|
globtype,cclasses,
|
||||||
aasmdata,ngenutil,
|
aasmdata,ngenutil,
|
||||||
symtype,symconst,symsym,symdef;
|
symtype,symconst,symsym,symdef;
|
||||||
|
|
||||||
@ -35,6 +35,7 @@ interface
|
|||||||
tllvmnodeutils = class(tnodeutils)
|
tllvmnodeutils = class(tnodeutils)
|
||||||
strict protected
|
strict protected
|
||||||
class procedure insertbsssym(list: tasmlist; sym: tstaticvarsym; size: asizeint; varalign: shortint); override;
|
class procedure insertbsssym(list: tasmlist; sym: tstaticvarsym; size: asizeint; varalign: shortint); override;
|
||||||
|
class procedure InsertUsedList(var usedsyms: tfpobjectlist; const usedsymsname: TSymstr);
|
||||||
public
|
public
|
||||||
class procedure InsertObjectInfo; override;
|
class procedure InsertObjectInfo; override;
|
||||||
end;
|
end;
|
||||||
@ -45,7 +46,7 @@ implementation
|
|||||||
uses
|
uses
|
||||||
verbose,cutils,globals,fmodule,systems,
|
verbose,cutils,globals,fmodule,systems,
|
||||||
aasmbase,aasmtai,cpubase,llvmbase,aasmllvm,
|
aasmbase,aasmtai,cpubase,llvmbase,aasmllvm,
|
||||||
aasmcnst,
|
aasmcnst,nllvmtcon,
|
||||||
symbase,symtable,defutil,
|
symbase,symtable,defutil,
|
||||||
llvmtype;
|
llvmtype;
|
||||||
|
|
||||||
@ -70,10 +71,49 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
class procedure tllvmnodeutils.InsertUsedList(var usedsyms: tfpobjectlist; const usedsymsname: TSymstr);
|
||||||
|
var
|
||||||
|
useddef: tdef;
|
||||||
|
tcb: ttai_typedconstbuilder;
|
||||||
|
decl: taillvmdecl;
|
||||||
|
i: longint;
|
||||||
|
begin
|
||||||
|
if usedsyms.count<>0 then
|
||||||
|
begin
|
||||||
|
tcb:=ctai_typedconstbuilder.create([tcalo_new_section]);
|
||||||
|
tllvmtai_typedconstbuilder(tcb).appendingdef:=true;
|
||||||
|
useddef:=carraydef.getreusable(voidpointertype,usedsyms.count);
|
||||||
|
tcb.maybe_begin_aggregate(useddef);
|
||||||
|
for i:=0 to usedsyms.count-1 do
|
||||||
|
begin
|
||||||
|
decl:=taillvmdecl(usedsyms[i]);
|
||||||
|
tcb.queue_init(voidpointertype);
|
||||||
|
tcb.queue_emit_asmsym(decl.namesym,decl.def);
|
||||||
|
end;
|
||||||
|
tcb.maybe_end_aggregate(useddef);
|
||||||
|
current_asmdata.AsmLists[al_globals].concatlist(
|
||||||
|
tcb.get_final_asmlist(
|
||||||
|
current_asmdata.DefineAsmSymbol(
|
||||||
|
usedsymsname,AB_GLOBAL,AT_DATA,useddef),useddef,sec_user,
|
||||||
|
'llvm.metadata',0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
tcb.free;
|
||||||
|
end;
|
||||||
|
usedsyms.free;
|
||||||
|
usedsyms:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
class procedure tllvmnodeutils.InsertObjectInfo;
|
class procedure tllvmnodeutils.InsertObjectInfo;
|
||||||
begin
|
begin
|
||||||
inherited;
|
inherited;
|
||||||
|
|
||||||
|
{ add the llvm.compiler.used array }
|
||||||
|
InsertUsedList(current_module.llvmcompilerusedsyms,'llvm.compiler.used');
|
||||||
|
{ add the llvm.used array }
|
||||||
|
InsertUsedList(current_module.llvmusedsyms,'llvm.used');
|
||||||
|
|
||||||
{ add "type xx = .." statements for all used recorddefs }
|
{ add "type xx = .." statements for all used recorddefs }
|
||||||
with TLLVMTypeInfo.Create do
|
with TLLVMTypeInfo.Create do
|
||||||
begin
|
begin
|
||||||
|
Loading…
Reference in New Issue
Block a user