/// Enum used to categorize the alignment types stored by LayoutAlignElem
enum AlignTypeEnum {
- INVALID_ALIGN = 0, ///< An invalid alignment
- INTEGER_ALIGN = 'i', ///< Integer type alignment
- VECTOR_ALIGN = 'v', ///< Vector type alignment
- FLOAT_ALIGN = 'f', ///< Floating point type alignment
- AGGREGATE_ALIGN = 'a' ///< Aggregate alignment
+ INVALID_ALIGN = 0,
+ INTEGER_ALIGN = 'i',
+ VECTOR_ALIGN = 'v',
+ FLOAT_ALIGN = 'f',
+ AGGREGATE_ALIGN = 'a'
};
+// FIXME: Currently the DataLayout string carries a "preferred alignment"
+// for types. As the DataLayout is module/global, this should likely be
+// sunk down to an FTTI element that is queried rather than a global
+// preference.
+
/// \brief Layout alignment element.
///
/// Stores the alignment data associated with a given alignment type (integer,
/// \note The unusual order of elements in the structure attempts to reduce
/// padding and make the structure slightly more cache friendly.
struct LayoutAlignElem {
- unsigned AlignType : 8; ///< Alignment type (AlignTypeEnum)
- unsigned TypeBitWidth : 24; ///< Type bit width
- unsigned ABIAlign : 16; ///< ABI alignment for this type/bitw
- unsigned PrefAlign : 16; ///< Pref. alignment for this type/bitw
+ /// \brief Alignment type from \c AlignTypeEnum
+ unsigned AlignType : 8;
+ unsigned TypeBitWidth : 24;
+ unsigned ABIAlign : 16;
+ unsigned PrefAlign : 16;
static LayoutAlignElem get(AlignTypeEnum align_type, unsigned abi_align,
unsigned pref_align, uint32_t bit_width);
/// \note The unusual order of elements in the structure attempts to reduce
/// padding and make the structure slightly more cache friendly.
struct PointerAlignElem {
- unsigned ABIAlign; ///< ABI alignment for this type/bitw
- unsigned PrefAlign; ///< Pref. alignment for this type/bitw
- uint32_t TypeByteWidth; ///< Type byte width
- uint32_t AddressSpace; ///< Address space for the pointer type
+ unsigned ABIAlign;
+ unsigned PrefAlign;
+ uint32_t TypeByteWidth;
+ uint32_t AddressSpace;
/// Initializer
static PointerAlignElem get(uint32_t AddressSpace, unsigned ABIAlign,
- unsigned PrefAlign, uint32_t TypeByteWidth);
+ unsigned PrefAlign, uint32_t TypeByteWidth);
bool operator==(const PointerAlignElem &rhs) const;
};
class DataLayout {
private:
/// Defaults to false.
- bool LittleEndian;
+ bool BigEndian;
- unsigned StackNaturalAlign;
+ unsigned StackNaturalAlign;
enum ManglingModeT {
MM_None,
MM_ELF,
MM_MachO,
- MM_WINCOFF,
+ MM_WinCOFF,
+ MM_WinCOFFX86,
MM_Mips
};
ManglingModeT ManglingMode;
/// \brief Primitive type alignment data.
SmallVector<LayoutAlignElem, 16> Alignments;
+ /// \brief The string representation used to create this DataLayout
+ std::string StringRepresentation;
+
typedef SmallVector<PointerAlignElem, 8> PointersTy;
PointersTy Pointers;
/// \brief Valid pointer predicate.
///
- /// Predicate that tests a PointerAlignElem reference returned by get() against
- /// InvalidPointerElem.
+ /// Predicate that tests a PointerAlignElem reference returned by get()
+ /// against \c InvalidPointerElem.
bool validPointer(const PointerAlignElem &align) const {
return &align != &InvalidPointerElem;
}
DataLayout &operator=(const DataLayout &DL) {
clear();
- LittleEndian = DL.isLittleEndian();
+ StringRepresentation = DL.StringRepresentation;
+ BigEndian = DL.isBigEndian();
StackNaturalAlign = DL.StackNaturalAlign;
ManglingMode = DL.ManglingMode;
LegalIntWidths = DL.LegalIntWidths;
bool operator==(const DataLayout &Other) const;
bool operator!=(const DataLayout &Other) const { return !(*this == Other); }
- ~DataLayout(); // Not virtual, do not subclass this class
+ ~DataLayout(); // Not virtual, do not subclass this class
/// Parse a data layout string (with fallback to default values).
void reset(StringRef LayoutDescription);
/// Layout endianness...
- bool isLittleEndian() const { return LittleEndian; }
- bool isBigEndian() const { return !LittleEndian; }
+ bool isLittleEndian() const { return !BigEndian; }
+ bool isBigEndian() const { return BigEndian; }
/// \brief Returns the string representation of the DataLayout.
///
/// This representation is in the same format accepted by the string
- /// constructor above.
- std::string getStringRepresentation() const;
+ /// constructor above. This should not be used to compare two DataLayout as
+ /// different string can represent the same layout.
+ const std::string &getStringRepresentation() const {
+ return StringRepresentation;
+ }
+
+ /// \brief Test if the DataLayout was constructed from an empty string.
+ bool isDefault() const { return StringRepresentation.empty(); }
/// \brief Returns true if the specified type is known to be a native integer
/// type supported by the CPU.
return false;
}
- bool isIllegalInteger(unsigned Width) const {
- return !isLegalInteger(Width);
- }
+ bool isIllegalInteger(unsigned Width) const { return !isLegalInteger(Width); }
/// Returns true if the given alignment exceeds the natural stack alignment.
bool exceedsNaturalStackAlignment(unsigned Align) const {
return (StackNaturalAlign != 0) && (Align > StackNaturalAlign);
}
+ unsigned getStackAlignment() const { return StackNaturalAlign; }
+
bool hasMicrosoftFastStdCallMangling() const {
- return ManglingMode == MM_WINCOFF;
+ return ManglingMode == MM_WinCOFFX86;
}
- bool hasLinkerPrivateGlobalPrefix() const {
- return ManglingMode == MM_MachO;
- }
+ bool hasLinkerPrivateGlobalPrefix() const { return ManglingMode == MM_MachO; }
const char *getLinkerPrivateGlobalPrefix() const {
if (ManglingMode == MM_MachO)
return "l";
- return getPrivateGlobalPrefix();
+ return "";
}
char getGlobalPrefix() const {
case MM_None:
case MM_ELF:
case MM_Mips:
+ case MM_WinCOFF:
return '\0';
case MM_MachO:
- case MM_WINCOFF:
+ case MM_WinCOFFX86:
return '_';
}
llvm_unreachable("invalid mangling mode");
case MM_Mips:
return "$";
case MM_MachO:
- case MM_WINCOFF:
+ case MM_WinCOFF:
+ case MM_WinCOFFX86:
return "L";
}
llvm_unreachable("invalid mangling mode");
///
/// For example, returns 5 for i36 and 10 for x86_fp80.
uint64_t getTypeStoreSize(Type *Ty) const {
- return (getTypeSizeInBits(Ty)+7)/8;
+ return (getTypeSizeInBits(Ty) + 7) / 8;
}
/// \brief Returns the maximum number of bits that may be overwritten by
///
/// For example, returns 40 for i36 and 80 for x86_fp80.
uint64_t getTypeStoreSizeInBits(Type *Ty) const {
- return 8*getTypeStoreSize(Ty);
+ return 8 * getTypeStoreSize(Ty);
}
/// \brief Returns the offset in bytes between successive objects of the
/// This is the amount that alloca reserves for this type. For example,
/// returns 96 or 128 for x86_fp80, depending on alignment.
uint64_t getTypeAllocSizeInBits(Type *Ty) const {
- return 8*getTypeAllocSize(Ty);
+ return 8 * getTypeAllocSize(Ty);
}
/// \brief Returns the minimum ABI-required alignment for the specified type.
const StructLayout *getStructLayout(StructType *Ty) const;
/// \brief Returns the preferred alignment of the specified global.
- ///
+ ///
/// This includes an explicitly requested alignment (if the global has one).
unsigned getPreferredAlignment(const GlobalVariable *GV) const;
};
inline DataLayout *unwrap(LLVMTargetDataRef P) {
- return reinterpret_cast<DataLayout*>(P);
+ return reinterpret_cast<DataLayout *>(P);
}
inline LLVMTargetDataRef wrap(const DataLayout *P) {
- return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P));
+ return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout *>(P));
}
-class DataLayoutPass : public ImmutablePass {
- DataLayout DL;
-
-public:
- /// This has to exist, because this is a pass, but it should never be used.
- DataLayoutPass();
- ~DataLayoutPass();
-
- const DataLayout &getDataLayout() const { return DL; }
-
- static char ID; // Pass identification, replacement for typeid
-
- bool doFinalization(Module &M) override;
- bool doInitialization(Module &M) override;
-};
-
/// Used to lazily calculate structure layout information for a target machine,
/// based on the DataLayout structure.
class StructLayout {
uint64_t StructSize;
unsigned StructAlignment;
- unsigned NumElements;
- uint64_t MemberOffsets[1]; // variable sized array!
+ bool IsPadded : 1;
+ unsigned NumElements : 31;
+ uint64_t MemberOffsets[1]; // variable sized array!
public:
+ uint64_t getSizeInBytes() const { return StructSize; }
- uint64_t getSizeInBytes() const {
- return StructSize;
- }
+ uint64_t getSizeInBits() const { return 8 * StructSize; }
- uint64_t getSizeInBits() const {
- return 8*StructSize;
- }
+ unsigned getAlignment() const { return StructAlignment; }
- unsigned getAlignment() const {
- return StructAlignment;
- }
+ /// Returns whether the struct has padding or not between its fields.
+ /// NB: Padding in nested element is not taken into account.
+ bool hasPadding() const { return IsPadded; }
/// \brief Given a valid byte offset into the structure, returns the structure
/// index that contains it.
}
uint64_t getElementOffsetInBits(unsigned Idx) const {
- return getElementOffset(Idx)*8;
+ return getElementOffset(Idx) * 8;
}
private:
- friend class DataLayout; // Only DataLayout can create this class
+ friend class DataLayout; // Only DataLayout can create this class
StructLayout(StructType *ST, const DataLayout &DL);
};
-
// The implementation of this method is provided inline as it is particularly
// well suited to constant folding when called on a specific Type subclass.
inline uint64_t DataLayout::getTypeSizeInBits(Type *Ty) const {
case Type::PPC_FP128TyID:
case Type::FP128TyID:
return 128;
- // In memory objects this is always aligned to a higher boundary, but
+ // In memory objects this is always aligned to a higher boundary, but
// only 80 bits contain information.
case Type::X86_FP80TyID:
return 80;