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

View File

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

View File

@ -117,13 +117,14 @@ implementation
fanonrecalignpos:=-1; fanonrecalignpos:=-1;
end; end;
function tllvmaggregateinformation.prepare_next_field(nextfielddef: tdef): asizeint; function tllvmaggregateinformation.prepare_next_field(nextfielddef: tdef): asizeint;
begin begin
result:=inherited; result:=inherited;
{ in case of C/ABI alignment, the padding gets added by LLVM } { in case we let LLVM align, don't add padding ourselves }
if tabstractrecordsymtable(tabstractrecorddef(def).symtable).usefieldalignment=C_alignment then if df_llvm_no_struct_packing in def.defoptions then
result:=0; result:=0;
end; end;
{ tllvmtypedconstplaceholder } { tllvmtypedconstplaceholder }
@ -301,10 +302,8 @@ implementation
procedure tllvmtai_typedconstbuilder.maybe_emit_tail_padding(def: tdef); procedure tllvmtai_typedconstbuilder.maybe_emit_tail_padding(def: tdef);
begin begin
{ in case of C/ABI alignment, the padding gets added by LLVM } { in case we let LLVM align, don't add padding ourselves }
if (is_record(def) or if df_llvm_no_struct_packing in def.defoptions then
is_object(def)) and
(tabstractrecordsymtable(tabstractrecorddef(def).symtable).usefieldalignment=C_alignment) then
exit; exit;
inherited; inherited;
end; end;

View File

@ -219,6 +219,11 @@ type
across units) -- never stored to ppu, because in that case the def would across units) -- never stored to ppu, because in that case the def would
be registered } be registered }
df_not_registered_no_free 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; tdefoptions=set of tdefoption;

View File

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