Generalize TargetData strings, to support more interesting forms of data.
authorChris Lattner <sabre@nondot.org>
Wed, 14 Feb 2007 05:52:17 +0000 (05:52 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 14 Feb 2007 05:52:17 +0000 (05:52 +0000)
Patch by Scott Michel.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34266 91177308-0d34-0410-b5e6-96231b3b80d8

13 files changed:
include/llvm/Target/TargetData.h
lib/CodeGen/ELFWriter.cpp
lib/CodeGen/MachOWriter.cpp
lib/CodeGen/MachineFunction.cpp
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/ExecutionEngine/JIT/JIT.cpp
lib/Target/ARM/ARMTargetMachine.cpp
lib/Target/PowerPC/PPCSubtarget.h
lib/Target/Sparc/SparcAsmPrinter.cpp
lib/Target/TargetData.cpp
lib/Target/X86/X86TargetMachine.cpp
lib/Transforms/Scalar/InstructionCombining.cpp

index ed9d86e9353ee383c4a80b7031ca36a29efe9da2..4f9d7c9f482dfdfa18b334f0ff00559147920a34 100644 (file)
@@ -22,6 +22,8 @@
 
 #include "llvm/Pass.h"
 #include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/SmallVector.h"
+#include <string>
 
 namespace llvm {
 
@@ -31,45 +33,96 @@ class StructType;
 class StructLayout;
 class GlobalVariable;
 
-class TargetData : public ImmutablePass {
-  bool          LittleEndian;          // Defaults to false
+/// 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;      //< Pref. alignment for this type/bitw
+  short               TypeBitWidth;   //< Type bit width
+
+  /// Initializer
+  static TargetAlignElem get(AlignTypeEnum align_type, unsigned char abi_align,
+                             unsigned char pref_align, short bit_width);
+  /// 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;
+};
 
-  // 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
+//! TargetAlignElem output stream inserter
+/*!
+  @sa TargetAlignElem::dump()
+ */
+std::ostream &operator<<(std::ostream &os, const TargetAlignElem &elem);
 
-  // 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
+class TargetData : public ImmutablePass {
+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
+
+  //! 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.
+   */
+  SmallVector<TargetAlignElem, 16> Alignments;
+  //! Alignment iterator shorthand
+  typedef SmallVector<TargetAlignElem, 16>::iterator align_iterator;
+  //! Constant alignment iterator shorthand
+  typedef SmallVector<TargetAlignElem, 16>::const_iterator align_const_iterator;
+  //! 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;
+
+  //! Set/initialize target alignments
+  void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
+                    unsigned char pref_align, short bit_width);
+  //! Get TargetAlignElem from alignment type and bit width
+  const TargetAlignElem &getAlignment(AlignTypeEnum, short) const;
+  //! Internal helper method that returns requested alignment for type.
+  unsigned char getAlignment(const Type *Ty, bool abi_or_pref) const;
+
+  /// Valid alignment predicate.
+  ///
+  /// Predicate that tests a TargetAlignElem reference returned by get() against
+  /// InvalidAlignmentElem.
+  inline bool validAlignment(const TargetAlignElem &align) const {
+    return (&align != &InvalidAlignmentElem);
+  }
 
 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);
   }
@@ -80,143 +133,36 @@ public:
   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
@@ -225,11 +171,11 @@ public:
 
   /// 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 5fd3dcc1d6cb354e22dceafaf3810e075e2aeecd..ffc0a929f318d67ef2ac7dea84a44d2719c918be 100644 (file)
@@ -255,7 +255,7 @@ void ELFWriter::EmitGlobal(GlobalVariable *GV) {
   }
 
   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 fe9d997ec51af5c1e9b62ef302c42e0433d6e0c3..0b7dfab80f3d1be82f1a396bdf466c2ca4277bbc 100644 (file)
