Quellcode durchsuchen

* treat records with {$packrecords c} the same as other records for LLVM
o while in principle LLVM can layout those the same as we do, this would
require special treatment in case some fields are not initialised in
a typed record declaration (because then we have to emit padding only
for the skipped fields, and not for any padding between them)
o exception: records we create to represent parameters, as those have to
match the ABI definitions exactly for them to be treated as expected

git-svn-id: trunk@32714 -

Jonas Maebe vor 9 Jahren
Ursprung
Commit
787caf4dda
5 geänderte Dateien mit 35 neuen und 37 gelöschten Zeilen
  1. 2 11
      compiler/llvm/agllvm.pas
  2. 13 8
      compiler/llvm/llvmdef.pas
  3. 9 10
      compiler/llvm/nllvmtcon.pas
  4. 5 0
      compiler/symconst.pas
  5. 6 8
      compiler/symtable.pas

+ 2 - 11
compiler/llvm/agllvm.pas

@@ -754,12 +754,7 @@ implementation
             tck_record:
               begin
                 writer.AsmWrite(defstr);
-                writer.AsmWrite(' ');
-                if (hp.def.typ in [objectdef,recorddef]) and
-                   (tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment) then
-                  writer.AsmWrite('<{')
-                else
-                  writer.AsmWrite('{');
+                writer.AsmWrite(' <{');
                 first:=true;
                 for p in tai_aggregatetypedconst(hp) do
                   begin
@@ -769,11 +764,7 @@ implementation
                       first:=false;
                     WriteTypedConstData(p);
                   end;
-                if (hp.def.typ in [recorddef,objectdef]) and
-                   (tabstractrecordsymtable(tabstractrecorddef(hp.def).symtable).usefieldalignment<>C_alignment) then
-                  writer.AsmWrite('}>')
-                else
-                  writer.AsmWrite('}');
+                writer.AsmWrite('}>');
               end;
             tck_array:
               begin

+ 13 - 8
compiler/llvm/llvmdef.pas

@@ -459,12 +459,12 @@ implementation
                 end
               else
                 begin
-                  encodedstr:=encodedstr+'{';
+                  encodedstr:=encodedstr+'<{';
                   { code pointer }
                   llvmaddencodedproctype(tabstractprocdef(def),'',lpd_procvar,encodedstr);
                   { data pointer (maybe todo: generate actual layout if
                     available) }
-                  encodedstr:=encodedstr+'*, i8*}';
+                  encodedstr:=encodedstr+'*, i8*}>';
                 end;
             end;
           objectdef :
@@ -535,13 +535,16 @@ implementation
         st: tllvmshadowsymtable;
         symdeflist: tfpobjectlist;
         i: longint;
+        nopacked: boolean;
       begin
         st:=tabstractrecordsymtable(def.symtable).llvmst;
         symdeflist:=st.symdeflist;
 
-        if tabstractrecordsymtable(def.symtable).usefieldalignment<>C_alignment then
-          encodedstr:=encodedstr+'<';
-        encodedstr:=encodedstr+'{ ';
+        nopacked:=df_llvm_no_struct_packing in def.defoptions;
+        if nopacked then
+          encodedstr:=encodedstr+'{ '
+        else
+          encodedstr:=encodedstr+'<{ ';
         if symdeflist.count>0 then
           begin
             i:=0;
@@ -563,9 +566,10 @@ implementation
                 inc(i);
               end;
           end;
-        encodedstr:=encodedstr+' }';
-        if tabstractrecordsymtable(def.symtable).usefieldalignment<>C_alignment then
-          encodedstr:=encodedstr+'>';
+        if nopacked then
+          encodedstr:=encodedstr+' }'
+        else
+          encodedstr:=encodedstr+' }>';
       end;
 
 
@@ -830,6 +834,7 @@ implementation
         result:=llvmgettemprecorddef(retdeflist,C_alignment,
           targetinfos[target_info.system]^.alignment.recordalignmin,
           targetinfos[target_info.system]^.alignment.maxCrecordalign);
+        include(result.defoptions,df_llvm_no_struct_packing);
       end;
 
 

+ 9 - 10
compiler/llvm/nllvmtcon.pas

@@ -117,13 +117,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;
+     begin
+       result:=inherited;
+       { in case we let LLVM align, don't add padding ourselves }
+       if df_llvm_no_struct_packing in def.defoptions then
+         result:=0;
+     end;
 
 
    { tllvmtypedconstplaceholder }
@@ -301,10 +302,8 @@ implementation
 
   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
+      { in case we let LLVM align, don't add padding ourselves }
+      if df_llvm_no_struct_packing in def.defoptions then
         exit;
       inherited;
     end;

+ 5 - 0
compiler/symconst.pas

@@ -219,6 +219,11 @@ type
       across units) -- never stored to ppu, because in that case the def would
       be registered }
     df_not_registered_no_free
+{$ifdef llvm}
+    { can't do this via symllvm because we have to access it in symtable }
+    ,
+    df_llvm_no_struct_packing
+{$endif llvm}
   );
   tdefoptions=set of tdefoption;
 

+ 6 - 8
compiler/symtable.pas

@@ -1819,9 +1819,6 @@ implementation
         tmpsize: aint;
       begin
         case equivst.usefieldalignment of
-          C_alignment:
-            { default for llvm, don't add explicit padding }
-            symdeflist.add(tllvmshadowsymtableentry.create(vardef,fieldoffset));
           bit_alignment:
             begin
               { curoffset: bit address after the previous field.      }
@@ -1857,7 +1854,7 @@ implementation
                     inc(curroffset,tobjectsymtable(tobjectdef(vardef).symtable).datasize*8);
                end;
             end
-          else
+          else if not(df_llvm_no_struct_packing in tdef(equivst.defowner).defoptions) then
             begin
               { curoffset: address right after the previous field }
               while (fieldoffset>curroffset) do
@@ -1871,6 +1868,9 @@ implementation
               else
                 inc(curroffset,tobjectsymtable(tobjectdef(vardef).symtable).datasize);
             end
+          else
+            { default for llvm, don't add explicit padding }
+            symdeflist.add(tllvmshadowsymtableentry.create(vardef,fieldoffset));
         end
       end;
 
@@ -1879,11 +1879,9 @@ implementation
       begin
         case equivst.usefieldalignment of
           { already correct in this case }
-          bit_alignment,
-          { handled by llvm }
-          C_alignment:
+          bit_alignment:
             ;
-          else
+          else if not(df_llvm_no_struct_packing in tdef(equivst.defowner).defoptions) then
             begin
               { add padding fields }
               while (finalsize>curroffset) do