Selaa lähdekoodia

* several fixes for emitting aggregate typed constants with C/ABI packing:
o don't emit explicit padding bytes (LLVM adds them)
o don't mark them in LLVM as packed either

git-svn-id: trunk@31187 -

Jonas Maebe 10 vuotta sitten
vanhempi
commit
7a8b5fd6c5
3 muutettua tiedostoa jossa 60 lisäystä ja 21 poistoa
  1. 28 18
      compiler/aasmcnst.pas
  2. 9 3
      compiler/llvm/agllvm.pas
  3. 23 0
      compiler/llvm/nllvmtcon.pas

+ 28 - 18
compiler/aasmcnst.pas

@@ -153,7 +153,7 @@ type
      constructor create(_def: tdef; _typ: ttypedconstkind); virtual;
      { calculated padding bytes for alignment if needed, and add the def of the
        next field in case we are constructing an anonymous record }
-     function prepare_next_field(nextfielddef: tdef): asizeint;
+     function prepare_next_field(nextfielddef: tdef): asizeint; virtual;
 
      property def: tdef read fdef;
      property typ: ttypedconstkind read ftyp;
@@ -269,6 +269,7 @@ type
      procedure emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); virtual;
 
     protected
+     procedure maybe_emit_tail_padding(def: tdef); virtual;
      function emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; var startlab: tasmlabel):tasmlabofs;
      procedure begin_aggregate_internal(def: tdef; anonymous: boolean); virtual;
      procedure end_aggregate_internal(def: tdef; anonymous: boolean); virtual;
@@ -1009,6 +1010,30 @@ implementation
      end;
 
 
+   procedure ttai_typedconstbuilder.maybe_emit_tail_padding(def: tdef);
+     var
+       info: taggregateinformation;
+       fillbytes: asizeint;
+     begin
+       info:=curagginfo;
+       if not assigned(info) then
+         internalerror(2014091002);
+       if def<>info.def then
+         internalerror(2014091205);
+       if (is_record(def) or
+           is_object(def)) and
+          not is_packed_record_or_object(def) then
+         begin
+           fillbytes:=def.size-info.curoffset;
+           while fillbytes>0 do
+             begin
+               do_emit_tai(Tai_const.Create_8bit(0),u8inttype);
+               dec(fillbytes)
+             end;
+         end;
+     end;
+
+
    function ttai_typedconstbuilder.emit_string_const_common(stringtype: tstringtype; len: asizeint; encoding: tstringencoding; var startlab: tasmlabel): tasmlabofs;
      var
        string_symofs: asizeint;
@@ -1102,30 +1127,15 @@ implementation
    procedure ttai_typedconstbuilder.end_aggregate_internal(def: tdef; anonymous: boolean);
      var
        info: taggregateinformation;
-       fillbytes: asizeint;
        tck: ttypedconstkind;
      begin
        tck:=aggregate_kind(def);
        if tck=tck_simple then
          exit;
-       info:=curagginfo;
-       if not assigned(info) then
-         internalerror(2014091002);
-       if def<>info.def then
-         internalerror(2014091205);
        { add tail padding if necessary }
-       if (is_record(def) or
-           is_object(def)) and
-          not is_packed_record_or_object(def) then
-         begin
-           fillbytes:=def.size-info.curoffset;
-           while fillbytes>0 do
-             begin
-               do_emit_tai(Tai_const.Create_8bit(0),u8inttype);
-               dec(fillbytes)
-             end;
-         end;
+       maybe_emit_tail_padding(def);
        { pop and free the information }
+       info:=curagginfo;
        faggregateinformation.count:=faggregateinformation.count-1;
        info.free;
      end;

+ 9 - 3
compiler/llvm/agllvm.pas

@@ -81,7 +81,7 @@ implementation
       SysUtils,
       cutils,cfileutl,systems,
       fmodule,verbose,
-      aasmcnst,symconst,symdef,
+      aasmcnst,symconst,symdef,symtable,
       llvmbase,aasmllvm,itllvm,llvmdef,
       cgbase,cgutils,cpubase;
 
@@ -685,7 +685,10 @@ implementation
               begin
                 AsmWrite(defstr);
                 AsmWrite(' ');
-                AsmWrite('<{');
+                if tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment then
+                  AsmWrite('<{')
+                else
+                  AsmWrite('{');
                 first:=true;
                 for p in tai_aggregatetypedconst(hp) do
                   begin
@@ -695,7 +698,10 @@ implementation
                       first:=false;
                     WriteTypedConstData(p);
                   end;
-                AsmWrite('}>');
+                if tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment then
+                  AsmWrite('}>')
+                else
+                  AsmWrite('}');
               end;
             tck_array:
               begin

+ 23 - 0
compiler/llvm/nllvmtcon.pas

@@ -39,6 +39,8 @@ interface
      public
       constructor create(_def: tdef; _typ: ttypedconstkind); override;
 
+      function prepare_next_field(nextfielddef: tdef): asizeint; override;
+
       property aggai: tai_aggregatetypedconst read faggai write faggai;
       property anonrecalignpos: longint read fanonrecalignpos write fanonrecalignpos;
     end;
@@ -66,11 +68,14 @@ interface
       procedure do_emit_tai(p: tai; def: tdef); override;
       procedure mark_anon_aggregate_alignment; override;
       procedure insert_marked_aggregate_alignment(def: tdef); override;
+      procedure maybe_emit_tail_padding(def: tdef); override;
       procedure begin_aggregate_internal(def: tdef; anonymous: boolean); override;
       procedure end_aggregate_internal(def: tdef; anonymous: boolean); override;
 
       function get_internal_data_section_start_label: tasmlabel; override;
       function get_internal_data_section_internal_label: tasmlabel; override;
+
+      procedure do_emit_extended_in_aggregate(p: tai);
      public
       destructor destroy; override;
       procedure emit_tai(p: tai; def: tdef); override;
@@ -104,6 +109,14 @@ implementation
        fanonrecalignpos:=-1;
      end;
 
+   function tllvmaggregateinformation.prepare_next_field(nextfielddef: tdef): asizeint;
+    begin
+      result:=inherited;
+      { in case of C/ABI alignment, the padding gets added by LLVM }
+      if tabstractrecordsymtable(tabstractrecorddef(def).symtable).usefieldalignment=C_alignment then
+        result:=0;
+    end;
+
 
   class constructor tllvmtai_typedconstbuilder.classcreate;
     begin
@@ -249,6 +262,16 @@ implementation
         end;
     end;
 
+  procedure tllvmtai_typedconstbuilder.maybe_emit_tail_padding(def: tdef);
+    begin
+      { in case of C/ABI alignment, the padding gets added by LLVM }
+      if (is_record(def) or
+          is_object(def)) and
+         (tabstractrecordsymtable(tabstractrecorddef(def).symtable).usefieldalignment=C_alignment) then
+        exit;
+      inherited;
+    end;
+
 
   procedure tllvmtai_typedconstbuilder.emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef);
     begin