* 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 -
This commit is contained in:
Jonas Maebe 2015-12-25 21:05:22 +00:00
parent f57a94b5aa
commit 787caf4dda
5 changed files with 35 additions and 37 deletions

View File

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

View File

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

View File

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

View File

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

View File

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