diff options
| -rw-r--r-- | llvm/include/llvm/Target/TargetData.h | 181 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/ELFWriter.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/MachOWriter.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/MachineFunction.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 15 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/JIT/JIT.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcAsmPrinter.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/TargetData.cpp | 243 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86TargetMachine.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 24 | ||||
| -rw-r--r-- | llvm/lib/VMCore/ValueTypes.cpp | 13 | 
12 files changed, 365 insertions, 141 deletions
diff --git a/llvm/include/llvm/Target/TargetData.h b/llvm/include/llvm/Target/TargetData.h index aaae41c17c6..42a40dd6c4c 100644 --- a/llvm/include/llvm/Target/TargetData.h +++ b/llvm/include/llvm/Target/TargetData.h @@ -35,15 +35,28 @@ class GlobalVariable;  class TargetData : public ImmutablePass {    bool          LittleEndian;          // Defaults to false -  unsigned char BoolAlignment;         // Defaults to 1 byte -  unsigned char ByteAlignment;         // Defaults to 1 byte -  unsigned char ShortAlignment;        // Defaults to 2 bytes -  unsigned char IntAlignment;          // Defaults to 4 bytes -  unsigned char LongAlignment;         // Defaults to 8 bytes -  unsigned char FloatAlignment;        // Defaults to 4 bytes -  unsigned char DoubleAlignment;       // Defaults to 8 bytes -  unsigned char PointerSize;           // Defaults to 8 bytes -  unsigned char PointerAlignment;      // Defaults to 8 bytes + +  // 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 + +  // 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  public:    /// Default ctor - This has to exist, because this is a pass, but it should @@ -68,15 +81,24 @@ public:    TargetData(const TargetData &TD) :       ImmutablePass(),      LittleEndian(TD.isLittleEndian()), -    BoolAlignment(TD.getBoolAlignment()), -    ByteAlignment(TD.getByteAlignment()), -    ShortAlignment(TD.getShortAlignment()), -    IntAlignment(TD.getIntAlignment()), -    LongAlignment(TD.getLongAlignment()), -    FloatAlignment(TD.getFloatAlignment()), -    DoubleAlignment(TD.getDoubleAlignment()), -    PointerSize(TD.getPointerSize()), -    PointerAlignment(TD.getPointerAlignment()) { +    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()) {    }    ~TargetData();  // Not virtual, do not subclass this class @@ -86,10 +108,16 @@ public:    /// 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 alignments of various data types and -  /// the size of pointers. The "-" 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. +  /// 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> @@ -97,20 +125,24 @@ public:    /// <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]</em> specifies double floating point alignment -  /// [default = 64] <br> -  /// <em>f:[align]</em> specifies single floating point alignment +  /// <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>l:[align]</em> specifies long integer alignment -  /// [default = 64] <br> -  /// <em>i:[align]</em> specifies integer alignment -  /// [default = 32] <br> -  /// <em>s:[align]</em> specifies short integer alignment -  /// [default = 16] <br> -  /// <em>b:[align]</em> specifies byte data type alignment -  /// [default = 8] <br> -  /// <em>B:[align]</em> specifies boolean data type alignment -  /// [default = 8] <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.    void init(const std::string &TargetDescription); @@ -120,17 +152,63 @@ public:    bool          isLittleEndian()       const { return     LittleEndian; }    bool          isBigEndian()          const { return    !LittleEndian; } -  /// Target alignment constraints -  unsigned char getBoolAlignment()     const { return    BoolAlignment; } -  unsigned char getByteAlignment()     const { return    ByteAlignment; } -  unsigned char getShortAlignment()    const { return   ShortAlignment; } -  unsigned char getIntAlignment()      const { return     IntAlignment; } -  unsigned char getLongAlignment()     const { return    LongAlignment; } -  unsigned char getFloatAlignment()    const { return   FloatAlignment; } -  unsigned char getDoubleAlignment()   const { return  DoubleAlignment; } -  unsigned char getPointerAlignment()  const { return PointerAlignment; } -  unsigned char getPointerSize()       const { return      PointerSize; } -  unsigned char getPointerSizeInBits() const { return    8*PointerSize; } +  /// 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 @@ -142,10 +220,13 @@ public:    ///    uint64_t getTypeSize(const Type *Ty) const; -  /// getTypeAlignment - Return the minimum required alignment for the specified -  /// type. -  /// -  unsigned char getTypeAlignment(const Type *Ty) const; +  /// getTypeAlignmentABI - Return the minimum ABI-required alignment for the +  /// specified type. +  unsigned char getTypeAlignmentABI(const Type *Ty) const; + +  /// getTypeAlignmentPref - Return the preferred stack/global alignment for +  /// the specified type. +  unsigned char getTypeAlignmentPref(const Type *Ty) const;    /// getTypeAlignmentShift - Return the minimum required alignment for the    /// specified type, returned as log2 of the value (a shift amount). diff --git a/llvm/lib/CodeGen/ELFWriter.cpp b/llvm/lib/CodeGen/ELFWriter.cpp index 4f988070fdd..3b9653740cc 100644 --- a/llvm/lib/CodeGen/ELFWriter.cpp +++ b/llvm/lib/CodeGen/ELFWriter.cpp @@ -241,7 +241,7 @@ void ELFWriter::EmitGlobal(GlobalVariable *GV) {    }    const Type *GVType = (const Type*)GV->getType(); -  unsigned Align = TM.getTargetData()->getTypeAlignment(GVType); +  unsigned Align = TM.getTargetData()->getTypeAlignmentPref(GVType);    unsigned Size  = TM.getTargetData()->getTypeSize(GVType);    // If this global has a zero initializer, it is part of the .bss or common diff --git a/llvm/lib/CodeGen/MachOWriter.cpp b/llvm/lib/CodeGen/MachOWriter.cpp index 64e11010b3c..82dcf1861b8 100644 --- a/llvm/lib/CodeGen/MachOWriter.cpp +++ b/llvm/lib/CodeGen/MachOWriter.cpp @@ -309,7 +309,7 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {    unsigned Size = TM.getTargetData()->getTypeSize(Ty);    unsigned Align = GV->getAlignment();    if (Align == 0) -    Align = TM.getTargetData()->getTypeAlignment(Ty); +    Align = TM.getTargetData()->getTypeAlignmentPref(Ty);    MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TM); diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index d26b3258fe8..0cba1567e18 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -123,7 +123,8 @@ 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.getIntAlignment() : TD.getPointerAlignment(); +  unsigned Alignment = IsPic ? TD.getIntABIAlignment() +                             : TD.getPointerABIAlignment();    JumpTableInfo = new MachineJumpTableInfo(EntrySize, Alignment);    BasicBlocks.Parent = this; diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index d83dcc4d50b..c8804e907ac 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3029,7 +3029,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()->getTypeAlignment(Ty); +        unsigned Align  = TLI.getTargetData()->getTypeAlignmentPref(Ty);          MachineFunction &MF = DAG.getMachineFunction();          int SSFI =            MF.getFrameInfo()->CreateStackObject((unsigned)TySize, Align); @@ -3937,7 +3937,9 @@ SDOperand SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {  SDOperand SelectionDAGLegalize::CreateStackTemporary(MVT::ValueType VT) {    MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();    unsigned ByteSize = MVT::getSizeInBits(VT)/8; -  int FrameIdx = FrameInfo->CreateStackObject(ByteSize, ByteSize); +  const Type *Ty = MVT::getTypeForValueType(VT); +  unsigned StackAlign = (unsigned)TLI.getTargetData()->getTypeAlignmentPref(Ty); +  int FrameIdx = FrameInfo->CreateStackObject(ByteSize, StackAlign);    return DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());  } @@ -4242,9 +4244,12 @@ SDOperand SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,    if (Op0.getValueType() == MVT::i32) {      // simple 32-bit [signed|unsigned] integer to float/double expansion -    // get the stack frame index of a 8 byte buffer +    // get the stack frame index of a 8 byte buffer, pessimistically aligned      MachineFunction &MF = DAG.getMachineFunction(); -    int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8); +    const Type *F64Type = MVT::getTypeForValueType(MVT::f64); +    unsigned StackAlign = +      (unsigned)TLI.getTargetData()->getTypeAlignmentPref(F64Type); +    int SSFI = MF.getFrameInfo()->CreateStackObject(8, StackAlign);      // get address of 8 byte buffer      SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());      // word offset constant for Hi/Lo address computation diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 7e6a75d7724..e8d58453c24 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -244,17 +244,9 @@ FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli,          const Type *Ty = AI->getAllocatedType();          uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);          unsigned Align =  -          std::max((unsigned)TLI.getTargetData()->getTypeAlignment(Ty), +          std::max((unsigned)TLI.getTargetData()->getTypeAlignmentPref(Ty),                     AI->getAlignment()); -        // If the alignment of the value is smaller than the size of the  -        // value, and if the size of the value is particularly small  -        // (<= 8 bytes), round up to the size of the value for potentially  -        // better performance. -        // -        // FIXME: This could be made better with a preferred alignment hook in -        // TargetData.  It serves primarily to 8-byte align doubles for X86. -        if (Align < TySize && TySize <= 8) Align = TySize;          TySize *= CUI->getZExtValue();   // Get total allocated size.          if (TySize == 0) TySize = 1; // Don't create zero-sized stack objects.          StaticAllocaMap[AI] = @@ -1729,8 +1721,9 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) {    const Type *Ty = I.getAllocatedType();    uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty); -  unsigned Align = std::max((unsigned)TLI.getTargetData()->getTypeAlignment(Ty), -                            I.getAlignment()); +  unsigned Align = +    std::max((unsigned)TLI.getTargetData()->getTypeAlignmentPref(Ty), +             I.getAlignment());    SDOperand AllocSize = getValue(I.getArraySize());    MVT::ValueType IntPtr = TLI.getPointerTy(); diff --git a/llvm/lib/ExecutionEngine/JIT/JIT.cpp b/llvm/lib/ExecutionEngine/JIT/JIT.cpp index 7fd62cc6e0c..c88e393d6a7 100644 --- a/llvm/lib/ExecutionEngine/JIT/JIT.cpp +++ b/llvm/lib/ExecutionEngine/JIT/JIT.cpp @@ -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()->getTypeAlignment(GlobalType); +    size_t A = getTargetData()->getTypeAlignmentPref(GlobalType);      if (A <= 8) {        Ptr = malloc(S);      } else { diff --git a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp index 3bb003ad3d3..d0d34fca38f 100644 --- a/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp +++ b/llvm/lib/Target/Sparc/SparcAsmPrinter.cpp @@ -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->getTypeAlignment(C->getType()); +      unsigned Align = TD->getTypeAlignmentPref(C->getType());        if (C->isNullValue() &&            (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || @@ -239,7 +239,7 @@ bool SparcAsmPrinter::doFinalization(Module &M) {            O << "\t.local " << name << "\n";          O << "\t.comm " << name << "," << TD->getTypeSize(C->getType()) -          << "," << (unsigned)TD->getTypeAlignment(C->getType()); +          << "," << Align;          O << "\n";        } else {          switch (I->getLinkage()) { diff --git a/llvm/lib/Target/TargetData.cpp b/llvm/lib/Target/TargetData.cpp index c0b0670b969..b1fe43dee80 100644 --- a/llvm/lib/Target/TargetData.cpp +++ b/llvm/lib/Target/TargetData.cpp @@ -34,8 +34,11 @@ namespace {    RegisterPass<TargetData> X("targetdata", "Target Data Layout");  } -static inline void getTypeInfo(const Type *Ty, const TargetData *TD, -                               uint64_t &Size, unsigned char &Alignment); +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,7 +55,7 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {      unsigned char A;      unsigned TyAlign;      uint64_t TySize; -    getTypeInfo(Ty, &TD, TySize, A); +    getTypeInfoABI(Ty, &TD, TySize, A);      TyAlign = ST->isPacked() ? 1 : A;      // Add padding if necessary to make the data element aligned properly... @@ -80,8 +83,7 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {  /// return the structure index that contains it.  unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {    std::vector<uint64_t>::const_iterator SI = -    std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(), -                     Offset); +    std::upper_bound(MemberOffsets.begin(), MemberOffsets.end(), Offset);    assert(SI != MemberOffsets.begin() && "Offset not in structure type!");    --SI;    assert(*SI <= Offset && "upper_bound didn't work"); @@ -99,15 +101,24 @@ void TargetData::init(const std::string &TargetDescription) {    std::string temp = TargetDescription;    LittleEndian = false; -  PointerSize = 8; -  PointerAlignment   = 8; -  DoubleAlignment = 8; -  FloatAlignment = 4; -  LongAlignment   = 8; -  IntAlignment   = 4; -  ShortAlignment  = 2; -  ByteAlignment  = 1; -  BoolAlignment   = 1; +  PointerMemSize = 8; +  PointerABIAlignment   = 8; +  DoubleABIAlignment = 8; +  FloatABIAlignment = 4; +  LongABIAlignment   = 8; +  IntABIAlignment   = 4; +  ShortABIAlignment  = 2; +  ByteABIAlignment  = 1; +  BoolABIAlignment   = 1; +  BoolPrefAlignment = BoolABIAlignment; +  BytePrefAlignment = ByteABIAlignment; +  ShortPrefAlignment = ShortABIAlignment; +  IntPrefAlignment = IntABIAlignment; +  LongPrefAlignment = LongABIAlignment; +  FloatPrefAlignment = FloatABIAlignment; +  DoublePrefAlignment = DoubleABIAlignment; +  PointerPrefAlignment = PointerABIAlignment; +  AggMinPrefAlignment = 0;    while (!temp.empty()) {      std::string token = getToken(temp, "-"); @@ -122,29 +133,58 @@ void TargetData::init(const std::string &TargetDescription) {        LittleEndian = true;        break;      case 'p': -      PointerSize = atoi(getToken(token,":").c_str()) / 8; -      PointerAlignment = atoi(getToken(token,":").c_str()) / 8; +      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': -      DoubleAlignment = atoi(getToken(token,":").c_str()) / 8; +      DoubleABIAlignment = atoi(getToken(token,":").c_str()) / 8; +      DoublePrefAlignment = atoi(getToken(token,":").c_str()) / 8; +      if (DoublePrefAlignment == 0) +        DoublePrefAlignment = DoubleABIAlignment;        break;      case 'f': -      FloatAlignment = atoi(getToken(token, ":").c_str()) / 8; +      FloatABIAlignment = atoi(getToken(token, ":").c_str()) / 8; +      FloatPrefAlignment = atoi(getToken(token,":").c_str()) / 8; +      if (FloatPrefAlignment == 0) +        FloatPrefAlignment = FloatABIAlignment;        break;      case 'l': -      LongAlignment = atoi(getToken(token, ":").c_str()) / 8; +      LongABIAlignment = atoi(getToken(token, ":").c_str()) / 8; +      LongPrefAlignment = atoi(getToken(token,":").c_str()) / 8; +      if (LongPrefAlignment == 0) +        LongPrefAlignment = LongABIAlignment;        break;      case 'i': -      IntAlignment = atoi(getToken(token, ":").c_str()) / 8; +      IntABIAlignment = atoi(getToken(token, ":").c_str()) / 8; +      IntPrefAlignment = atoi(getToken(token,":").c_str()) / 8; +      if (IntPrefAlignment == 0) +        IntPrefAlignment = IntABIAlignment;        break;      case 's': -      ShortAlignment = atoi(getToken(token, ":").c_str()) / 8; +      ShortABIAlignment = atoi(getToken(token, ":").c_str()) / 8; +      ShortPrefAlignment = atoi(getToken(token,":").c_str()) / 8; +      if (ShortPrefAlignment == 0) +        ShortPrefAlignment = ShortABIAlignment;        break;      case 'b': -      ByteAlignment = atoi(getToken(token, ":").c_str()) / 8; +      ByteABIAlignment = atoi(getToken(token, ":").c_str()) / 8; +      BytePrefAlignment = atoi(getToken(token,":").c_str()) / 8; +      if (BytePrefAlignment == 0) +        BytePrefAlignment = ByteABIAlignment;        break;      case 'B': -      BoolAlignment = atoi(getToken(token, ":").c_str()) / 8; +      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; +      if (AggMinPrefAlignment == 0) +        AggMinPrefAlignment = 0;        break;      default:        break; @@ -153,16 +193,25 @@ void TargetData::init(const std::string &TargetDescription) {  }  TargetData::TargetData(const Module *M) { -  LittleEndian     = M->getEndianness() != Module::BigEndian; -  PointerSize      = M->getPointerSize() != Module::Pointer64 ? 4 : 8; -  PointerAlignment = PointerSize; -  DoubleAlignment  = PointerSize; -  FloatAlignment   = 4; -  LongAlignment    = PointerSize; -  IntAlignment     = 4; -  ShortAlignment   = 2; -  ByteAlignment    = 1; -  BoolAlignment    = 1; +  LittleEndian       = M->getEndianness() != Module::BigEndian; +  PointerMemSize     = M->getPointerSize() != Module::Pointer64 ? 4 : 8; +  PointerABIAlignment = PointerMemSize; +  DoubleABIAlignment  = PointerMemSize; +  FloatABIAlignment   = 4; +  LongABIAlignment    = PointerMemSize; +  IntABIAlignment     = 4; +  ShortABIAlignment   = 2; +  ByteABIAlignment    = 1; +  BoolABIAlignment    = 1; +  BoolPrefAlignment = BoolABIAlignment; +  BytePrefAlignment = ByteABIAlignment; +  ShortPrefAlignment = ShortABIAlignment; +  IntPrefAlignment = IntABIAlignment; +  LongPrefAlignment = LongABIAlignment; +  FloatPrefAlignment = FloatABIAlignment; +  DoublePrefAlignment = DoubleABIAlignment; +  PointerPrefAlignment = PointerABIAlignment; +  AggMinPrefAlignment = 0;  }  /// Layouts - The lazy cache of structure layout information maintained by @@ -195,14 +244,22 @@ std::string TargetData::getStringRepresentation() const {    else      repr << "E"; -  repr << "-p:" << (PointerSize * 8) << ":" << (PointerAlignment * 8); -  repr << "-d:64:" << (DoubleAlignment * 8); -  repr << "-f:32:" << (FloatAlignment * 8); -  repr << "-l:64:" << (LongAlignment * 8); -  repr << "-i:32:" << (IntAlignment * 8); -  repr << "-s:16:" << (ShortAlignment * 8); -  repr << "-b:8:" << (ByteAlignment * 8); -  repr << "-B:8:" << (BoolAlignment * 8); +  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);    return repr.str();  } @@ -237,41 +294,41 @@ void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const { -static inline void getTypeInfo(const Type *Ty, const TargetData *TD, -                               uint64_t &Size, unsigned char &Alignment) { +static inline void getTypeInfoABI(const Type *Ty, const TargetData *TD, +                                  uint64_t &Size, unsigned char &Alignment) {    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->getByteAlignment(); +      Size = 1; Alignment = TD->getByteABIAlignment();      } else if (BitWidth <= 16) { -      Size = 2; Alignment = TD->getShortAlignment(); +      Size = 2; Alignment = TD->getShortABIAlignment();      } else if (BitWidth <= 32) { -      Size = 4; Alignment = TD->getIntAlignment(); +      Size = 4; Alignment = TD->getIntABIAlignment();      } else if (BitWidth <= 64) { -      Size = 8; Alignment = TD->getLongAlignment(); +      Size = 8; Alignment = TD->getLongABIAlignment();      } else        assert(0 && "Integer types > 64 bits not supported.");      return;    } -  case Type::VoidTyID:   Size = 1; Alignment = TD->getByteAlignment(); return; -  case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return; -  case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); 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->getPointerAlignment(); +    Size = TD->getPointerSize(); Alignment = TD->getPointerABIAlignment();      return;    case Type::ArrayTyID: {      const ArrayType *ATy = cast<ArrayType>(Ty); -    getTypeInfo(ATy->getElementType(), TD, Size, Alignment); +    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); -    getTypeInfo(PTy->getElementType(), TD, Size, Alignment); +    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. @@ -292,22 +349,94 @@ static inline void getTypeInfo(const Type *Ty, const TargetData *TD,    }  } +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(); +    } else if (BitWidth <= 16) { +      Size = 2; Alignment = TD->getShortPrefAlignment(); +    } else if (BitWidth <= 32) { +      Size = 4; Alignment = TD->getIntPrefAlignment(); +    } else if (BitWidth <= 64) { +      Size = 8; Alignment = TD->getLongPrefAlignment(); +    } else +      assert(0 && "Integer types > 64 bits not supported."); +    return; +  } +  case Type::VoidTyID: +    Size = 1; Alignment = TD->getBytePrefAlignment(); +    return; +  case Type::FloatTyID: +    Size = 4; Alignment = TD->getFloatPrefAlignment(); +    return; +  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; +  } +  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; +  } +  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; +  } +} + +  uint64_t TargetData::getTypeSize(const Type *Ty) const {    uint64_t Size;    unsigned char Align; -  getTypeInfo(Ty, this, Size, Align); +  getTypeInfoABI(Ty, this, Size, Align);    return Size;  } -unsigned char TargetData::getTypeAlignment(const Type *Ty) const { +unsigned char TargetData::getTypeAlignmentABI(const Type *Ty) const { +  uint64_t Size; +  unsigned char Align; +  getTypeInfoABI(Ty, this, Size, Align); +  return Align; +} + +unsigned char TargetData::getTypeAlignmentPref(const Type *Ty) const {    uint64_t Size;    unsigned char Align; -  getTypeInfo(Ty, this, Size, Align); +  getTypeInfoPref(Ty, this, Size, Align);    return Align;  }  unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const { -  unsigned Align = getTypeAlignment(Ty); +  unsigned Align = getTypeAlignmentABI(Ty);    assert(!(Align & (Align-1)) && "Alignment is not a power of two!");    return Log2_32(Align);  } diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp index d8283a5f220..17bc7b14eb1 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -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-l:32") : -               std::string("e-p:32:32-d:32-l:32")), +               std::string("e-p:64:64-d:32:64-l:32") : +               std::string("e-p:32:32-d:32:64-l:32")),      FrameInfo(TargetFrameInfo::StackGrowsDown,                Subtarget.getStackAlignment(), Subtarget.is64Bit() ? -8 : -4),      InstrInfo(*this), JITInfo(*this), TLInfo(*this) { diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 414ae794b18..04b06d28aa7 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -5779,8 +5779,8 @@ Instruction *InstCombiner::PromoteCastOfAllocation(CastInst &CI,    const Type *CastElTy = PTy->getElementType();    if (!AllocElTy->isSized() || !CastElTy->isSized()) return 0; -  unsigned AllocElTyAlign = TD->getTypeAlignment(AllocElTy); -  unsigned CastElTyAlign = TD->getTypeAlignment(CastElTy); +  unsigned AllocElTyAlign = TD->getTypeAlignmentABI(AllocElTy); +  unsigned CastElTyAlign = TD->getTypeAlignmentABI(CastElTy);    if (CastElTyAlign < AllocElTyAlign) return 0;    // If the allocation has multiple uses, only promote it if we are strictly @@ -6878,18 +6878,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->getTypeAlignment(GV->getType()->getElementType()); +      Align = TD->getTypeAlignmentPref(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->getTypeAlignment(AI->getType()->getElementType()); +        Align = TD->getTypeAlignmentPref(AI->getType()->getElementType());        else if (isa<MallocInst>(AI)) {          // Malloc returns maximally aligned memory. -        Align = TD->getTypeAlignment(AI->getType()->getElementType()); -        Align = std::max(Align, (unsigned)TD->getTypeAlignment(Type::DoubleTy)); -        Align = std::max(Align, (unsigned)TD->getTypeAlignment(Type::Int64Ty)); +        Align = TD->getTypeAlignmentABI(AI->getType()->getElementType()); +        Align = +          std::max(Align, +                   (unsigned)TD->getTypeAlignmentABI(Type::DoubleTy)); +        Align = +          std::max(Align, +                   (unsigned)TD->getTypeAlignmentABI(Type::Int64Ty));        }      }      return Align; @@ -6924,10 +6928,12 @@ static unsigned GetKnownAlignment(Value *V, TargetData *TD) {      if (!TD) return 0;      const Type *BasePtrTy = GEPI->getOperand(0)->getType(); -    if (TD->getTypeAlignment(cast<PointerType>(BasePtrTy)->getElementType()) +    const PointerType *PtrTy = cast<PointerType>(BasePtrTy); +    if (TD->getTypeAlignmentABI(PtrTy->getElementType())          <= BaseAlignment) {        const Type *GEPTy = GEPI->getType(); -      return TD->getTypeAlignment(cast<PointerType>(GEPTy)->getElementType()); +      const PointerType *GEPPtrTy = cast<PointerType>(GEPTy); +      return TD->getTypeAlignmentABI(GEPPtrTy->getElementType());      }      return 0;    } diff --git a/llvm/lib/VMCore/ValueTypes.cpp b/llvm/lib/VMCore/ValueTypes.cpp index 8732d641983..e421d5d4303 100644 --- a/llvm/lib/VMCore/ValueTypes.cpp +++ b/llvm/lib/VMCore/ValueTypes.cpp @@ -82,8 +82,8 @@ MVT::ValueType MVT::getVectorType(ValueType VT, unsigned NumElements) {  }  /// MVT::getTypeForValueType - This method returns an LLVM type corresponding -/// to the specified ValueType.  For integer types, this returns an unsigned -/// type.  Note that this will abort for types that cannot be represented. +/// to the specified ValueType.  Note that this will abort for types that cannot +/// be represented.  const Type *MVT::getTypeForValueType(MVT::ValueType VT) {    switch (VT) {    default: assert(0 && "ValueType does not correspond to LLVM type!"); @@ -95,5 +95,14 @@ const Type *MVT::getTypeForValueType(MVT::ValueType VT) {    case MVT::i64:   return Type::Int64Ty;    case MVT::f32:   return Type::FloatTy;    case MVT::f64:   return Type::DoubleTy; +  case MVT::v8i8:  return PackedType::get(Type::Int8Ty, 8); +  case MVT::v4i16: return PackedType::get(Type::Int16Ty, 4); +  case MVT::v2i32: return PackedType::get(Type::Int32Ty, 2); +  case MVT::v16i8: return PackedType::get(Type::Int8Ty, 16); +  case MVT::v8i16: return PackedType::get(Type::Int16Ty, 8); +  case MVT::v4i32: return PackedType::get(Type::Int32Ty, 4); +  case MVT::v2i64: return PackedType::get(Type::Int64Ty, 2); +  case MVT::v4f32: return PackedType::get(Type::FloatTy, 4); +  case MVT::v2f64: return PackedType::get(Type::DoubleTy, 2);    }  }  | 

