mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-10 01:46:58 +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) }
|
||||
{$ifdef llvm}
|
||||
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}
|
||||
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 }
|
||||
@ -588,6 +590,8 @@ implementation
|
||||
procaddrdefs:=THashSet.Create(64,true,false);
|
||||
{$ifdef llvm}
|
||||
llvmdefs:=THashSet.Create(64,true,false);
|
||||
llvmusedsyms:=TFPObjectList.Create(false);
|
||||
llvmcompilerusedsyms:=TFPObjectList.Create(false);
|
||||
{$endif llvm}
|
||||
ansistrdef:=nil;
|
||||
wpoinfo:=nil;
|
||||
@ -714,6 +718,8 @@ implementation
|
||||
procaddrdefs.free;
|
||||
{$ifdef llvm}
|
||||
llvmdefs.free;
|
||||
llvmusedsyms.free;
|
||||
llvmcompilerusedsyms.free;
|
||||
{$endif llvm}
|
||||
ansistrdef:=nil;
|
||||
wpoinfo.free;
|
||||
@ -784,6 +790,10 @@ implementation
|
||||
{$ifdef llvm}
|
||||
llvmdefs.free;
|
||||
llvmdefs:=THashSet.Create(64,true,false);
|
||||
llvmusedsyms.free;
|
||||
llvmusedsyms:=TFPObjectList.Create(false);
|
||||
llvmcompilerusedsyms.free;
|
||||
llvmcompilerusedsyms:=TFPObjectList.Create(false);
|
||||
{$endif llvm}
|
||||
wpoinfo.free;
|
||||
wpoinfo:=nil;
|
||||
|
@ -124,7 +124,7 @@ interface
|
||||
implementation
|
||||
|
||||
uses
|
||||
verbose,systems,
|
||||
verbose,systems,fmodule,
|
||||
aasmdata,
|
||||
cpubase,cpuinfo,llvmbase,
|
||||
symtable,llvmdef,defutil,defcmp;
|
||||
@ -202,7 +202,18 @@ implementation
|
||||
include(decl.flags,ldf_vectorized);
|
||||
if tcalo_weak in options then
|
||||
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);
|
||||
fasmlist:=newasmlist;
|
||||
end;
|
||||
|
@ -26,7 +26,7 @@ unit nllvmutil;
|
||||
interface
|
||||
|
||||
uses
|
||||
globtype,
|
||||
globtype,cclasses,
|
||||
aasmdata,ngenutil,
|
||||
symtype,symconst,symsym,symdef;
|
||||
|
||||
@ -35,6 +35,7 @@ interface
|
||||
tllvmnodeutils = class(tnodeutils)
|
||||
strict protected
|
||||
class procedure insertbsssym(list: tasmlist; sym: tstaticvarsym; size: asizeint; varalign: shortint); override;
|
||||
class procedure InsertUsedList(var usedsyms: tfpobjectlist; const usedsymsname: TSymstr);
|
||||
public
|
||||
class procedure InsertObjectInfo; override;
|
||||
end;
|
||||
@ -45,7 +46,7 @@ implementation
|
||||
uses
|
||||
verbose,cutils,globals,fmodule,systems,
|
||||
aasmbase,aasmtai,cpubase,llvmbase,aasmllvm,
|
||||
aasmcnst,
|
||||
aasmcnst,nllvmtcon,
|
||||
symbase,symtable,defutil,
|
||||
llvmtype;
|
||||
|
||||
@ -70,10 +71,49 @@ implementation
|
||||
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;
|
||||
begin
|
||||
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 }
|
||||
with TLLVMTypeInfo.Create do
|
||||
begin
|
||||
|
Loading…
Reference in New Issue
Block a user