@@ -147,7 +147,7 @@ void MachOCodeEmitter::startFunction(MachineFunction &MF) {
 
   // Align the output buffer to the appropriate alignment, power of 2.
   unsigned FnAlign = F->getAlignment();
-  unsigned TDAlign = TD->getTypeAlignmentPref(F->getType());
+  unsigned TDAlign = TD->getPrefTypeAlignment(F->getType());
   unsigned Align = Log2_32(std::max(FnAlign, TDAlign));
   assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
 
@@ -332,7 +332,7 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
   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 0cba1567e184697ae60c5dbd57aaf1ef952c68a0..5ae73ca40a017598267cd3c362fd2d6dba05e4f6 100644 (file)
@@ -13,6 +13,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/DerivedTypes.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineInstr.h"
 #include "llvm/CodeGen/SSARegMap.h"
@@ -123,7 +124,7 @@ MachineFunction::MachineFunction(const Function *F,
   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 7b148f1158ff9844249e6048b7d50398ffe91083..0bd40c29343cc69847ce4701e046482d6de9ef90 100644 (file)
@@ -3056,7 +3056,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         // 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);
@@ -3979,7 +3979,7 @@ SDOperand SelectionDAGLegalize::CreateStackTemporary(MVT::ValueType VT) {
   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());
 }
@@ -4289,7 +4289,7 @@ SDOperand SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
     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 e2bda6d4c41f79000d98127446a0d3fae6cf3c6a..e72d88c73401c5780712f0120374dfc5a118cb70 100644 (file)
@@ -244,7 +244,7 @@ FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli,
         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.
@@ -1733,7 +1733,7 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) {
   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());
@@ -2934,7 +2934,7 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
     bool isInReg = FTy->paramHasAttr(j, FunctionType::InRegAttribute);
     bool isSRet  = FTy->paramHasAttr(j, FunctionType::StructRetAttribute);
     unsigned OriginalAlignment =
-      getTargetData()->getTypeAlignmentABI(I->getType());
+      getTargetData()->getABITypeAlignment(I->getType());
     // Flags[31:27] -> OriginalAlignment
     // Flags[2] -> isSRet
     // Flags[1] -> isInReg
@@ -3120,7 +3120,7 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
     bool isInReg = Args[i].isInReg;
     bool isSRet  = Args[i].isSRet;
     unsigned OriginalAlignment =
-      getTargetData()->getTypeAlignmentABI(Args[i].Ty);
+      getTargetData()->getABITypeAlignment(Args[i].Ty);
     // Flags[31:27] -> OriginalAlignment
     // Flags[2] -> isSRet
     // Flags[1] -> isInReg
index ca3dbb96a7b2959491a4d7c4985bd08e1a0353bc..070947bc1da652264e349eb187a58f45ac3ac6c6 100644 (file)
@@ -338,7 +338,7 @@ void *JIT::getOrEmitGlobalVariable(const GlobalVariable *GV) {
     // 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 19d917c31dbbc7a78793d59f93f0e060542b04bc..2fa701608582a9f3a9a481e5e354658dc02837e4 100644 (file)
@@ -37,12 +37,14 @@ ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS)
     DataLayout(Subtarget.isAPCS_ABI() ?
                // APCS ABI
           (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")) :
                // AAPCS ABI
           (Subtarget.isThumb() ?
-           std::string("e-p:32:32-d:64:64-l:64:64-s:16:32-b:8:32-B:8:32-A:32") :
-           std::string("e-p:32:32-d:64:64-l:64:64"))),
+           std::string("e-p:32:32-f64:64:64-i64:64:64-"
+                       "i16:16:32-i8:8:32-i1:8:32-a:0:32") :
+           std::string("e-p:32:32-f64:64:64-i64:64:64"))),
     InstrInfo(Subtarget),
     FrameInfo(Subtarget) {}
 
index d8c04871f56529bee1ebfb667dfbf67a0ce5f76f..7bc2b803b5528a7e667c7c2d2635890c048b8ac3 100644 (file)
@@ -104,8 +104,8 @@ public:
   /// 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 d0d34fca38fd038205f921eee2ff6d3ba29da092..1f823265d0ba9df801266473dcf5d4d422323ccc 100644 (file)
