* 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:
Jonas Maebe 2014-03-06 21:42:03 +00:00
parent 02ca215272
commit b82053ef40
6 changed files with 99 additions and 45 deletions

View File

@ -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;

View File

@ -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
];

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;