llvm.org GIT mirror llvm / a0fcc08
Change packed struct layout so that field sizes are the same as in unpacked structs, only field positions differ. This only matters for structs containing x86 long double or an apint; it may cause backwards compatibility problems if someone has bitcode containing a packed struct with a field of one of those types. The issue is that only 10 bytes are needed to hold an x86 long double: the store size is 10 bytes, but the ABI size is 12 or 16 bytes (linux/ darwin) which comes from rounding the store size up by the alignment. Because it seemed silly not to pack an x86 long double into 10 bytes in a packed struct, this is what was done. I now think this was a mistake. Reserving the ABI size for an x86 long double field even in a packed struct makes things more uniform: the ABI size is now always used when reserving space for a type. This means that developers are less likely to make mistakes. It also makes life easier for the CBE which otherwise could not represent all LLVM packed structs (PR2402). Front-end people might need to adjust the way they create LLVM structs - see following change to llvm-gcc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51928 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan Sands 11 years ago
5 changed file(s) with 30 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
313313 void EmitConstantValueOnly(const Constant *CV);
314314
315315 /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
316 /// If Packed is false, pad to the ABI size.
317 void EmitGlobalConstant(const Constant* CV, bool Packed = false);
316 void EmitGlobalConstant(const Constant* CV);
318317
319318 virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
320319
888888 }
889889
890890 /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
891 /// If Packed is false, pad to the ABI size.
892 void AsmPrinter::EmitGlobalConstant(const Constant *CV, bool Packed) {
891 void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
893892 const TargetData *TD = TM.getTargetData();
894 unsigned Size = Packed ?
895 TD->getTypeStoreSize(CV->getType()) : TD->getABITypeSize(CV->getType());
893 unsigned Size = TD->getABITypeSize(CV->getType());
896894
897895 if (CV->isNullValue() || isa(CV)) {
898896 EmitZeros(Size);
902900 EmitString(CVA);
903901 } else { // Not a string. Print the values in successive locations
904902 for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i)
905 EmitGlobalConstant(CVA->getOperand(i), false);
903 EmitGlobalConstant(CVA->getOperand(i));
906904 }
907905 return;
908906 } else if (const ConstantStruct *CVS = dyn_cast(CV)) {
913911 const Constant* field = CVS->getOperand(i);
914912
915913 // Check if padding is needed and insert one or more 0s.
916 uint64_t fieldSize = TD->getTypeStoreSize(field->getType());
914 uint64_t fieldSize = TD->getABITypeSize(field->getType());
917915 uint64_t padSize = ((i == e-1 ? Size : cvsLayout->getElementOffset(i+1))
918916 - cvsLayout->getElementOffset(i)) - fieldSize;
919917 sizeSoFar += fieldSize + padSize;
920918
921 // Now print the actual field value without ABI size padding.
922 EmitGlobalConstant(field, true);
919 // Now print the actual field value.
920 EmitGlobalConstant(field);
923921
924922 // Insert padding - this may include padding to increase the size of the
925923 // current field up to the ABI size (if the struct is not packed) as well
10651063 const VectorType *PTy = CP->getType();
10661064
10671065 for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I)
1068 EmitGlobalConstant(CP->getOperand(I), false);
1066 EmitGlobalConstant(CP->getOperand(I));
10691067
10701068 return;
10711069 }
4747 // Loop over each of the elements, placing them in memory...
4848 for (unsigned i = 0, e = NumElements; i != e; ++i) {
4949 const Type *Ty = ST->getElementType(i);
50 unsigned TyAlign = ST->isPacked() ?
51 1 : TD.getABITypeAlignment(Ty);
52 uint64_t TySize = ST->isPacked() ?
53 TD.getTypeStoreSize(Ty) : TD.getABITypeSize(Ty);
50 unsigned TyAlign = ST->isPacked() ? 1 : TD.getABITypeAlignment(Ty);
5451
5552 // Add padding if necessary to align the data element properly...
5653 StructSize = (StructSize + TyAlign - 1)/TyAlign * TyAlign;
5956 StructAlignment = std::max(TyAlign, StructAlignment);
6057
6158 MemberOffsets[i] = StructSize;
62 StructSize += TySize; // Consume space for this data item
59 StructSize += TD.getABITypeSize(Ty); // Consume space for this data item
6360 }
6461
6562 // Empty structures have alignment of 1 byte.
736736
737737 /// HasPadding - Return true if the specified type has any structure or
738738 /// alignment padding, false otherwise.
739 static bool HasPadding(const Type *Ty, const TargetData &TD,
740 bool inPacked = false) {
739 static bool HasPadding(const Type *Ty, const TargetData &TD) {
741740 if (const StructType *STy = dyn_cast(Ty)) {
742741 const StructLayout *SL = TD.getStructLayout(STy);
743742 unsigned PrevFieldBitOffset = 0;
745744 unsigned FieldBitOffset = SL->getElementOffsetInBits(i);
746745
747746 // Padding in sub-elements?
748 if (HasPadding(STy->getElementType(i), TD, STy->isPacked()))
747 if (HasPadding(STy->getElementType(i), TD))
749748 return true;
750749
751750 // Check to see if there is any padding between this element and the
769768 }
770769
771770 } else if (const ArrayType *ATy = dyn_cast(Ty)) {
772 return HasPadding(ATy->getElementType(), TD, false);
771 return HasPadding(ATy->getElementType(), TD);
773772 } else if (const VectorType *VTy = dyn_cast(Ty)) {
774 return HasPadding(VTy->getElementType(), TD, false);
775 }
776 return inPacked ?
777 false : TD.getTypeSizeInBits(Ty) != TD.getABITypeSizeInBits(Ty);
773 return HasPadding(VTy->getElementType(), TD);
774 }
775 return TD.getTypeSizeInBits(Ty) != TD.getABITypeSizeInBits(Ty);
778776 }
779777
780778 /// isSafeStructAllocaToScalarRepl - Check to see if the specified allocation of
0 ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep true
1
2 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
3 target triple = "x86_64-unknown-linux-gnu"
4 %packed = type <{ x86_fp80, i8 }>
5 %unpacked = type { x86_fp80, i8 }
6
7 define i1 @q() nounwind {
8 entry:
9 %char_p = getelementptr %packed* null, i32 0, i32 1 ; [#uses=1]
10 %char_u = getelementptr %unpacked* null, i32 0, i32 1 ; [#uses=1]
11 %res = icmp eq i8* %char_p, %char_u ; [#uses=1]
12 ret i1 %res
13 }