@@ -229,7 +229,7 @@ bool SparcAsmPrinter::doFinalization(Module &M) {
       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 38f0854f8064d357fb88c4820f95e47d394360ba..26a30a7809798dbc643e7af5c65516eeeb1783cb 100644 (file)
@@ -36,12 +36,6 @@ namespace {
   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
 //===----------------------------------------------------------------------===//
@@ -54,11 +48,10 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
   // Loop over each of the elements, placing them in memory...
   for (unsigned i = 0, e = NumElements; i != e; ++i) {
     const Type *Ty = ST->getElementType(i);
-    unsigned char A;
     unsigned TyAlign;
     uint64_t TySize;
-    getTypeInfoABI(Ty, &TD, TySize, A);
-    TyAlign = ST->isPacked() ? 1 : A;
+    TyAlign = (unsigned) TD.getABITypeAlignment(Ty);
+    TySize = (unsigned) TD.getTypeSize(Ty);
 
     // Add padding if necessary to make the data element aligned properly...
     if (StructSize % TyAlign != 0)
@@ -95,39 +88,127 @@ unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
   return SI-&MemberOffsets[0];
 }
 
+//===----------------------------------------------------------------------===//
+// TargetAlignElem, TargetAlign support
+//===----------------------------------------------------------------------===//
+
+TargetAlignElem
+TargetAlignElem::get(AlignTypeEnum align_type, unsigned char abi_align,
+                     unsigned char pref_align, short bit_width)
+{
+  TargetAlignElem retval;
+  retval.AlignType = align_type;
+  retval.ABIAlign = abi_align;
+  retval.PrefAlign = pref_align;
+  retval.TypeBitWidth = bit_width;
+  return retval;
+}
+
+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 TargetData::InvalidAlignmentElem =
+                TargetAlignElem::get((AlignTypeEnum) -1, 0, 0, 0);
+
 //===----------------------------------------------------------------------===//
 //                       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><br>
+ <i>[E|e]</i>: Endianness. "E" specifies a big-endian target data model, "e"
+ specifies a little-endian target data model.
+ <br><br>
+ <i>p:<size>:<abi_align>:<pref_align></i>: Pointer size, ABI and preferred
+ alignment.
+ <br><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><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><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
+  setAlignment(INTEGER_ALIGN,   1,  1, 1); // Bool
+  setAlignment(INTEGER_ALIGN,   1,  1, 8); // Byte
+  setAlignment(INTEGER_ALIGN,   2,  2, 16); // short
+  setAlignment(INTEGER_ALIGN,   4,  4, 32); // int
+  setAlignment(INTEGER_ALIGN,   0,  8, 64); // long
+  setAlignment(FLOAT_ALIGN,     4,  4, 32); // float
+  setAlignment(FLOAT_ALIGN,     0,  8, 64); // double
+  setAlignment(PACKED_ALIGN,    8,  8, 64); // v2i32
+  setAlignment(PACKED_ALIGN,   16, 16, 128); // v16i8, v8i16, v4i32, ...
+  setAlignment(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;
@@ -136,56 +217,26 @@ void TargetData::init(const std::string &TargetDescription) {
       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;
-      break;
-    case 'd':
-      DoubleABIAlignment = atoi(getToken(token,":").c_str()) / 8;
-      DoublePrefAlignment = atoi(getToken(token,":").c_str()) / 8;
-      if (DoublePrefAlignment == 0)
-        DoublePrefAlignment = DoubleABIAlignment;
-      break;
-    case 'f':
-      FloatABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
-      FloatPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
-      if (FloatPrefAlignment == 0)
-        FloatPrefAlignment = FloatABIAlignment;
-      break;
-    case 'l':
-      LongABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
-      LongPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
-      if (LongPrefAlignment == 0)
-        LongPrefAlignment = LongABIAlignment;
+      PointerABIAlign = atoi(getToken(token,":").c_str()) / 8;
+      PointerPrefAlign = atoi(getToken(token,":").c_str()) / 8;
+      if (PointerPrefAlign == 0)
+        PointerPrefAlign = PointerABIAlign;
       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;
+    case 'v':
+    case 'f':
+    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;
+      setAlignment(align_type, abi_align, pref_align, size);
       break;
+    }
     default:
       break;
     }
@@ -193,16 +244,62 @@ void TargetData::init(const std::string &TargetDescription) {
 
   // 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 = getAlignment(INTEGER_ALIGN, 64);
+  if (long_align.ABIAlign == 0)
+    setAlignment(INTEGER_ALIGN, PointerMemSize, PointerMemSize, 64);
+
+  const TargetAlignElem &double_align = getAlignment(FLOAT_ALIGN, 64);
+  if (double_align.ABIAlign == 0)
+    setAlignment(FLOAT_ALIGN, PointerMemSize, PointerMemSize, 64);
 }
 
 TargetData::TargetData(const Module *M) {
   init(M->getDataLayout());
 }
 
+void
+TargetData::setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
+                         unsigned char pref_align, short bit_width) {
+  TargetAlignElem elt = TargetAlignElem::get(align_type, abi_align,
+                                             pref_align, bit_width);
+  std::pair<align_iterator, align_iterator> ins_result =
+            std::equal_range(Alignments.begin(), Alignments.end(), elt);
+  align_iterator I = ins_result.first;
+  if (I->AlignType == align_type && I->TypeBitWidth == bit_width) {
+    // Update the abi, preferred alignments.
+    I->ABIAlign = abi_align;
+    I->PrefAlign = pref_align;
+  } else
+    Alignments.insert(I, elt);
+
+#if 0
+  // Keep around for debugging and testing...
+  align_iterator E = ins_result.second;
+
+  cerr << "setAlignment(" << elt << ")\n";
+  cerr << "I = " << (I - Alignments.begin())
+       << ", E = " << (E - Alignments.begin()) << "\n";
+  std::copy(Alignments.begin(), Alignments.end(),
+            std::ostream_iterator<TargetAlignElem>(*cerr, "\n"));
+  cerr << "=====\n";
+#endif
+}
+
+const TargetAlignElem &
+TargetData::getAlignment(AlignTypeEnum align_type, short bit_width) const
+{
+  std::pair<align_const_iterator, align_const_iterator> find_result =
+                std::equal_range(Alignments.begin(), Alignments.end(),
+                                 TargetAlignElem::get(align_type, 0, 0,
+                                                      bit_width));
+  align_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;
+}
+
 /// LayoutInfo - The lazy cache of structure layout information maintained by
 /// TargetData.  Note that the struct types must have been free'd before
 /// llvm_shutdown is called (and thus this is deallocated) because all the
@@ -280,190 +377,187 @@ void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
 }
 
 
