|
@@ -27,7 +27,7 @@ interface
|
|
|
|
|
|
uses
|
|
|
globtype,cclasses,
|
|
|
- aasmdata,ngenutil,
|
|
|
+ aasmbase,aasmdata,ngenutil,
|
|
|
symtype,symconst,symsym,symdef;
|
|
|
|
|
|
|
|
@@ -38,6 +38,7 @@ interface
|
|
|
class procedure InsertUsedList(var usedsyms: tfpobjectlist; const usedsymsname: TSymstr);
|
|
|
public
|
|
|
class procedure InsertObjectInfo; override;
|
|
|
+ class procedure RegisterUsedAsmSym(sym: TAsmSymbol; def: tdef; compileronly: boolean); override;
|
|
|
end;
|
|
|
|
|
|
|
|
@@ -45,7 +46,7 @@ implementation
|
|
|
|
|
|
uses
|
|
|
verbose,cutils,globals,fmodule,systems,
|
|
|
- aasmbase,aasmtai,cpubase,llvmbase,aasmllvm,
|
|
|
+ aasmtai,cpubase,llvmbase,aasmllvm,
|
|
|
aasmcnst,nllvmtcon,
|
|
|
symbase,symtable,defutil,
|
|
|
llvmtype;
|
|
@@ -71,24 +72,73 @@ implementation
|
|
|
end;
|
|
|
|
|
|
|
|
|
+ type
|
|
|
+ TTypedAsmSym = class
|
|
|
+ sym: TAsmSymbol;
|
|
|
+ def: tdef;
|
|
|
+ constructor Create(s: TAsmSymbol; d: tdef);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ constructor TTypedAsmSym.Create(s: TAsmSymbol; d: tdef);
|
|
|
+ begin
|
|
|
+ sym:=s;
|
|
|
+ def:=d;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
+ function TypedAsmSymComparer(p1, p2: Pointer): Integer;
|
|
|
+ var
|
|
|
+ sym1: TTypedAsmSym absolute p1;
|
|
|
+ sym2: TTypedAsmSym absolute p2;
|
|
|
+ begin
|
|
|
+ result:=CompareStr(sym1.sym.Name,sym2.sym.Name);
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
class procedure tllvmnodeutils.InsertUsedList(var usedsyms: tfpobjectlist; const usedsymsname: TSymstr);
|
|
|
var
|
|
|
useddef: tdef;
|
|
|
tcb: ttai_typedconstbuilder;
|
|
|
- decl: taillvmdecl;
|
|
|
- i: longint;
|
|
|
+ prevasmsym: TAsmSymbol;
|
|
|
+ typedsym: TTypedAsmSym;
|
|
|
+ uniquesyms, i: longint;
|
|
|
begin
|
|
|
if usedsyms.count<>0 then
|
|
|
begin
|
|
|
+ { a symbol can appear multiple times -> sort the list so we can filter out doubles }
|
|
|
+ usedsyms.Sort(@TypedAsmSymComparer);
|
|
|
+ { count uniques }
|
|
|
+ prevasmsym:=nil;
|
|
|
+ uniquesyms:=0;
|
|
|
+ for i:=0 to usedsyms.count-1 do
|
|
|
+ begin
|
|
|
+ typedsym:=TTypedAsmSym(usedsyms[i]);
|
|
|
+ if (prevasmsym<>typedsym.sym) and
|
|
|
+ { even though we already filter on pure assembler routines when adding the symbols,
|
|
|
+ some may slip through because of forward definitions that are not yet resolved }
|
|
|
+ not((typedsym.def.typ=procdef) and
|
|
|
+ (po_assembler in tprocdef(typedsym.def).procoptions)) then
|
|
|
+ inc(uniquesyms);
|
|
|
+ prevasmsym:=typedsym.sym;
|
|
|
+ end;
|
|
|
+ { emit uniques }
|
|
|
+ prevasmsym:=nil;
|
|
|
tcb:=ctai_typedconstbuilder.create([tcalo_new_section]);
|
|
|
tllvmtai_typedconstbuilder(tcb).appendingdef:=true;
|
|
|
- useddef:=carraydef.getreusable(voidpointertype,usedsyms.count);
|
|
|
+ useddef:=carraydef.getreusable(voidpointertype,uniquesyms);
|
|
|
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);
|
|
|
+ typedsym:=TTypedAsmSym(usedsyms[i]);
|
|
|
+ if (prevasmsym<>typedsym.sym) and
|
|
|
+ not((typedsym.def.typ=procdef) and
|
|
|
+ (po_assembler in tprocdef(typedsym.def).procoptions)) then
|
|
|
+ begin
|
|
|
+ tcb.queue_init(voidpointertype);
|
|
|
+ tcb.queue_emit_asmsym(typedsym.sym,typedsym.def);
|
|
|
+ prevasmsym:=typedsym.sym;
|
|
|
+ end;
|
|
|
end;
|
|
|
tcb.maybe_end_aggregate(useddef);
|
|
|
current_asmdata.AsmLists[al_globals].concatlist(
|
|
@@ -123,6 +173,28 @@ implementation
|
|
|
end;
|
|
|
|
|
|
|
|
|
+ class procedure tllvmnodeutils.RegisterUsedAsmSym(sym: TAsmSymbol; def: tdef; compileronly: boolean);
|
|
|
+ var
|
|
|
+ last: TTypedAsmSym;
|
|
|
+ begin
|
|
|
+ if compileronly then
|
|
|
+ begin
|
|
|
+ { filter multiple adds in succession here already }
|
|
|
+ last:=TTypedAsmSym(current_module.llvmcompilerusedsyms.Last);
|
|
|
+ if not assigned(last) or
|
|
|
+ (last.sym<>sym) then
|
|
|
+ current_module.llvmcompilerusedsyms.Add(TTypedAsmSym.Create(sym,def))
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ last:=TTypedAsmSym(current_module.llvmusedsyms.Last);
|
|
|
+ if not assigned(last) or
|
|
|
+ (last.sym<>sym) then
|
|
|
+ current_module.llvmusedsyms.Add(TTypedAsmSym.Create(sym,def))
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
begin
|
|
|
cnodeutils:=tllvmnodeutils;
|
|
|
end.
|