mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 16:49:00 +02:00
* reworked handling of defined/declared symbols in llvm: we now automatically
generate declarations when external symbols are referred in a taillvm instruction * added "declared" field to tasmsymbol for llvm to make avoid declaring a symbol multiple times (harmless, but unnecessary) * all kinds of declarations/definitions are now handled using the new taillvmdecl, the old separate types have been removed git-svn-id: branches/hlcgllvm@27010 -
This commit is contained in:
parent
02ca215272
commit
b82053ef40
@ -158,6 +158,10 @@ interface
|
||||
{$endif AVR}
|
||||
bind : TAsmsymbind;
|
||||
typ : TAsmsymtype;
|
||||
{$ifdef llvm}
|
||||
{ have we generated a declaration for this symbol? }
|
||||
declared : boolean;
|
||||
{$endif llvm}
|
||||
{ Alternate symbol which can be used for 'renaming' needed for
|
||||
asm inlining. Also used for external and common solving during linking }
|
||||
altsymbol : TAsmSymbol;
|
||||
|
@ -104,9 +104,8 @@ interface
|
||||
{$endif JVM}
|
||||
{$ifdef llvm}
|
||||
ait_llvmins, { llvm instruction }
|
||||
ait_llvmprocdef, { start of an llvm procedure }
|
||||
ait_llvmvarsym, { global variable }
|
||||
ait_llvmalias, { alias for a symbol }
|
||||
ait_llvmdecl, { llvm symbol declaration (global/external variable, external procdef) }
|
||||
{$endif}
|
||||
{ SEH directives used in ARM,MIPS and x86_64 COFF targets }
|
||||
ait_seh_directive
|
||||
@ -223,10 +222,9 @@ interface
|
||||
'jcatch',
|
||||
{$endif JVM}
|
||||
{$ifdef llvm}
|
||||
'llvmins', { llvm instruction }
|
||||
'llvmprocdef',
|
||||
'llvmvarsym',
|
||||
'llvmins',
|
||||
'llvmalias',
|
||||
'llvmdecl',
|
||||
{$endif}
|
||||
'seh_directive'
|
||||
);
|
||||
@ -356,6 +354,9 @@ interface
|
||||
{$ifdef JVM}
|
||||
ait_jvar, ait_jcatch,
|
||||
{$endif JVM}
|
||||
{$ifdef llvm}
|
||||
ait_llvmdecl,
|
||||
{$endif llvm}
|
||||
ait_seh_directive
|
||||
];
|
||||
|
||||
|
@ -35,6 +35,9 @@ interface
|
||||
type
|
||||
{ taillvm }
|
||||
taillvm = class(tai_cpu_abstract_sym)
|
||||
private
|
||||
procedure maybe_declare(def: tdef; const ref: treference);
|
||||
public
|
||||
llvmopcode: tllvmop;
|
||||
|
||||
constructor create_llvm(op: tllvmop);
|
||||
@ -131,16 +134,12 @@ interface
|
||||
constructor create(_oldsym: tasmsymbol; const newname: TSymStr; _def: tdef; _vis: tllvmvisibility; _linkage: tllvmlinkage);
|
||||
end;
|
||||
|
||||
{ start of a procedure }
|
||||
taillvmprocdef = class(tailineinfo)
|
||||
procdef: tprocdef;
|
||||
constructor create(_procdef: tprocdef);
|
||||
end;
|
||||
|
||||
{ global variable definition }
|
||||
taillvmvarsym = class(tailineinfo)
|
||||
varsym: tstaticvarsym;
|
||||
constructor create(_varsym: tstaticvarsym);
|
||||
{ declarations/definitions of symbols (procedures, variables), both defined
|
||||
here and external }
|
||||
taillvmdecl = class(tai)
|
||||
namesym: tasmsymbol;
|
||||
def: tdef;
|
||||
constructor create(_namesym: tasmsymbol; _def: tdef);
|
||||
end;
|
||||
|
||||
|
||||
@ -149,13 +148,14 @@ implementation
|
||||
uses
|
||||
cutils, cclasses, strings, aasmcpu;
|
||||
|
||||
{ taillvmvarsym }
|
||||
{ taillvmprocdecl }
|
||||
|
||||
constructor taillvmvarsym.create(_varsym: tstaticvarsym);
|
||||
constructor taillvmdecl.create(_namesym: tasmsymbol; _def: tdef);
|
||||
begin
|
||||
inherited create;
|
||||
typ:=ait_llvmvarsym;
|
||||
varsym:=_varsym;
|
||||
typ:=ait_llvmdecl;
|
||||
namesym:=_namesym;
|
||||
def:=_def;
|
||||
end;
|
||||
|
||||
{ taillvmalias }
|
||||
@ -171,14 +171,6 @@ uses
|
||||
linkage:=_linkage;
|
||||
end;
|
||||
|
||||
{ taillvmprocdef }
|
||||
constructor taillvmprocdef.create(_procdef: tprocdef);
|
||||
begin
|
||||
inherited create;
|
||||
typ:=ait_llvmprocdef;
|
||||
procdef:=_procdef;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
@ -186,6 +178,24 @@ uses
|
||||
taicpu Constructors
|
||||
*****************************************************************************}
|
||||
|
||||
procedure taillvm.maybe_declare(def: tdef; const ref: treference);
|
||||
begin
|
||||
{ add llvm declarations for imported symbols }
|
||||
if not assigned(ref.symbol) or
|
||||
(ref.symbol.declared) or
|
||||
not(ref.symbol.bind in [AB_EXTERNAL,AB_WEAK_EXTERNAL]) then
|
||||
exit;
|
||||
if ref.refaddr<>addr_full then
|
||||
begin
|
||||
if def.typ<>pointerdef then
|
||||
internalerror(2014020701);
|
||||
def:=tpointerdef(def).pointeddef;
|
||||
end;
|
||||
current_asmdata.AsmLists[al_imports].concat(taillvmdecl.create(ref.symbol,def));
|
||||
ref.symbol.declared:=true;
|
||||
end;
|
||||
|
||||
|
||||
constructor taillvm.create_llvm(op: tllvmop);
|
||||
begin
|
||||
create(a_none);
|
||||
@ -555,24 +565,26 @@ uses
|
||||
end;
|
||||
|
||||
|
||||
{ store i32 3, i32* %ptr }
|
||||
constructor taillvm.op_reg_size_ref_size(op: tllvmop; dst: tregister; fromsize: tdef; const src: treference; tosize: tdef);
|
||||
begin
|
||||
create_llvm(op);
|
||||
ops:=4;
|
||||
loadreg(0,dst);
|
||||
maybe_declare(fromsize,src);
|
||||
loaddef(1,fromsize);
|
||||
loadref(2,src);
|
||||
loaddef(3,tosize);
|
||||
end;
|
||||
|
||||
|
||||
{ store i32 3, i32* %ptr }
|
||||
constructor taillvm.op_size_reg_size_ref(op: tllvmop; fromsize: tdef; src: tregister; ptrsize: tdef; const toref: treference);
|
||||
begin
|
||||
create_llvm(op);
|
||||
ops:=4;
|
||||
loaddef(0,fromsize);
|
||||
loadreg(1,src);
|
||||
maybe_declare(ptrsize,toref);
|
||||
loaddef(2,ptrsize);
|
||||
loadref(3,toref);
|
||||
end;
|
||||
@ -582,8 +594,10 @@ uses
|
||||
begin
|
||||
create_llvm(op);
|
||||
ops:=4;
|
||||
maybe_declare(fromsize,src);
|
||||
loaddef(0,fromsize);
|
||||
loadref(1,src);
|
||||
maybe_declare(ptrsize,toref);
|
||||
loaddef(2,ptrsize);
|
||||
loadref(3,toref);
|
||||
end;
|
||||
@ -595,6 +609,7 @@ uses
|
||||
ops:=4;
|
||||
loaddef(0,fromsize);
|
||||
loadconst(1,src);
|
||||
maybe_declare(ptrsize,toref);
|
||||
loaddef(2,ptrsize);
|
||||
loadref(3,toref);
|
||||
end;
|
||||
@ -605,6 +620,7 @@ uses
|
||||
create_llvm(op);
|
||||
ops:=3;
|
||||
loadreg(0,dst);
|
||||
maybe_declare(fromsize,fromref);
|
||||
loaddef(1,fromsize);
|
||||
loadref(2,fromref);
|
||||
end;
|
||||
@ -682,6 +698,7 @@ uses
|
||||
else
|
||||
ops:=5;
|
||||
loadreg(0,dst);
|
||||
maybe_declare(ptrsize,ref);
|
||||
loaddef(1,ptrsize);
|
||||
loadref(2,ref);
|
||||
if indirect then
|
||||
@ -707,6 +724,7 @@ uses
|
||||
else
|
||||
ops:=5;
|
||||
loadreg(0,dst);
|
||||
maybe_declare(ptrsize,ref);
|
||||
loaddef(1,ptrsize);
|
||||
loadref(2,ref);
|
||||
if indirect then
|
||||
|
@ -598,22 +598,47 @@ implementation
|
||||
asmwriteln(tai_symbol(hp).sym.name);
|
||||
// internalerror(2013010705);
|
||||
end;
|
||||
ait_llvmprocdef:
|
||||
ait_llvmdecl:
|
||||
begin
|
||||
asmwrite('define ');
|
||||
asmwrite(llvmencodeproctype(tprocdef(taillvmdecl(hp).def),'',lpd_decl));
|
||||
asmwriteln(' {');
|
||||
end;
|
||||
ait_llvmvarsym:
|
||||
begin
|
||||
asmwrite(taillvmvarsym(hp).varsym.mangledname);
|
||||
if not taillvmvarsym(hp).varsym.globalasmsym then
|
||||
asmwrite(' = internal global ')
|
||||
if taillvmdecl(hp).def.typ=procdef then
|
||||
begin
|
||||
if taillvmdecl(hp).namesym.bind in [AB_EXTERNAL,AB_WEAK_EXTERNAL] then
|
||||
begin
|
||||
asmwrite('declare');
|
||||
asmwriteln(llvmencodeproctype(tprocdef(taillvmdecl(hp).def),taillvmdecl(hp).namesym.name,lpd_decl));
|
||||
end
|
||||
else
|
||||
begin
|
||||
asmwrite('define');
|
||||
asmwrite(llvmencodeproctype(tprocdef(taillvmdecl(hp).def),'',lpd_decl));
|
||||
asmwriteln(' {');
|
||||
end;
|
||||
end
|
||||
else
|
||||
asmwrite(' = global ');
|
||||
asmwrite(llvmencodetype(taillvmvarsym(hp).varsym.vardef));
|
||||
asmwrite(' zeroinitializer, align ');
|
||||
asmwriteln(tostr(taillvmvarsym(hp).varsym.vardef.alignment));
|
||||
begin
|
||||
asmwrite(taillvmdecl(hp).namesym.name);
|
||||
case taillvmdecl(hp).namesym.bind of
|
||||
AB_EXTERNAL:
|
||||
asmwrite(' = external global ');
|
||||
AB_COMMON:
|
||||
asmwrite(' = common global ');
|
||||
AB_LOCAL:
|
||||
asmwrite(' = internal global ');
|
||||
AB_GLOBAL:
|
||||
asmwrite(' = global ');
|
||||
AB_WEAK_EXTERNAL:
|
||||
asmwrite(' = extern_weak global ');
|
||||
AB_PRIVATE_EXTERN:
|
||||
asmwrite('= linker_private global ');
|
||||
else
|
||||
internalerror(2014020104);
|
||||
end;
|
||||
asmwrite(llvmencodetype(taillvmdecl(hp).def));
|
||||
if not(taillvmdecl(hp).namesym.bind in [AB_EXTERNAL,AB_WEAK_EXTERNAL]) then
|
||||
asmwrite(' zeroinitializer');
|
||||
asmwrite(', align ');
|
||||
asmwriteln(tostr(taillvmdecl(hp).def.alignment));
|
||||
end;
|
||||
end;
|
||||
ait_llvmalias:
|
||||
begin
|
||||
|
@ -707,7 +707,7 @@ implementation
|
||||
list.concat(taillvmalias.create(asmsym,item.str,current_procinfo.procdef,llv_default,lll_default));
|
||||
item:=TCmdStrListItem(item.next);
|
||||
end;
|
||||
list.concat(taillvmprocdef.create(current_procinfo.procdef));
|
||||
list.concat(taillvmdecl.create(asmsym,current_procinfo.procdef));
|
||||
end;
|
||||
|
||||
|
||||
|
@ -51,12 +51,18 @@ implementation
|
||||
|
||||
uses
|
||||
verbose,cutils,globals,fmodule,
|
||||
aasmtai,cpubase,llvmbase,aasmllvm,
|
||||
aasmbase,aasmtai,cpubase,llvmbase,aasmllvm,
|
||||
symbase,symtable,defutil;
|
||||
|
||||
class procedure tllvmnodeutils.insertbsssym(list: tasmlist; sym: tstaticvarsym; size: asizeint);
|
||||
var
|
||||
asmsym: tasmsymbol;
|
||||
begin
|
||||
list.concat(taillvmvarsym.Create(sym));
|
||||
if sym.globalasmsym then
|
||||
asmsym:=current_asmdata.DefineAsmSymbol(sym.mangledname,AB_GLOBAL,AT_DATA)
|
||||
else
|
||||
asmsym:=current_asmdata.DefineAsmSymbol(sym.mangledname,AB_LOCAL,AT_DATA);
|
||||
list.concat(taillvmdecl.Create(asmsym,sym.vardef));
|
||||
end;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user