+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();
 }
 
 
-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 {
-      Size = ((BitWidth + 7) / 8) & ~1;
-      Alignment = TD->getLongABIAlignment();
-    }
-    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);
-    unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
-    Size = AlignedSize*ATy->getNumElements();
-    return;
-  }
-  case Type::PackedTyID: {
-    const PackedType *PTy = cast<PackedType>(Ty);
-    getTypeInfoABI(PTy->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*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 AlignedSize*ATy->getNumElements();
   }
   case Type::StructTyID: {
     // Get the layout annotation... which is lazily created on demand.
-    const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
-    Size = Layout->getSizeInBytes(); Alignment = Layout->getAlignment();
-    return;
+    const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
+    return Layout->getSizeInBytes();
   }
-
-  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->getSizeInBytes();
-    Alignment = std::max(Layout->getAlignment(),
-                         (const unsigned int)TD->getAggMinPrefAlignment());
-    return;
-  }
-
   default:
-    assert(0 && "Bad type for getTypeInfoPref!!!");
-    return;
+    assert(0 && "TargetData::getTypeSize(): Unsupported type");
+    break;
   }
-}
-
-
-uint64_t TargetData::getTypeSize(const Type *Ty) const {
-  uint64_t Size;
-  unsigned char Align;
-  getTypeInfoABI(Ty, this, Size, Align);
-  return Size;
+  return 0;
 }
 
 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 = getAlignment(AGGREGATE_ALIGN, 0);
+    assert(validAlignment(elem)
+           && "Aggregate alignment return invalid in getAlignment");
+    if (abi_or_pref) {
+      return (elem.ABIAlign < Layout->getAlignment()
+              ? Layout->StructAlignment
+              : elem.ABIAlign);
+    } else {
+      return (elem.PrefAlign < Layout->getAlignment()
+              ? 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 = getAlignment((AlignTypeEnum) AlignType,
+                                             getTypeSize(Ty) * 8);
+  if (validAlignment(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);
 }
@@ -533,4 +627,3 @@ unsigned TargetData::getPreferredAlignmentLog(const GlobalVariable *GV) const {
   }
   return Alignment;
 }
-
index 7a5a63dacf81c524e1884db8f9513f9539cd98c9..10bef90489596290942646b21157681fedc24f20 100644 (file)
@@ -109,8 +109,8 @@ X86_64TargetMachine::X86_64TargetMachine(const Module &M, const std::string &FS)
 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 5782260daceb33e7c8264b14df904f4fd745e994..84b83116228caac09a3ca5b0af5ec23730873ff3 100644 (file)
@@ -366,7 +366,6 @@ static Value *getBitCastOperand(Value *V) {
 
 /// 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
@@ -5813,8 +5812,8 @@ Instruction *InstCombiner::PromoteCastOfAllocation(CastInst &CI,
   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
@@ -6903,22 +6902,22 @@ static unsigned GetKnownAlignment(Value *V, TargetData *TD) {
   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;
@@ -6954,11 +6953,11 @@ static unsigned GetKnownAlignment(Value *V, TargetData *TD) {
 
     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;
   }
@@ -8550,8 +8549,10 @@ static bool CheapToScalarize(Value *V, bool isConstant) {
   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)))