Forráskód Böngészése

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

Jonas Maebe 11 éve
szülő
commit
b82053ef40

+ 4 - 0
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;

+ 6 - 5
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
                     ];
 

+ 41 - 23
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

+ 39 - 14
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

+ 1 - 1
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;
 
 

+ 8 - 2
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;