+ LLVM support for library init/fini routines

git-svn-id: branches/debug_eh@42108 -
This commit is contained in:
Jonas Maebe 2019-05-19 19:26:59 +00:00
parent 9f18cbf5d6
commit 5473f4fc44
2 changed files with 75 additions and 2 deletions

View File

@ -151,6 +151,8 @@ interface
llvmdefs : THashSet; { defs added for llvm-specific reasons (not saved/restored) }
llvmusedsyms : TFPObjectList; { a list of asmsymbols and their defs 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 asmsymbols and their defs that need to be added to llvm.compiler.used (so they're not removed by llvm optimisation passes) }
llvminitprocs,
llvmfiniprocs : TFPList;
{$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 }
@ -598,6 +600,8 @@ implementation
llvmdefs:=THashSet.Create(64,true,false);
llvmusedsyms:=TFPObjectList.Create(true);
llvmcompilerusedsyms:=TFPObjectList.Create(true);
llvminitprocs:=TFPList.Create;
llvmfiniprocs:=TFPList.Create;
{$endif llvm}
ansistrdef:=nil;
wpoinfo:=nil;
@ -727,6 +731,8 @@ implementation
llvmdefs.free;
llvmusedsyms.free;
llvmcompilerusedsyms.free;
llvminitprocs.free;
llvmfiniprocs.free;
{$endif llvm}
ansistrdef:=nil;
wpoinfo.free;
@ -801,6 +807,10 @@ implementation
llvmusedsyms:=TFPObjectList.Create(true);
llvmcompilerusedsyms.free;
llvmcompilerusedsyms:=TFPObjectList.Create(true);
llvminitprocs.free;
llvminitprocs:=TFPList.Create;
llvmfiniprocs.free;
llvmfiniprocs:=TFPList.Create;
{$endif llvm}
wpoinfo.free;
wpoinfo:=nil;

View File

@ -35,11 +35,14 @@ 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);
class procedure InsertUsedList(var usedsyms: tfpobjectlist; const usedsymsname: TSymStr);
class procedure InsertInitFiniList(var procdefs: tfplist; const initfinisymsname: TSymStr);
public
class procedure InsertObjectInfo; override;
class procedure RegisterUsedAsmSym(sym: TAsmSymbol; def: tdef; compileronly: boolean); override;
class procedure GenerateObjCImageInfo; override;
class procedure RegisterModuleInitFunction(pd: tprocdef); override;
class procedure RegisterModuleFiniFunction(pd: tprocdef); override;
end;
@ -50,7 +53,7 @@ implementation
aasmtai,cpubase,llvmbase,aasmllvm,
aasmcnst,nllvmtcon,
symbase,symtable,defutil,
llvmtype,
llvmtype,llvmdef,
objcasm;
class procedure tllvmnodeutils.insertbsssym(list: tasmlist; sym: tstaticvarsym; size: asizeint; varalign: shortint);
@ -156,6 +159,50 @@ implementation
end;
class procedure tllvmnodeutils.InsertInitFiniList(var procdefs: tfplist; const initfinisymsname: TSymStr);
var
itemdef: trecorddef;
arraydef: tarraydef;
pd: tprocdef;
fields: array[0..2] of tdef;
tcb: ttai_typedconstbuilder;
i: longint;
begin
if procdefs.count<>0 then
begin
pd:=tprocdef(procdefs[0]);
fields[0]:=s32inttype;
fields[1]:=pd.getcopyas(procvardef,pc_address_only,'');
fields[2]:=voidpointertype;
itemdef:=llvmgettemprecorddef(fields,C_alignment,
targetinfos[target_info.system]^.alignment.recordalignmin,
targetinfos[target_info.system]^.alignment.maxCrecordalign);
include(itemdef.defoptions,df_llvm_no_struct_packing);
tcb:=ctai_typedconstbuilder.create([tcalo_new_section]);
tllvmtai_typedconstbuilder(tcb).appendingdef:=true;
arraydef:=carraydef.getreusable(itemdef,procdefs.Count);
tcb.maybe_begin_aggregate(arraydef);
for i:=0 to procdefs.count-1 do
begin
tcb.maybe_begin_aggregate(itemdef);
tcb.emit_ord_const(65535,s32inttype);
tcb.emit_procdef_const(tprocdef(procdefs[i]));
tcb.emit_tai(Tai_const.Create_sym(nil),voidpointertype);
tcb.maybe_end_aggregate(itemdef);
end;
tcb.maybe_end_aggregate(arraydef);
current_asmdata.AsmLists[al_globals].concatlist(
tcb.get_final_asmlist(
current_asmdata.DefineAsmSymbol(
initfinisymsname,AB_GLOBAL,AT_DATA,arraydef),arraydef,sec_data,
initfinisymsname,voidpointertype.alignment
)
);
tcb.free;
end;
end;
class procedure tllvmnodeutils.InsertObjectInfo;
begin
inherited;
@ -164,6 +211,10 @@ implementation
InsertUsedList(current_module.llvmcompilerusedsyms,'llvm.compiler.used');
{ add the llvm.used array }
InsertUsedList(current_module.llvmusedsyms,'llvm.used');
{ add the llvm.global_ctors array }
InsertInitFiniList(current_module.llvminitprocs,'llvm.global_ctors');
{ add the llvm.global_dtors array }
InsertInitFiniList(current_module.llvmfiniprocs,'llvm.global_dtors');
{ add "type xx = .." statements for all used recorddefs }
with TLLVMTypeInfo.Create do
@ -244,6 +295,18 @@ implementation
end;
class procedure tllvmnodeutils.RegisterModuleInitFunction(pd: tprocdef);
begin
current_module.llvminitprocs.add(pd);
end;
class procedure tllvmnodeutils.RegisterModuleFiniFunction(pd: tprocdef);
begin
current_module.llvmfiniprocs.add(pd);
end;
begin
cnodeutils:=tllvmnodeutils;
end.