From b82053ef401ac1cdcdf46d9d57a5dfc4a66ac996 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Thu, 6 Mar 2014 21:42:03 +0000 Subject: [PATCH] * 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 - --- compiler/aasmbase.pas | 4 +++ compiler/aasmtai.pas | 11 ++++--- compiler/llvm/aasmllvm.pas | 64 ++++++++++++++++++++++++------------- compiler/llvm/agllvm.pas | 53 ++++++++++++++++++++++-------- compiler/llvm/hlcgllvm.pas | 2 +- compiler/llvm/nllvmutil.pas | 10 ++++-- 6 files changed, 99 insertions(+), 45 deletions(-) diff --git a/compiler/aasmbase.pas b/compiler/aasmbase.pas index 18ca27814e..1a22316436 100644 --- a/compiler/aasmbase.pas +++ b/compiler/aasmbase.pas @@ -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; diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas index 0a5b5ddfdc..6dda7ddedb 100644 --- a/compiler/aasmtai.pas +++ b/compiler/aasmtai.pas @@ -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 ]; diff --git a/compiler/llvm/aasmllvm.pas b/compiler/llvm/aasmllvm.pas index 157766910f..3371761fdd 100644 --- a/compiler/llvm/aasmllvm.pas +++ b/compiler/llvm/aasmllvm.pas @@ -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 diff --git a/compiler/llvm/agllvm.pas b/compiler/llvm/agllvm.pas index 56000303d0..dc969424b3 100644 --- a/compiler/llvm/agllvm.pas +++ b/compiler/llvm/agllvm.pas @@ -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 diff --git a/compiler/llvm/hlcgllvm.pas b/compiler/llvm/hlcgllvm.pas index ea59b47a7d..8dad47e359 100644 --- a/compiler/llvm/hlcgllvm.pas +++ b/compiler/llvm/hlcgllvm.pas @@ -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; diff --git a/compiler/llvm/nllvmutil.pas b/compiler/llvm/nllvmutil.pas index 62bcfef029..e391fa4c2d 100644 --- a/compiler/llvm/nllvmutil.pas +++ b/compiler/llvm/nllvmutil.pas @@ -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;