Revamped the TargetData spec string so that alignments for differently sized types can be more flexibly specified. Also added support for vector alignments (32 and 64 bits). The default spec string now looks like:
"E-p:64:64:64-a0:0:0-f32:32:32-f64:0:64" "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:0:64" "-v64:64:64-v128:128:128" Although, it should be noted, that this isn't actually parsed (it's the result of calling TargetData::getRepresentation()). Internally, a SmallVector is created with these various and sundry types, sizes and alignments. Gratuitously changed "getTypeAlignmentABI" to "getABITypeAlignment" and "getTypeAlignmentPref" to "getPrefTypeAlignment". Slimmed down the TargetData code so that there are fewer moving parts -- if changes have to be made, it's should be more maintainable. -scooter -- Scott Michel [EMAIL PROTECTED] High Performance Hardware Section Manager 310/336-5034 Computer Systems Research Department The Aerospace Corporation
Index: include/llvm/Target/TargetData.h =================================================================== --- include/llvm/Target/TargetData.h (.../trunk) (revision 423) +++ include/llvm/Target/TargetData.h (.../branches/llvm-spu) (revision 423) @@ -23,6 +23,7 @@ #include "llvm/Pass.h" #include "llvm/Support/DataTypes.h" #include <vector> +#include "llvm/ADT/SmallVector.h" #include <string> namespace llvm { @@ -33,45 +34,120 @@ class StructLayout; class GlobalVariable; +/// Enum used to categorize the alignment types stored by TargetAlignElem +enum AlignTypeEnum { + INTEGER_ALIGN = 'i', ///< Integer type alignment + PACKED_ALIGN = 'v', ///< Vector type alignment + FLOAT_ALIGN = 'f', ///< Floating point type alignment + AGGREGATE_ALIGN = 'a' ///< Aggregate alignment +}; +/// Target alignment element. +/// +/// Stores the alignment data associated with a given alignment type (pointer, +/// integer, packed/vector, float) and type bit width. +/// +/// @note The unusual order of elements in the structure attempts to reduce +/// padding and make the structure slightly more cache friendly. +struct TargetAlignElem { + unsigned char AlignType; //< Alignment type (AlignTypeEnum) + unsigned char ABIAlign; //< ABI alignment for this type/bitw + unsigned char PrefAlign; //< Preferred alignment for this type/bitw + short TypeBitWidth; //< Type bit width + + /// Default constructor + TargetAlignElem(); + /// Full constructor + TargetAlignElem(AlignTypeEnum align_type, unsigned char abi_align, + unsigned char pref_align, short bit_width); + /// Copy constructor + TargetAlignElem(const TargetAlignElem &src); + /// Destructor + ~TargetAlignElem() { } + /// Assignment operator + TargetAlignElem &operator=(const TargetAlignElem &rhs); + /// Less-than predicate + bool operator<(const TargetAlignElem &rhs) const; + /// Equality predicate + bool operator==(const TargetAlignElem &rhs) const; + /// output stream operator + std::ostream &dump(std::ostream &os) const; +}; + +/// Output stream inserter +/// @sa TargetAlignElem::dump() +std::ostream &operator<<(std::ostream &os, const TargetAlignElem &elem); + +/// Target alignment container +/// +/// This is the container for most primitive types' alignment, i.e., integer, +/// floating point, vectors and aggregates. +class TargetAlign : public SmallVector<TargetAlignElem, 16> { +private: + /// Invalid alignment + /// This member is a signal that a requested alignment type and + /// bit width were not found in the SmallVector. + static const TargetAlignElem InvalidAlignmentElem; +public: + /// Default constructor + TargetAlign(); + /// Destructor + ~TargetAlign() { } + /// Copy constructor + TargetAlign(const TargetAlign &src); + /// Assignment operator + TargetAlign &operator=(const TargetAlign &rhs); + /// Add elements to the container. + /// + /// Adds elements to the container, keeping the container sorted. If the + /// requested alignment type (@a align_type) and bit width (@a bit_width) + /// exist in the container, then the matching element's ABI and preferred + /// alignments are overwritten with @a abi_align and @a pref_align. + void set(AlignTypeEnum align_type, short bit_width, unsigned char abi_align, + unsigned char pref_align); + /// Get the data associated with a given alignment type and bit width. + /// + /// @return InvalidAlignmentElem if not found, otherwise, the matching + /// TargetAlignElem. + const TargetAlignElem &get(AlignTypeEnum align_type, short bit_width) const; + /// Valid alignment predicate. + /// + /// Predicate that tests a TargetAlignElem reference returned by get() against + /// InvalidAlignmentElem. + inline bool valid(const TargetAlignElem &align) const { + return (&align != &InvalidAlignmentElem); + } +}; + class TargetData : public ImmutablePass { - bool LittleEndian; // Defaults to false +private: + bool LittleEndian; ///< Defaults to false + unsigned char PointerMemSize; ///< Pointer size in bytes + unsigned char PointerABIAlign; ///< Pointer ABI alignment + unsigned char PointerPrefAlign; ///< Pointer preferred global alignment - // ABI alignments - unsigned char BoolABIAlignment; // Defaults to 1 byte - unsigned char ByteABIAlignment; // Defaults to 1 byte - unsigned char ShortABIAlignment; // Defaults to 2 bytes - unsigned char IntABIAlignment; // Defaults to 4 bytes - unsigned char LongABIAlignment; // Defaults to 8 bytes - unsigned char FloatABIAlignment; // Defaults to 4 bytes - unsigned char DoubleABIAlignment; // Defaults to 8 bytes - unsigned char PointerMemSize; // Defaults to 8 bytes - unsigned char PointerABIAlignment; // Defaults to 8 bytes + /// Where the primitive type alignment data is stored. + /// + /// @sa init(). + /// @note Could support multiple size pointer alignments, e.g., 32-bit + /// pointers vs. 64-bit pointers by extending TargetAlignment, but for + /// now, we don't. + TargetAlign Alignments; - // Preferred stack/global type alignments - unsigned char BoolPrefAlignment; // Defaults to BoolABIAlignment - unsigned char BytePrefAlignment; // Defaults to ByteABIAlignment - unsigned char ShortPrefAlignment; // Defaults to ShortABIAlignment - unsigned char IntPrefAlignment; // Defaults to IntABIAlignment - unsigned char LongPrefAlignment; // Defaults to LongABIAlignment - unsigned char FloatPrefAlignment; // Defaults to FloatABIAlignment - unsigned char DoublePrefAlignment; // Defaults to DoubleABIAlignment - unsigned char PointerPrefAlignment; // Defaults to PointerABIAlignment - unsigned char AggMinPrefAlignment; // Defaults to 0 bytes + //! Internal helper method that returns requested alignment for type. + unsigned char getAlignment(const Type *Ty, bool abi_or_pref) const; public: - /// Default ctor - This has to exist, because this is a pass, but it should - /// never be used. + /// Default ctor. + /// + /// @note This has to exist, because this is a pass, but it should never be + /// used. TargetData() { assert(0 && "ERROR: Bad TargetData ctor used. " "Tool did not specify a TargetData to use?"); abort(); } - /// Constructs a TargetData from a string of the following format: - /// "E-p:64:64-d:64-f:32-l:64-i:32-s:16-b:8-B:8" - /// The above string is considered the default, and any values not specified - /// in the string will be assumed to be as above, with the caveat that unspecified - /// values are always assumed to be smaller than the size of a pointer. + /// Constructs a TargetData from a specification string. See init(). TargetData(const std::string &TargetDescription) { init(TargetDescription); } @@ -82,143 +158,36 @@ TargetData(const TargetData &TD) : ImmutablePass(), LittleEndian(TD.isLittleEndian()), - BoolABIAlignment(TD.getBoolABIAlignment()), - ByteABIAlignment(TD.getByteABIAlignment()), - ShortABIAlignment(TD.getShortABIAlignment()), - IntABIAlignment(TD.getIntABIAlignment()), - LongABIAlignment(TD.getLongABIAlignment()), - FloatABIAlignment(TD.getFloatABIAlignment()), - DoubleABIAlignment(TD.getDoubleABIAlignment()), - PointerMemSize(TD.getPointerSize()), - PointerABIAlignment(TD.getPointerABIAlignment()), - BoolPrefAlignment(TD.getBoolPrefAlignment()), - BytePrefAlignment(TD.getBytePrefAlignment()), - ShortPrefAlignment(TD.getShortPrefAlignment()), - IntPrefAlignment(TD.getIntPrefAlignment()), - LongPrefAlignment(TD.getLongPrefAlignment()), - FloatPrefAlignment(TD.getFloatPrefAlignment()), - DoublePrefAlignment(TD.getDoublePrefAlignment()), - PointerPrefAlignment(TD.getPointerPrefAlignment()), - AggMinPrefAlignment(TD.getAggMinPrefAlignment()) { - } + PointerMemSize(TD.PointerMemSize), + PointerABIAlign(TD.PointerABIAlign), + PointerPrefAlign(TD.PointerPrefAlign), + Alignments(TD.Alignments) + { } ~TargetData(); // Not virtual, do not subclass this class - /// Parse a target data layout string and initialize TargetData members. - /// - /// Parse a target data layout string, initializing the various TargetData - /// members along the way. A TargetData specification string looks like - /// "E-p:64:64-d:64-f:32-l:64-i:32-s:16-b:8-B:8" and specifies the - /// target's endianess, the ABI alignments of various data types and - /// the size of pointers. - /// - /// "-" is used as a separator and ":" separates a token from its argument. - /// - /// Alignment is indicated in bits and internally converted to the - /// appropriate number of bytes. - /// - /// The preferred stack/global alignment specifications (":[prefalign]") are - /// optional and default to the ABI alignment. - /// - /// Valid tokens: - /// <br> - /// <em>E</em> specifies big endian architecture (1234) [default]<br> - /// <em>e</em> specifies little endian architecture (4321) <br> - /// <em>p:[ptr size]:[ptr align]</em> specifies pointer size and alignment - /// [default = 64:64] <br> - /// <em>d:[align]:[prefalign]</em> specifies double floating - /// point alignment [default = 64] <br> - /// <em>f:[align]:[prefalign]</em> specifies single floating - /// point alignment [default = 32] <br> - /// <em>l:[align]:[prefalign]:[globalign[</em> specifies long integer - /// alignment [default = 64] <br> - /// <em>i:[align]:[prefalign]</em> specifies integer alignment - /// [default = 32] <br> - /// <em>s:[align]:[prefalign]</em> specifies short integer - /// alignment [default = 16] <br> - /// <em>b:[align]:[prefalign]</em> specifies byte data type - /// alignment [default = 8] <br> - /// <em>B:[align]:[prefalign]</em> specifies boolean data type - /// alignment [default = 8] <br> - /// <em>A:[prefalign]</em> specifies an aggregates' minimum alignment - /// on the stack and when emitted as a global. The default minimum aggregate - /// alignment defaults to 0, which causes the aggregate's "natural" internal - /// alignment calculated by llvm to be preferred. - /// - /// All other token types are silently ignored. + //! Parse a target data layout string and initialize TargetData alignments. void init(const std::string &TargetDescription); - /// Target endianness... bool isLittleEndian() const { return LittleEndian; } bool isBigEndian() const { return !LittleEndian; } - /// Target boolean alignment - unsigned char getBoolABIAlignment() const { return BoolABIAlignment; } - /// Target byte alignment - unsigned char getByteABIAlignment() const { return ByteABIAlignment; } - /// Target short alignment - unsigned char getShortABIAlignment() const { return ShortABIAlignment; } - /// Target integer alignment - unsigned char getIntABIAlignment() const { return IntABIAlignment; } - /// Target long alignment - unsigned char getLongABIAlignment() const { return LongABIAlignment; } - /// Target single precision float alignment - unsigned char getFloatABIAlignment() const { return FloatABIAlignment; } - /// Target double precision float alignment - unsigned char getDoubleABIAlignment() const { return DoubleABIAlignment; } - /// Target pointer alignment - unsigned char getPointerABIAlignment() const { return PointerABIAlignment; } - /// Target pointer size - unsigned char getPointerSize() const { return PointerMemSize; } - /// Target pointer size, in bits - unsigned char getPointerSizeInBits() const { return 8*PointerMemSize; } - - /// Return target's alignment for booleans on stack - unsigned char getBoolPrefAlignment() const { - return BoolPrefAlignment; - } - /// Return target's alignment for integers on stack - unsigned char getBytePrefAlignment() const { - return BytePrefAlignment; - } - /// Return target's alignment for shorts on stack - unsigned char getShortPrefAlignment() const { - return ShortPrefAlignment; - } - /// Return target's alignment for integers on stack - unsigned char getIntPrefAlignment() const { - return IntPrefAlignment; - } - /// Return target's alignment for longs on stack - unsigned char getLongPrefAlignment() const { - return LongPrefAlignment; - } - /// Return target's alignment for single precision floats on stack - unsigned char getFloatPrefAlignment() const { - return FloatPrefAlignment; - } - /// Return target's alignment for double preceision floats on stack - unsigned char getDoublePrefAlignment() const { - return DoublePrefAlignment; - } - /// Return target's alignment for stack-based pointers - unsigned char getPointerPrefAlignment() const { - return PointerPrefAlignment; - } - /// Return target's alignment for stack-based structures - unsigned char getAggMinPrefAlignment() const { - return AggMinPrefAlignment; - } - /// getStringRepresentation - Return the string representation of the /// TargetData. This representation is in the same format accepted by the /// string constructor above. std::string getStringRepresentation() const; + /// Target pointer alignment + unsigned char getPointerABIAlignment() const { return PointerABIAlign; } + /// Return target's alignment for stack-based pointers + unsigned char getPointerPrefAlignment() const { return PointerPrefAlign; } + /// Target pointer size + unsigned char getPointerSize() const { return PointerMemSize; } + /// Target pointer size, in bits + unsigned char getPointerSizeInBits() const { return 8*PointerMemSize; } /// getTypeSize - Return the number of bytes necessary to hold the specified /// type. - /// uint64_t getTypeSize(const Type *Ty) const; /// getTypeSizeInBits - Return the number of bytes necessary to hold the @@ -227,11 +196,11 @@ /// getTypeAlignmentABI - Return the minimum ABI-required alignment for the /// specified type. - unsigned char getTypeAlignmentABI(const Type *Ty) const; + unsigned char getABITypeAlignment(const Type *Ty) const; /// getTypeAlignmentPref - Return the preferred stack/global alignment for /// the specified type. - unsigned char getTypeAlignmentPref(const Type *Ty) const; + unsigned char getPrefTypeAlignment(const Type *Ty) const; /// getPreferredTypeAlignmentShift - Return the preferred alignment for the /// specified type, returned as log2 of the value (a shift amount). Index: tools/llc/llc.cpp =================================================================== --- tools/llc/llc.cpp (.../trunk) (revision 423) +++ tools/llc/llc.cpp (.../branches/llvm-spu) (revision 423) @@ -175,9 +175,11 @@ sys::PrintStackTraceOnErrorSignal(); // Load the module to be compiled... - std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); + std::string errmsg; + std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename, &errmsg)); if (M.get() == 0) { std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; + std::cerr << "why = " << errmsg << "\n"; return 1; } Module &mod = *M.get(); Index: lib/CodeGen/ELFWriter.cpp =================================================================== --- lib/CodeGen/ELFWriter.cpp (.../trunk) (revision 423) +++ lib/CodeGen/ELFWriter.cpp (.../branches/llvm-spu) (revision 423) @@ -241,7 +241,7 @@ } const Type *GVType = (const Type*)GV->getType(); - unsigned Align = TM.getTargetData()->getTypeAlignmentPref(GVType); + unsigned Align = TM.getTargetData()->getPrefTypeAlignment(GVType); unsigned Size = TM.getTargetData()->getTypeSize(GVType); // If this global has a zero initializer, it is part of the .bss or common Index: lib/CodeGen/MachineFunction.cpp =================================================================== --- lib/CodeGen/MachineFunction.cpp (.../trunk) (revision 423) +++ lib/CodeGen/MachineFunction.cpp (.../branches/llvm-spu) (revision 423) @@ -13,6 +13,8 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Type.h" +#include "llvm/DerivedTypes.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/SSARegMap.h" @@ -123,7 +125,7 @@ const TargetData &TD = *TM.getTargetData(); bool IsPic = TM.getRelocationModel() == Reloc::PIC_; unsigned EntrySize = IsPic ? 4 : TD.getPointerSize(); - unsigned Alignment = IsPic ? TD.getIntABIAlignment() + unsigned Alignment = IsPic ? TD.getABITypeAlignment(Type::Int32Ty) : TD.getPointerABIAlignment(); JumpTableInfo = new MachineJumpTableInfo(EntrySize, Alignment); Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (.../trunk) (revision 423) +++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (.../branches/llvm-spu) (revision 423) @@ -244,7 +244,7 @@ const Type *Ty = AI->getAllocatedType(); uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty); unsigned Align = - std::max((unsigned)TLI.getTargetData()->getTypeAlignmentPref(Ty), + std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), AI->getAlignment()); TySize *= CUI->getZExtValue(); // Get total allocated size. @@ -1730,7 +1730,7 @@ const Type *Ty = I.getAllocatedType(); uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty); unsigned Align = - std::max((unsigned)TLI.getTargetData()->getTypeAlignmentPref(Ty), + std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty), I.getAlignment()); SDOperand AllocSize = getValue(I.getArraySize()); Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (.../trunk) (revision 423) +++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (.../branches/llvm-spu) (revision 423) @@ -3042,7 +3042,7 @@ // new ones, as reuse may inhibit scheduling. const Type *Ty = MVT::getTypeForValueType(ExtraVT); unsigned TySize = (unsigned)TLI.getTargetData()->getTypeSize(Ty); - unsigned Align = TLI.getTargetData()->getTypeAlignmentPref(Ty); + unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty); MachineFunction &MF = DAG.getMachineFunction(); int SSFI = MF.getFrameInfo()->CreateStackObject((unsigned)TySize, Align); @@ -3937,7 +3937,7 @@ MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo(); unsigned ByteSize = MVT::getSizeInBits(VT)/8; const Type *Ty = MVT::getTypeForValueType(VT); - unsigned StackAlign = (unsigned)TLI.getTargetData()->getTypeAlignmentPref(Ty); + unsigned StackAlign = (unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty); int FrameIdx = FrameInfo->CreateStackObject(ByteSize, StackAlign); return DAG.getFrameIndex(FrameIdx, TLI.getPointerTy()); } @@ -4247,7 +4247,7 @@ MachineFunction &MF = DAG.getMachineFunction(); const Type *F64Type = MVT::getTypeForValueType(MVT::f64); unsigned StackAlign = - (unsigned)TLI.getTargetData()->getTypeAlignmentPref(F64Type); + (unsigned)TLI.getTargetData()->getPrefTypeAlignment(F64Type); int SSFI = MF.getFrameInfo()->CreateStackObject(8, StackAlign); // get address of 8 byte buffer SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy()); Index: lib/CodeGen/MachOWriter.cpp =================================================================== --- lib/CodeGen/MachOWriter.cpp (.../trunk) (revision 423) +++ lib/CodeGen/MachOWriter.cpp (.../branches/llvm-spu) (revision 423) @@ -318,7 +318,7 @@ unsigned Size = TM.getTargetData()->getTypeSize(Ty); unsigned Align = GV->getAlignment(); if (Align == 0) - Align = TM.getTargetData()->getTypeAlignmentPref(Ty); + Align = TM.getTargetData()->getPrefTypeAlignment(Ty); MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TM); Index: lib/Target/PowerPC/PPCSubtarget.h =================================================================== --- lib/Target/PowerPC/PPCSubtarget.h (.../trunk) (revision 423) +++ lib/Target/PowerPC/PPCSubtarget.h (.../branches/llvm-spu) (revision 423) @@ -104,8 +104,8 @@ /// getTargetDataString - Return the pointer size and type alignment /// properties of this subtarget. const char *getTargetDataString() const { - return isPPC64() ? "E-p:64:64-d:32:64-l:32:64" - : "E-p:32:32-d:32:64-l:32:64"; + return isPPC64() ? "E-p:64:64-f64:32:64-i64:32:64" + : "E-p:32:32-f64:32:64-i64:32:64"; } /// isPPC64 - Return true if we are generating code for 64-bit pointer mode. Index: lib/Target/ARM/ARMTargetMachine.cpp =================================================================== --- lib/Target/ARM/ARMTargetMachine.cpp (.../trunk) (revision 423) +++ lib/Target/ARM/ARMTargetMachine.cpp (.../branches/llvm-spu) (revision 423) @@ -36,11 +36,11 @@ : Subtarget(M, FS), DataLayout(Subtarget.isTargetDarwin() ? (Subtarget.isThumb() ? - std::string("e-p:32:32-d:32:32-l:32:32-s:16:32-b:8:32-B:8:32-A:32") : - std::string("e-p:32:32-d:32:32-l:32:32")) : + std::string("e-p:32:32-f64:32:32-i64:32:32-i16:16:32-i8:8:32-i1:8:32-a:0:32") : + std::string("e-p:32:32-f64:32:32-i64:32:32")) : (Subtarget.isThumb() ? - std::string("e-p:32:32-d:32:64-l:32:64-s:16:32-b:8:32-B:8:32-A:32") : - std::string("e-p:32:32-d:32:64-l:32:64"))), + std::string("e-p:32:32-f64:32:64-i64:32:64-i16:16:32-i8:8:32-i1:8:32-a:0:32") : + std::string("e-p:32:32-f64:32:64-i64:32:64"))), InstrInfo(Subtarget), FrameInfo(Subtarget) {} Index: lib/Target/X86/X86TargetMachine.cpp =================================================================== --- lib/Target/X86/X86TargetMachine.cpp (.../trunk) (revision 423) +++ lib/Target/X86/X86TargetMachine.cpp (.../branches/llvm-spu) (revision 423) @@ -109,8 +109,8 @@ X86TargetMachine::X86TargetMachine(const Module &M, const std::string &FS, bool is64Bit) : Subtarget(M, FS, is64Bit), DataLayout(Subtarget.is64Bit() ? - std::string("e-p:64:64-d:32:64-l:32:64") : - std::string("e-p:32:32-d:32:64-l:32:64")), + std::string("e-p:64:64-f64:32:64-i64:32:64") : + std::string("e-p:32:32-f64:32:64-i64:32:64")), FrameInfo(TargetFrameInfo::StackGrowsDown, Subtarget.getStackAlignment(), Subtarget.is64Bit() ? -8 : -4), InstrInfo(*this), JITInfo(*this), TLInfo(*this) { Index: lib/Target/TargetData.cpp =================================================================== --- lib/Target/TargetData.cpp (.../trunk) (revision 423) +++ lib/Target/TargetData.cpp (.../branches/llvm-spu) (revision 423) @@ -23,6 +23,7 @@ #include "llvm/Support/GetElementPtrTypeIterator.h" #include "llvm/Support/MathExtras.h" #include "llvm/ADT/StringExtras.h" +#include <iostream> #include <algorithm> #include <cstdlib> #include <sstream> @@ -34,12 +35,6 @@ RegisterPass<TargetData> X("targetdata", "Target Data Layout"); } -static inline void getTypeInfoABI(const Type *Ty, const TargetData *TD, - uint64_t &Size, unsigned char &Alignment); - -static inline void getTypeInfoPref(const Type *Ty, const TargetData *TD, - uint64_t &Size, unsigned char &Alignment); - //===----------------------------------------------------------------------===// // Support for StructLayout //===----------------------------------------------------------------------===// @@ -52,11 +47,9 @@ for (StructType::element_iterator TI = ST->element_begin(), TE = ST->element_end(); TI != TE; ++TI) { const Type *Ty = *TI; - unsigned char A; unsigned TyAlign; uint64_t TySize; - getTypeInfoABI(Ty, &TD, TySize, A); - TyAlign = ST->isPacked() ? 1 : A; + TyAlign = (unsigned) TD.getABITypeAlignment(Ty); // Add padding if necessary to make the data element aligned properly... if (StructSize % TyAlign != 0) @@ -94,38 +87,204 @@ } //===----------------------------------------------------------------------===// +// TargetAlignElem, TargetAlign support +//===----------------------------------------------------------------------===// + +TargetAlignElem::TargetAlignElem() : + AlignType(0), + ABIAlign(0), + PrefAlign(0), + TypeBitWidth(0) +{ } + +TargetAlignElem::TargetAlignElem(AlignTypeEnum align_type, + unsigned char abi_align, + unsigned char pref_align, + short bit_width) : + AlignType((unsigned char ) align_type), + ABIAlign(abi_align), + PrefAlign(pref_align), + TypeBitWidth(bit_width) +{ } + +TargetAlignElem::TargetAlignElem(const TargetAlignElem &src) : + AlignType(src.AlignType), + ABIAlign(src.ABIAlign), + PrefAlign(src.PrefAlign), + TypeBitWidth(src.TypeBitWidth) +{ } + +TargetAlignElem & +TargetAlignElem::operator=(const TargetAlignElem &rhs) { + if (this != &rhs) { + AlignType = rhs.AlignType; + ABIAlign = rhs.ABIAlign; + PrefAlign = rhs.PrefAlign; + TypeBitWidth = rhs.TypeBitWidth; + } + + return *this; +} + +bool +TargetAlignElem::operator<(const TargetAlignElem &rhs) const +{ + return ((AlignType < rhs.AlignType) + || (AlignType == rhs.AlignType && TypeBitWidth < rhs.TypeBitWidth)); +} + +bool +TargetAlignElem::operator==(const TargetAlignElem &rhs) const +{ + return (AlignType == rhs.AlignType + && ABIAlign == rhs.ABIAlign + && PrefAlign == rhs.PrefAlign + && TypeBitWidth == rhs.TypeBitWidth); +} + +std::ostream & +TargetAlignElem::dump(std::ostream &os) const +{ + return os << AlignType + << TypeBitWidth + << ":" << (int) (ABIAlign * 8) + << ":" << (int) (PrefAlign * 8); +} + +std::ostream & +llvm::operator<<(std::ostream &os, const TargetAlignElem &elem) +{ + return elem.dump(os); +} + +const TargetAlignElem TargetAlign::InvalidAlignmentElem; + +TargetAlign::TargetAlign() +{ } + +TargetAlign::TargetAlign(const TargetAlign &src) : + SmallVector<TargetAlignElem, 16>(src) +{ } + +TargetAlign & +TargetAlign::operator=(const TargetAlign &rhs) { + if (this != &rhs) { + SmallVector<TargetAlignElem, 16>::operator=(rhs); + } + + return *this; +} + +void +TargetAlign::set(AlignTypeEnum align_type, short bit_width, + unsigned char abi_align, unsigned char pref_align) +{ + TargetAlignElem elt(align_type, abi_align, pref_align, bit_width); + std::pair<iterator, iterator> ins_result = std::equal_range(begin(), end(), elt); + iterator I = ins_result.first; +#if 0 + // Keep around for debugging... + iterator E = ins_result.second; +#endif + + if (I->AlignType == align_type && I->TypeBitWidth == bit_width) { + // Update the abi, preferred alignments. + I->ABIAlign = abi_align; + I->PrefAlign = pref_align; + } else + insert(I, elt); + +#if 0 + // Keep around for debugging and testing... + cerr << "I = " << (I - begin()) << ", E = " << (E - begin()) << "\n"; + std::copy(begin(), end(), std::ostream_iterator<TargetAlignElem>(*cerr, "\n")); + cerr << "=====\n"; +#endif +} + +const TargetAlignElem & +TargetAlign::get(AlignTypeEnum align_type, short bit_width) const +{ + TargetAlignElem elt(align_type, 0, 0, bit_width); + std::pair<const_iterator, const_iterator> find_result = std::equal_range(begin(), end(), elt); + const_iterator I = find_result.first; + + // Note: This may not be reasonable if variable-width integer sizes are passed, + // at which point, more sophisticated searching will need to be done. + return *I; +} + +//===----------------------------------------------------------------------===// // TargetData Class Implementation //===----------------------------------------------------------------------===// +/*! + A TargetDescription string consists of a sequence of hyphen-delimited + specifiers for target endianness, pointer size and alignments, and various + primitive type sizes and alignments. A typical string looks something like: + <br> + "E-p:32:32:32-i1:8:8-i8:8:8-i32:32:32-i64:32:64-f32:32:32-f64:32:64" + <br> + (note: this string is not fully specified and is only an example.) + \p + Alignments come in two flavors: ABI and preferred. ABI alignment (abi_align, + below) dictates how a type will be aligned within an aggregate and when used + as an argument. Preferred alignment (pref_align, below) determines a type's + alignment when emitted as a global. + \p + Specifier string details: + <br> + <i>[E|e]</i>: Endianness. "E" specifies a big-endian target data model, "e" + specifies a little-endian target data model. + <br> + <i>p:<size>:<abi_align>:<pref_align></i>: Pointer size, ABI and preferred + alignment. + <br> + <i><type><size>:<abi_align>:<pref_align></i>: Numeric type alignment. Type is + one of <i>i|f|v|a</i>, corresponding to integer, floating point, vector (aka + packed) or aggregate. Size indicates the size, e.g., 32 or 64 bits. + \p + The default string, fully specified is: + <br> + "E-p:64:64:64-a0:0:0-f32:32:32-f64:0:64" + "-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:0:64" + "-v64:64:64-v128:128:128" + <br> + Note that in the case of aggregates, 0 is the default ABI and preferred + alignment. This is a special case, where the aggregate's computed worst-case + alignment will be used. + */ void TargetData::init(const std::string &TargetDescription) { std::string temp = TargetDescription; LittleEndian = false; PointerMemSize = 8; - PointerABIAlignment = 8; - DoubleABIAlignment = 0; - FloatABIAlignment = 4; - LongABIAlignment = 0; - IntABIAlignment = 4; - ShortABIAlignment = 2; - ByteABIAlignment = 1; - BoolABIAlignment = 1; - BoolPrefAlignment = BoolABIAlignment; - BytePrefAlignment = ByteABIAlignment; - ShortPrefAlignment = ShortABIAlignment; - IntPrefAlignment = IntABIAlignment; - LongPrefAlignment = 8; - FloatPrefAlignment = FloatABIAlignment; - DoublePrefAlignment = 8; - PointerPrefAlignment = PointerABIAlignment; - AggMinPrefAlignment = 0; + PointerABIAlign = 8; + PointerPrefAlign = PointerABIAlign; + + // Default alignments + Alignments.set(INTEGER_ALIGN, 1, 1, 1); // Bool + Alignments.set(INTEGER_ALIGN, 8, 1, 1); // Byte + Alignments.set(INTEGER_ALIGN, 16, 2, 2); // short + Alignments.set(INTEGER_ALIGN, 32, 4, 4); // int + Alignments.set(INTEGER_ALIGN, 64, 0, 8); // long + Alignments.set(FLOAT_ALIGN, 32, 4, 4); // float + Alignments.set(FLOAT_ALIGN, 64, 0, 8); // double + Alignments.set(PACKED_ALIGN, 64, 8, 8); // v2i32 + Alignments.set(PACKED_ALIGN, 128, 16, 16); // v16i8, v8i16, v4i32, ... + Alignments.set(AGGREGATE_ALIGN, 0, 0, 0); // struct, union, class, ... while (!temp.empty()) { std::string token = getToken(temp, "-"); - char signal = getToken(token, ":")[0]; - - switch(signal) { + std::string arg0 = getToken(token, ":"); + const char *p = arg0.c_str(); + AlignTypeEnum align_type; + short size; + unsigned char abi_align; + unsigned char pref_align; + + switch(*p) { case 'E': LittleEndian = false; break; @@ -134,56 +293,26 @@ break; case 'p': PointerMemSize = atoi(getToken(token,":").c_str()) / 8; - PointerABIAlignment = atoi(getToken(token,":").c_str()) / 8; - PointerPrefAlignment = atoi(getToken(token,":").c_str()) / 8; - if (PointerPrefAlignment == 0) - PointerPrefAlignment = PointerABIAlignment; + PointerABIAlign = atoi(getToken(token,":").c_str()) / 8; + PointerPrefAlign = atoi(getToken(token,":").c_str()) / 8; + if (PointerPrefAlign == 0) + PointerPrefAlign = PointerABIAlign; break; - case 'd': - DoubleABIAlignment = atoi(getToken(token,":").c_str()) / 8; - DoublePrefAlignment = atoi(getToken(token,":").c_str()) / 8; - if (DoublePrefAlignment == 0) - DoublePrefAlignment = DoubleABIAlignment; - break; + case 'i': + case 'v': case 'f': - FloatABIAlignment = atoi(getToken(token, ":").c_str()) / 8; - FloatPrefAlignment = atoi(getToken(token,":").c_str()) / 8; - if (FloatPrefAlignment == 0) - FloatPrefAlignment = FloatABIAlignment; + case 'a': { + align_type = (*p == 'i' ? INTEGER_ALIGN : + (*p == 'f' ? FLOAT_ALIGN : + (*p == 'v' ? PACKED_ALIGN : AGGREGATE_ALIGN))); + size = (short) atoi(++p); + abi_align = atoi(getToken(token, ":").c_str()) / 8; + pref_align = atoi(getToken(token, ":").c_str()) / 8; + if (pref_align == 0) + pref_align = abi_align; + Alignments.set(align_type, size, abi_align, pref_align); break; - case 'l': - LongABIAlignment = atoi(getToken(token, ":").c_str()) / 8; - LongPrefAlignment = atoi(getToken(token,":").c_str()) / 8; - if (LongPrefAlignment == 0) - LongPrefAlignment = LongABIAlignment; - break; - case 'i': - IntABIAlignment = atoi(getToken(token, ":").c_str()) / 8; - IntPrefAlignment = atoi(getToken(token,":").c_str()) / 8; - if (IntPrefAlignment == 0) - IntPrefAlignment = IntABIAlignment; - break; - case 's': - ShortABIAlignment = atoi(getToken(token, ":").c_str()) / 8; - ShortPrefAlignment = atoi(getToken(token,":").c_str()) / 8; - if (ShortPrefAlignment == 0) - ShortPrefAlignment = ShortABIAlignment; - break; - case 'b': - ByteABIAlignment = atoi(getToken(token, ":").c_str()) / 8; - BytePrefAlignment = atoi(getToken(token,":").c_str()) / 8; - if (BytePrefAlignment == 0) - BytePrefAlignment = ByteABIAlignment; - break; - case 'B': - BoolABIAlignment = atoi(getToken(token, ":").c_str()) / 8; - BoolPrefAlignment = atoi(getToken(token,":").c_str()) / 8; - if (BoolPrefAlignment == 0) - BoolPrefAlignment = BoolABIAlignment; - break; - case 'A': - AggMinPrefAlignment = atoi(getToken(token,":").c_str()) / 8; - break; + } default: break; } @@ -191,10 +320,14 @@ // Unless explicitly specified, the alignments for longs and doubles is // capped by pointer size. - if (LongABIAlignment == 0) - LongABIAlignment = LongPrefAlignment = PointerMemSize; - if (DoubleABIAlignment == 0) - DoubleABIAlignment = DoublePrefAlignment = PointerMemSize; + // FIXME: Is this still necessary? + const TargetAlignElem &long_align = Alignments.get(INTEGER_ALIGN, 64); + if (long_align.ABIAlign == 0) + Alignments.set(INTEGER_ALIGN, 64, PointerMemSize, PointerMemSize); + + const TargetAlignElem &double_align = Alignments.get(FLOAT_ALIGN, 64); + if (double_align.ABIAlign == 0) + Alignments.set(FLOAT_ALIGN, 64, PointerMemSize, PointerMemSize); } TargetData::TargetData(const Module *M) { @@ -223,31 +356,42 @@ } } +struct hyphen_delimited : + public std::iterator<std::output_iterator_tag, void, void, void, void> +{ + std::ostream &o; + + hyphen_delimited(std::ostream &os) : + o(os) + { } + + hyphen_delimited &operator=(const TargetAlignElem &elem) + { + o << "-" << elem; + return *this; + } + + hyphen_delimited &operator*() + { + return *this; + } + + hyphen_delimited &operator++() + { + return *this; + } +}; + std::string TargetData::getStringRepresentation() const { std::stringstream repr; - + if (LittleEndian) repr << "e"; else repr << "E"; - - repr << "-p:" << (PointerMemSize * 8) << ":" << (PointerABIAlignment * 8); - repr << "-d:" << (DoubleABIAlignment * 8) << ":" - << (DoublePrefAlignment * 8); - repr << "-f:" << (FloatABIAlignment * 8) << ":" - << (FloatPrefAlignment * 8); - repr << "-l:" << (LongABIAlignment * 8) << ":" - << (LongPrefAlignment * 8); - repr << "-i:" << (IntABIAlignment * 8) << ":" - << (IntPrefAlignment * 8); - repr << "-s:" << (ShortABIAlignment * 8) << ":" - << (ShortPrefAlignment * 8); - repr << "-b:" << (ByteABIAlignment * 8) << ":" - << (BytePrefAlignment * 8); - repr << "-B:" << (BoolABIAlignment * 8) << ":" - << (BoolPrefAlignment * 8); - repr << "-A:" << (AggMinPrefAlignment * 8); - + repr << "-p:" << (PointerMemSize * 8) << ":" << (PointerABIAlign * 8) + << ":" << (PointerPrefAlign * 8); + std::copy(Alignments.begin(), Alignments.end(), hyphen_delimited(repr)); return repr.str(); } @@ -279,161 +423,146 @@ Layouts->erase(I); } - - -static inline void getTypeInfoABI(const Type *Ty, const TargetData *TD, - uint64_t &Size, unsigned char &Alignment) { +uint64_t TargetData::getTypeSize(const Type *Ty) const { assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"); switch (Ty->getTypeID()) { - case Type::IntegerTyID: { - unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth(); - if (BitWidth <= 8) { - Size = 1; Alignment = TD->getByteABIAlignment(); - } else if (BitWidth <= 16) { - Size = 2; Alignment = TD->getShortABIAlignment(); - } else if (BitWidth <= 32) { - Size = 4; Alignment = TD->getIntABIAlignment(); - } else if (BitWidth <= 64) { - Size = 8; Alignment = TD->getLongABIAlignment(); - } else - assert(0 && "Integer types > 64 bits not supported."); - return; - } - case Type::VoidTyID: Size = 1; Alignment = TD->getByteABIAlignment(); return; - case Type::FloatTyID: Size = 4; Alignment = TD->getFloatABIAlignment(); return; - case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleABIAlignment(); return; case Type::LabelTyID: case Type::PointerTyID: - Size = TD->getPointerSize(); Alignment = TD->getPointerABIAlignment(); - return; + return getPointerSize(); case Type::ArrayTyID: { const ArrayType *ATy = cast<ArrayType>(Ty); - getTypeInfoABI(ATy->getElementType(), TD, Size, Alignment); + uint64_t Size; + unsigned char Alignment; + Size = getTypeSize(ATy->getElementType()); + Alignment = getABITypeAlignment(ATy->getElementType()); unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment; - Size = AlignedSize*ATy->getNumElements(); - return; + return AlignedSize*ATy->getNumElements(); } - case Type::PackedTyID: { - const PackedType *PTy = cast<PackedType>(Ty); - getTypeInfoABI(PTy->getElementType(), TD, Size, Alignment); - unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment; - Size = AlignedSize*PTy->getNumElements(); - // FIXME: The alignments of specific packed types are target dependent. - // For now, just set it to be equal to Size. - Alignment = Size; - return; - } case Type::StructTyID: { // Get the layout annotation... which is lazily created on demand. - const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty)); - Size = Layout->StructSize; Alignment = Layout->StructAlignment; - return; + const StructLayout *Layout = getStructLayout(cast<StructType>(Ty)); + return Layout->StructSize; } - - default: - assert(0 && "Bad type for getTypeInfo!!!"); - return; - } -} - -static inline void getTypeInfoPref(const Type *Ty, const TargetData *TD, - uint64_t &Size, unsigned char &Alignment) { - assert(Ty->isSized() && "Cannot getTypeInfoPref() on a type that is unsized!"); - switch (Ty->getTypeID()) { case Type::IntegerTyID: { unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth(); if (BitWidth <= 8) { - Size = 1; Alignment = TD->getBytePrefAlignment(); + return 1; } else if (BitWidth <= 16) { - Size = 2; Alignment = TD->getShortPrefAlignment(); + return 2; } else if (BitWidth <= 32) { - Size = 4; Alignment = TD->getIntPrefAlignment(); + return 4; } else if (BitWidth <= 64) { - Size = 8; Alignment = TD->getLongPrefAlignment(); + return 8; } else assert(0 && "Integer types > 64 bits not supported."); - return; + break; } case Type::VoidTyID: - Size = 1; Alignment = TD->getBytePrefAlignment(); - return; + return 1; case Type::FloatTyID: - Size = 4; Alignment = TD->getFloatPrefAlignment(); - return; + return 4; case Type::DoubleTyID: - Size = 8; Alignment = TD->getDoublePrefAlignment(); - return; - case Type::LabelTyID: - case Type::PointerTyID: - Size = TD->getPointerSize(); Alignment = TD->getPointerPrefAlignment(); - return; - case Type::ArrayTyID: { - const ArrayType *ATy = cast<ArrayType>(Ty); - getTypeInfoPref(ATy->getElementType(), TD, Size, Alignment); - unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment; - Size = AlignedSize*ATy->getNumElements(); - return; - } + return 8; case Type::PackedTyID: { const PackedType *PTy = cast<PackedType>(Ty); - getTypeInfoPref(PTy->getElementType(), TD, Size, Alignment); - unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment; - Size = AlignedSize*PTy->getNumElements(); - // FIXME: The alignments of specific packed types are target dependent. - // For now, just set it to be equal to Size. - Alignment = Size; - return; + return PTy->getBitWidth() / 8; } - case Type::StructTyID: { - // Get the layout annotation... which is lazily created on demand; - // enforce minimum aggregate alignment. - const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty)); - Size = Layout->StructSize; - Alignment = std::max(Layout->StructAlignment, - (const unsigned int) TD->getAggMinPrefAlignment()); - return; - } - default: - assert(0 && "Bad type for getTypeInfoPref!!!"); - return; + assert(0 && "TargetData::getTypeSize(): Unsupported type"); + break; } + return 0; } - -uint64_t TargetData::getTypeSize(const Type *Ty) const { - uint64_t Size; - unsigned char Align; - getTypeInfoABI(Ty, this, Size, Align); - return Size; -} - uint64_t TargetData::getTypeSizeInBits(const Type *Ty) const { if (Ty->isInteger()) return cast<IntegerType>(Ty)->getBitWidth(); + else + return getTypeSize(Ty) * 8; +} - uint64_t Size; - unsigned char Align; - getTypeInfoABI(Ty, this, Size, Align); - return Size * 8; + +/*! + \param abi_or_pref Flag that determines which alignment is returned. true + returns the ABI alignment, false returns the preferred alignment. + \param Ty The underlying type for which alignment is determined. + + Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref + == false) for the requested type \a Ty. + */ +unsigned char TargetData::getAlignment(const Type *Ty, bool abi_or_pref) const +{ + int AlignType = -1; + + assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!"); + switch (Ty->getTypeID()) { + /* Early escape for the non-numeric types */ + case Type::LabelTyID: + case Type::PointerTyID: + return (abi_or_pref + ? getPointerABIAlignment() + : getPointerPrefAlignment()); + case Type::ArrayTyID: { + const ArrayType *ATy = cast<ArrayType>(Ty); + return (abi_or_pref + ? getABITypeAlignment(ATy->getElementType()) + : getPrefTypeAlignment(ATy->getElementType())); + } + case Type::StructTyID: { + // Get the layout annotation... which is lazily created on demand. + const StructLayout *Layout = getStructLayout(cast<StructType>(Ty)); + const TargetAlignElem &elem = Alignments.get(AGGREGATE_ALIGN, 0); + assert(Alignments.valid(elem) + && "Aggregate alignment return invalid in getAlignment"); + if (abi_or_pref) { + return (elem.ABIAlign < Layout->StructAlignment + ? Layout->StructAlignment + : elem.ABIAlign); + } else { + return (elem.PrefAlign < Layout->StructAlignment + ? Layout->StructAlignment + : elem.PrefAlign); + } + } + case Type::IntegerTyID: + case Type::VoidTyID: + AlignType = INTEGER_ALIGN; + break; + case Type::FloatTyID: + case Type::DoubleTyID: + AlignType = FLOAT_ALIGN; + break; + case Type::PackedTyID: + AlignType = PACKED_ALIGN; + break; + default: + assert(0 && "Bad type for getAlignment!!!"); + break; + } + + const TargetAlignElem &elem = Alignments.get((AlignTypeEnum) AlignType, + getTypeSize(Ty)); + if (Alignments.valid(elem)) + return (abi_or_pref ? elem.ABIAlign : elem.PrefAlign); + else { + cerr << "TargetData::getAlignment: align type " << AlignType + << " size " << getTypeSize(Ty) << " not found in Alignments.\n"; + abort(); + /*NOTREACHED*/ + return 0; + } } -unsigned char TargetData::getTypeAlignmentABI(const Type *Ty) const { - uint64_t Size; - unsigned char Align; - getTypeInfoABI(Ty, this, Size, Align); - return Align; +unsigned char TargetData::getABITypeAlignment(const Type *Ty) const { + return getAlignment(Ty, true); } -unsigned char TargetData::getTypeAlignmentPref(const Type *Ty) const { - uint64_t Size; - unsigned char Align; - getTypeInfoPref(Ty, this, Size, Align); - return Align; +unsigned char TargetData::getPrefTypeAlignment(const Type *Ty) const { + return getAlignment(Ty, false); } unsigned char TargetData::getPreferredTypeAlignmentShift(const Type *Ty) const { - unsigned Align = getTypeAlignmentPref(Ty); + unsigned Align = (unsigned) getPrefTypeAlignment(Ty); assert(!(Align & (Align-1)) && "Alignment is not a power of two!"); return Log2_32(Align); } @@ -504,4 +633,3 @@ } return Alignment; } - Index: lib/Target/Sparc/SparcAsmPrinter.cpp =================================================================== --- lib/Target/Sparc/SparcAsmPrinter.cpp (.../trunk) (revision 423) +++ lib/Target/Sparc/SparcAsmPrinter.cpp (.../branches/llvm-spu) (revision 423) @@ -229,7 +229,7 @@ std::string name = Mang->getValueName(I); Constant *C = I->getInitializer(); unsigned Size = TD->getTypeSize(C->getType()); - unsigned Align = TD->getTypeAlignmentPref(C->getType()); + unsigned Align = TD->getPrefTypeAlignment(C->getType()); if (C->isNullValue() && (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || Index: lib/ExecutionEngine/JIT/JIT.cpp =================================================================== --- lib/ExecutionEngine/JIT/JIT.cpp (.../trunk) (revision 423) +++ lib/ExecutionEngine/JIT/JIT.cpp (.../branches/llvm-spu) (revision 423) @@ -338,7 +338,7 @@ // compilation. const Type *GlobalType = GV->getType()->getElementType(); size_t S = getTargetData()->getTypeSize(GlobalType); - size_t A = getTargetData()->getTypeAlignmentPref(GlobalType); + size_t A = getTargetData()->getPrefTypeAlignment(GlobalType); if (A <= 8) { Ptr = malloc(S); } else { Index: lib/Transforms/Scalar/InstructionCombining.cpp =================================================================== --- lib/Transforms/Scalar/InstructionCombining.cpp (.../trunk) (revision 423) +++ lib/Transforms/Scalar/InstructionCombining.cpp (.../branches/llvm-spu) (revision 423) @@ -365,7 +365,6 @@ /// This function is a wrapper around CastInst::isEliminableCastPair. It /// simply extracts arguments and returns what that function returns. -/// @Determine if it is valid to eliminate a Convert pair static Instruction::CastOps isEliminableCastPair( const CastInst *CI, ///< The first cast instruction @@ -5793,8 +5792,8 @@ const Type *CastElTy = PTy->getElementType(); if (!AllocElTy->isSized() || !CastElTy->isSized()) return 0; - unsigned AllocElTyAlign = TD->getTypeAlignmentABI(AllocElTy); - unsigned CastElTyAlign = TD->getTypeAlignmentABI(CastElTy); + unsigned AllocElTyAlign = TD->getABITypeAlignment(AllocElTy); + unsigned CastElTyAlign = TD->getABITypeAlignment(CastElTy); if (CastElTyAlign < AllocElTyAlign) return 0; // If the allocation has multiple uses, only promote it if we are strictly @@ -6886,22 +6885,22 @@ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) { unsigned Align = GV->getAlignment(); if (Align == 0 && TD) - Align = TD->getTypeAlignmentPref(GV->getType()->getElementType()); + Align = TD->getPrefTypeAlignment(GV->getType()->getElementType()); return Align; } else if (AllocationInst *AI = dyn_cast<AllocationInst>(V)) { unsigned Align = AI->getAlignment(); if (Align == 0 && TD) { if (isa<AllocaInst>(AI)) - Align = TD->getTypeAlignmentPref(AI->getType()->getElementType()); + Align = TD->getPrefTypeAlignment(AI->getType()->getElementType()); else if (isa<MallocInst>(AI)) { // Malloc returns maximally aligned memory. - Align = TD->getTypeAlignmentABI(AI->getType()->getElementType()); + Align = TD->getABITypeAlignment(AI->getType()->getElementType()); Align = std::max(Align, - (unsigned)TD->getTypeAlignmentABI(Type::DoubleTy)); + (unsigned)TD->getABITypeAlignment(Type::DoubleTy)); Align = std::max(Align, - (unsigned)TD->getTypeAlignmentABI(Type::Int64Ty)); + (unsigned)TD->getABITypeAlignment(Type::Int64Ty)); } } return Align; @@ -6937,11 +6936,11 @@ const Type *BasePtrTy = GEPI->getOperand(0)->getType(); const PointerType *PtrTy = cast<PointerType>(BasePtrTy); - if (TD->getTypeAlignmentABI(PtrTy->getElementType()) + if (TD->getABITypeAlignment(PtrTy->getElementType()) <= BaseAlignment) { const Type *GEPTy = GEPI->getType(); const PointerType *GEPPtrTy = cast<PointerType>(GEPTy); - return TD->getTypeAlignmentABI(GEPPtrTy->getElementType()); + return TD->getABITypeAlignment(GEPPtrTy->getElementType()); } return 0; } @@ -8532,8 +8531,10 @@ return false; } -/// getShuffleMask - Read and decode a shufflevector mask. It turns undef -/// elements into values that are larger than the #elts in the input. +/// Read and decode a shufflevector mask. +/// +/// It turns undef elements into values that are larger than the number of +/// elements in the input. static std::vector<unsigned> getShuffleMask(const ShuffleVectorInst *SVI) { unsigned NElts = SVI->getType()->getNumElements(); if (isa<ConstantAggregateZero>(SVI->getOperand(2)))
diff -rN -u old-llvm-cfrontend/gcc/llvm-backend.cpp new-llvm-cfrontend/gcc/llvm-backend.cpp --- old-llvm-cfrontend/gcc/llvm-backend.cpp 2007-02-02 18:59:18.000000000 -0800 +++ new-llvm-cfrontend/gcc/llvm-backend.cpp 2007-02-02 19:00:31.000000000 -0800 @@ -555,7 +555,7 @@ // Set the alignment for the global. if (DECL_ALIGN_UNIT(decl) && - getTargetData().getTypeAlignmentABI(GV->getType()->getElementType()) != + getTargetData().getPrefTypeAlignment(GV->getType()->getElementType()) != DECL_ALIGN_UNIT(decl)) GV->setAlignment(DECL_ALIGN_UNIT(decl)); diff -rN -u old-llvm-cfrontend/gcc/llvm-convert.cpp new-llvm-cfrontend/gcc/llvm-convert.cpp --- old-llvm-cfrontend/gcc/llvm-convert.cpp 2007-02-02 19:00:05.000000000 -0800 +++ new-llvm-cfrontend/gcc/llvm-convert.cpp 2007-02-02 19:01:25.000000000 -0800 @@ -4227,7 +4227,7 @@ // In this case, we know that the alignment of the field is less than // the size of the field. To get the pointer close enough, add some // number of alignment units to the pointer. - unsigned ByteAlignment = TD.getTypeAlignmentABI(FieldTy); + unsigned ByteAlignment = TD.getABITypeAlignment(FieldTy); assert(ByteAlignment*8 <= LLVMValueBitSize && "Unknown overlap case!"); unsigned NumAlignmentUnits = BitStart/(ByteAlignment*8); assert(NumAlignmentUnits && "Not adjusting pointer?"); diff -rN -u old-llvm-cfrontend/gcc/llvm-types.cpp new-llvm-cfrontend/gcc/llvm-types.cpp --- old-llvm-cfrontend/gcc/llvm-types.cpp 2007-02-02 18:59:20.000000000 -0800 +++ new-llvm-cfrontend/gcc/llvm-types.cpp 2007-02-02 19:00:32.000000000 -0800 @@ -677,7 +677,7 @@ /// getTypeAlignment - Return the alignment of the specified type in bytes. /// unsigned getTypeAlignment(const Type *Ty) const { - return TD.getTypeAlignmentABI(Ty); + return TD.getABITypeAlignment(Ty); } /// getTypeSize - Return the size of the specified type in bytes. @@ -1153,7 +1153,7 @@ const Type *TheTy = ConvertType(TREE_TYPE(Field)); unsigned Size = TD.getTypeSize(TheTy); - unsigned Align = TD.getTypeAlignmentABI(TheTy); + unsigned Align = TD.getABITypeAlignment(TheTy); if (UnionTy == 0 || Size>MaxSize || (Size == MaxSize && Align > MaxAlign)) { UnionTy = TheTy; MaxSize = Size;
_______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits