Per Chris' suggestion to submit enhancement patches to llvm-commits,... - Adds stack and global alignment options to TargetData specification strings.
- Adds minimum stack and global alignment for aggregates. -scooter -- Scott Michel [EMAIL PROTECTED] Member of Technical Staff, CSRD 310/336-5034 The Aerospace Corporation
--- old-llvm/include/llvm/Target/TargetData.h 2007-01-17 12:23:39.000000000 -0800 +++ new-llvm/include/llvm/Target/TargetData.h 2007-01-17 12:23:39.000000000 -0800 @@ -35,15 +35,39 @@ 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 + + // "SAAlignment": Struct/Array alignments + unsigned char BoolSAAlignment; // Defaults to 1 byte + unsigned char ByteSAAlignment; // Defaults to 1 byte + unsigned char ShortSAAlignment; // Defaults to 2 bytes + unsigned char IntSAAlignment; // Defaults to 4 bytes + unsigned char LongSAAlignment; // Defaults to 8 bytes + unsigned char FloatSAAlignment; // Defaults to 4 bytes + unsigned char DoubleSAAlignment; // Defaults to 8 bytes + unsigned char PointerMemSize; // Defaults to 8 bytes + unsigned char PointerSAAlignment; // Defaults to 8 bytes + + // Stack type alignments. + unsigned char BoolStackAlignment; // Defaults to BoolAlignment + unsigned char ByteStackAlignment; // Defaults to ByteAlignment + unsigned char ShortStackAlignment; // Defaults to ShortAlignment + unsigned char IntStackAlignment; // Defaults to IntAlignment + unsigned char LongStackAlignment; // Defaults to LongAlignment + unsigned char FloatStackAlignment; // Defaults to FloatAlignment + unsigned char DoubleStackAlignment; // Defaults to DoubleAlignment + unsigned char PointerStackAlignment; // Defaults to PointerAlignment + unsigned char AggMinStackAlignment; // Defaults to 4 bytes + + // Global alignments + unsigned char BoolGlobalAlignment; // Defaults to BoolAlignment + unsigned char ByteGlobalAlignment; // Defaults to ByteAlignment + unsigned char ShortGlobalAlignment; // Defaults to ShortAlignment + unsigned char IntGlobalAlignment; // Defaults to IntAlignment + unsigned char LongGlobalAlignment; // Defaults to LongAlignment + unsigned char FloatGlobalAlignment; // Defaults to FloatAlignment + unsigned char DoubleGlobalAlignment; // Defaults to DoubleAlignment + unsigned char PointerGlobalAlignment;// Defaults to PointerAlignment + unsigned char AggMinGlobalAlignment; // Defaults to 4 bytes public: /// Default ctor - This has to exist, because this is a pass, but it should @@ -68,15 +92,33 @@ 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()) { + BoolSAAlignment(TD.getBoolSAAlignment()), + ByteSAAlignment(TD.getByteSAAlignment()), + ShortSAAlignment(TD.getShortSAAlignment()), + IntSAAlignment(TD.getIntSAAlignment()), + LongSAAlignment(TD.getLongSAAlignment()), + FloatSAAlignment(TD.getFloatSAAlignment()), + DoubleSAAlignment(TD.getDoubleSAAlignment()), + PointerMemSize(TD.getPointerSize()), + PointerSAAlignment(TD.getPointerSAAlignment()), + BoolStackAlignment(TD.getBoolStackAlignment()), + ByteStackAlignment(TD.getByteStackAlignment()), + ShortStackAlignment(TD.getShortStackAlignment()), + IntStackAlignment(TD.getIntStackAlignment()), + LongStackAlignment(TD.getLongStackAlignment()), + FloatStackAlignment(TD.getFloatStackAlignment()), + DoubleStackAlignment(TD.getDoubleStackAlignment()), + PointerStackAlignment(TD.getPointerStackAlignment()), + AggMinStackAlignment(TD.getAggMinStackAlignment()), + BoolGlobalAlignment(TD.getBoolGlobalAlignment()), + ByteGlobalAlignment(TD.getByteGlobalAlignment()), + ShortGlobalAlignment(TD.getShortGlobalAlignment()), + IntGlobalAlignment(TD.getIntGlobalAlignment()), + LongGlobalAlignment(TD.getLongGlobalAlignment()), + FloatGlobalAlignment(TD.getFloatGlobalAlignment()), + DoubleGlobalAlignment(TD.getDoubleGlobalAlignment()), + PointerGlobalAlignment(TD.getPointerGlobalAlignment()), + AggMinGlobalAlignment(TD.getAggMinGlobalAlignment()) { } ~TargetData(); // Not virtual, do not subclass this class @@ -86,10 +128,19 @@ /// 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 struct/array 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 stack alignment specifications (":[stackalign]") are optional and + /// default to the memory alignment. + /// + /// The global alignment specifications (":[globalign]") are also optional + /// and default to structure/array alignment. /// /// Valid tokens: /// <br> @@ -97,20 +148,25 @@ /// <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 - /// [default = 32] <br> - /// <em>l:[align]</em> specifies long integer alignment - /// [default = 64] <br> - /// <em>i:[align]</em> specifies integer alignment + /// <em>d:[align]:[stackalign]:[globalign]</em> specifies double floating + /// point alignment [default = 64] <br> + /// <em>f:[align]:[stackalign]:[globalign]</em> specifies single floating + /// point alignment [default = 32] <br> + /// <em>l:[align]:[stackalign]:[globalign[</em> specifies long integer + /// alignment [default = 64] <br> + /// <em>i:[align]:[stackalign]:[globalign]</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]:[stackalign]:[globalign]</em> specifies short integer + /// alignment [default = 16] <br> + /// <em>b:[align]:[stackalign]:[globalign]</em> specifies byte data type + /// alignment [default = 8] <br> + /// <em>B:[align]:[stackalign]:[globalign]</em> specifies boolean data type + /// alignment [default = 8] <br> + /// <em>A:[minstackalign]:[minglobalign]</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 +176,100 @@ 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 getBoolSAAlignment() const { return BoolSAAlignment; } + /// Target byte alignment + unsigned char getByteSAAlignment() const { return ByteSAAlignment; } + /// Target short alignment + unsigned char getShortSAAlignment() const { return ShortSAAlignment; } + /// Target integer alignment + unsigned char getIntSAAlignment() const { return IntSAAlignment; } + /// Target long alignment + unsigned char getLongSAAlignment() const { return LongSAAlignment; } + /// Target single precision float alignment + unsigned char getFloatSAAlignment() const { return FloatSAAlignment; } + /// Target double precision float alignment + unsigned char getDoubleSAAlignment() const { return DoubleSAAlignment; } + /// Target pointer alignment + unsigned char getPointerSAAlignment() const { return PointerSAAlignment; } + /// 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 getBoolStackAlignment() const { + return BoolStackAlignment; + } + /// Return target's alignment for integers on stack + unsigned char getByteStackAlignment() const { + return ByteStackAlignment; + } + /// Return target's alignment for shorts on stack + unsigned char getShortStackAlignment() const { + return ShortStackAlignment; + } + /// Return target's alignment for integers on stack + unsigned char getIntStackAlignment() const { + return IntStackAlignment; + } + /// Return target's alignment for longs on stack + unsigned char getLongStackAlignment() const { + return LongStackAlignment; + } + /// Return target's alignment for single precision floats on stack + unsigned char getFloatStackAlignment() const { + return FloatStackAlignment; + } + /// Return target's alignment for double preceision floats on stack + unsigned char getDoubleStackAlignment() const { + return DoubleStackAlignment; + } + /// Return target's alignment for stack-based pointers + unsigned char getPointerStackAlignment() const { + return PointerStackAlignment; + } + /// Return target's alignment for stack-based structures + unsigned char getAggMinStackAlignment() const { + return AggMinStackAlignment; + } + + /// Return target's alignment for global booleans + unsigned char getBoolGlobalAlignment() const { + return BoolGlobalAlignment; + } + /// Return target's alignment for global integers + unsigned char getByteGlobalAlignment() const { + return ByteGlobalAlignment; + } + /// Return target's alignment for global shorts + unsigned char getShortGlobalAlignment() const { + return ShortGlobalAlignment; + } + /// Return target's alignment for global integers + unsigned char getIntGlobalAlignment() const { + return IntGlobalAlignment; + } + /// Return target's alignment for global longs + unsigned char getLongGlobalAlignment() const { + return LongGlobalAlignment; + } + /// Return target's alignment for global single precision floats + unsigned char getFloatGlobalAlignment() const { + return FloatGlobalAlignment; + } + /// Return target's alignment for global double precision floats + unsigned char getDoubleGlobalAlignment() const { + return DoubleGlobalAlignment; + } + /// Return target's alignment for global pointers + unsigned char getPointerGlobalAlignment() const { + return PointerGlobalAlignment; + } + /// Return target's alignment for global structures + unsigned char getAggMinGlobalAlignment() const { + return AggMinGlobalAlignment; + } /// getStringRepresentation - Return the string representation of the /// TargetData. This representation is in the same format accepted by the @@ -142,10 +281,18 @@ /// uint64_t getTypeSize(const Type *Ty) const; - /// getTypeAlignment - Return the minimum required alignment for the specified + /// getTypeAlignmentStructArray - Return the minimum required alignment for the specified /// type. /// - unsigned char getTypeAlignment(const Type *Ty) const; + unsigned char getTypeAlignmentStructArray(const Type *Ty) const; + + /// getTypeAlignmentStack- Return the stack-based alignment for the specified + /// type. + unsigned char getTypeAlignmentStack(const Type *Ty) const; + + /// getTypeAlignmentGlobal- Return the stack-based alignment for the specified + /// type. + unsigned char getTypeAlignmentGlobal(const Type *Ty) const; /// getTypeAlignmentShift - Return the minimum required alignment for the /// specified type, returned as log2 of the value (a shift amount). --- old-llvm/lib/CodeGen/ELFWriter.cpp 2007-01-17 12:22:57.000000000 -0800 +++ new-llvm/lib/CodeGen/ELFWriter.cpp 2007-01-17 12:22:58.000000000 -0800 @@ -236,7 +236,7 @@ } const Type *GVType = (const Type*)GV->getType(); - unsigned Align = TM.getTargetData()->getTypeAlignment(GVType); + unsigned Align = TM.getTargetData()->getTypeAlignmentGlobal(GVType); unsigned Size = TM.getTargetData()->getTypeSize(GVType); // If this global has a zero initializer, it is part of the .bss or common --- old-llvm/lib/CodeGen/MachOWriter.cpp 2007-01-17 12:22:57.000000000 -0800 +++ new-llvm/lib/CodeGen/MachOWriter.cpp 2007-01-17 12:22:58.000000000 -0800 @@ -295,7 +295,7 @@ unsigned Size = TM.getTargetData()->getTypeSize(Ty); unsigned Align = GV->getAlignment(); if (Align == 0) - Align = TM.getTargetData()->getTypeAlignment(Ty); + Align = TM.getTargetData()->getTypeAlignmentGlobal(Ty); MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TM); --- old-llvm/lib/CodeGen/MachineFunction.cpp 2007-01-17 12:22:57.000000000 -0800 +++ new-llvm/lib/CodeGen/MachineFunction.cpp 2007-01-17 12:22:58.000000000 -0800 @@ -123,7 +123,8 @@ 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.getIntSAAlignment() + : TD.getPointerSAAlignment(); JumpTableInfo = new MachineJumpTableInfo(EntrySize, Alignment); BasicBlocks.Parent = this; --- old-llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp 2007-01-17 12:22:57.000000000 -0800 +++ new-llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp 2007-01-17 12:22:58.000000000 -0800 @@ -3028,7 +3028,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()->getTypeAlignment(Ty); + unsigned Align = TLI.getTargetData()->getTypeAlignmentStack(Ty); MachineFunction &MF = DAG.getMachineFunction(); int SSFI = MF.getFrameInfo()->CreateStackObject((unsigned)TySize, Align); @@ -3936,7 +3936,9 @@ 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()->getTypeAlignmentStack(Ty); + int FrameIdx = FrameInfo->CreateStackObject(ByteSize, StackAlign); return DAG.getFrameIndex(FrameIdx, TLI.getPointerTy()); } @@ -4241,9 +4243,12 @@ 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()->getTypeAlignmentStack(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 --- old-llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp 2007-01-17 12:22:57.000000000 -0800 +++ new-llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp 2007-01-17 12:22:58.000000000 -0800 @@ -244,17 +244,9 @@ 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()->getTypeAlignmentStack(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 @@ 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()->getTypeAlignmentStack(Ty), + I.getAlignment()); SDOperand AllocSize = getValue(I.getArraySize()); MVT::ValueType IntPtr = TLI.getPointerTy(); --- old-llvm/lib/ExecutionEngine/JIT/JIT.cpp 2007-01-17 12:22:57.000000000 -0800 +++ new-llvm/lib/ExecutionEngine/JIT/JIT.cpp 2007-01-17 12:22:58.000000000 -0800 @@ -338,7 +338,7 @@ // compilation. const Type *GlobalType = GV->getType()->getElementType(); size_t S = getTargetData()->getTypeSize(GlobalType); - size_t A = getTargetData()->getTypeAlignment(GlobalType); + size_t A = getTargetData()->getTypeAlignmentGlobal(GlobalType); if (A <= 8) { Ptr = malloc(S); } else { --- old-llvm/lib/Target/ARM/ARMAsmPrinter.cpp 2007-01-17 12:22:57.000000000 -0800 +++ new-llvm/lib/Target/ARM/ARMAsmPrinter.cpp 2007-01-17 12:22:58.000000000 -0800 @@ -306,7 +306,7 @@ std::string name = Mang->getValueName(I); Constant *C = I->getInitializer(); unsigned Size = TD->getTypeSize(C->getType()); - unsigned Align = Log2_32(TD->getTypeAlignment(C->getType())); + unsigned Align = Log2_32(TD->getTypeAlignmentGlobal(C->getType())); if (C->isNullValue() && !I->hasSection() && --- old-llvm/lib/Target/Sparc/SparcAsmPrinter.cpp 2007-01-17 12:22:57.000000000 -0800 +++ new-llvm/lib/Target/Sparc/SparcAsmPrinter.cpp 2007-01-17 12:22:58.000000000 -0800 @@ -229,7 +229,7 @@ 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->getTypeAlignmentGlobal(C->getType()); if (C->isNullValue() && (I->hasLinkOnceLinkage() || I->hasInternalLinkage() || @@ -239,7 +239,7 @@ 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()) { --- old-llvm/lib/Target/TargetData.cpp 2007-01-17 12:22:57.000000000 -0800 +++ new-llvm/lib/Target/TargetData.cpp 2007-01-17 12:22:58.000000000 -0800 @@ -34,8 +34,15 @@ 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 getTypeInfoStructArray(const Type *Ty, const TargetData *TD, + uint64_t &Size, + unsigned char &Alignment); + +static inline void getTypeInfoStack(const Type *Ty, const TargetData *TD, + uint64_t &Size, unsigned char &Alignment); + +static inline void getTypeInfoGlobal(const Type *Ty, const TargetData *TD, + uint64_t &Size, unsigned char &Alignment); //===----------------------------------------------------------------------===// // Support for StructLayout @@ -52,7 +59,7 @@ unsigned char A; unsigned TyAlign; uint64_t TySize; - getTypeInfo(Ty, &TD, TySize, A); + getTypeInfoStructArray(Ty, &TD, TySize, A); TyAlign = ST->isPacked() ? 1 : A; // Add padding if necessary to make the data element aligned properly... @@ -80,8 +87,7 @@ /// 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 +105,33 @@ 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; + PointerSAAlignment = 8; + DoubleSAAlignment = 8; + FloatSAAlignment = 4; + LongSAAlignment = 8; + IntSAAlignment = 4; + ShortSAAlignment = 2; + ByteSAAlignment = 1; + BoolSAAlignment = 1; + BoolStackAlignment = BoolSAAlignment; + ByteStackAlignment = ByteSAAlignment; + ShortStackAlignment = ShortSAAlignment; + IntStackAlignment = IntSAAlignment; + LongStackAlignment = LongSAAlignment; + FloatStackAlignment = FloatSAAlignment; + DoubleStackAlignment = DoubleSAAlignment; + PointerStackAlignment = PointerSAAlignment; + AggMinStackAlignment = 0; + BoolGlobalAlignment = BoolSAAlignment; + ByteGlobalAlignment = ByteSAAlignment; + ShortGlobalAlignment = ShortSAAlignment; + IntGlobalAlignment = IntSAAlignment; + LongGlobalAlignment = LongSAAlignment; + FloatGlobalAlignment = FloatSAAlignment; + DoubleGlobalAlignment = DoubleSAAlignment; + PointerGlobalAlignment = PointerSAAlignment; + AggMinGlobalAlignment = 0; while (!temp.empty()) { std::string token = getToken(temp, "-"); @@ -122,29 +146,85 @@ 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; + PointerSAAlignment = atoi(getToken(token,":").c_str()) / 8; + PointerStackAlignment = atoi(getToken(token,":").c_str()) / 8; + if (PointerStackAlignment == 0) + PointerStackAlignment = PointerSAAlignment; + PointerGlobalAlignment = atoi(getToken(token,":").c_str()) / 8; + if (PointerGlobalAlignment == 0) + PointerGlobalAlignment = PointerSAAlignment; break; case 'd': - DoubleAlignment = atoi(getToken(token,":").c_str()) / 8; + DoubleSAAlignment = atoi(getToken(token,":").c_str()) / 8; + DoubleStackAlignment = atoi(getToken(token,":").c_str()) / 8; + if (DoubleStackAlignment == 0) + DoubleStackAlignment = DoubleSAAlignment; + DoubleGlobalAlignment = atoi(getToken(token,":").c_str()) / 8; + if (DoubleGlobalAlignment == 0) + DoubleGlobalAlignment = DoubleSAAlignment; break; case 'f': - FloatAlignment = atoi(getToken(token, ":").c_str()) / 8; + FloatSAAlignment = atoi(getToken(token, ":").c_str()) / 8; + FloatStackAlignment = atoi(getToken(token,":").c_str()) / 8; + if (FloatStackAlignment == 0) + FloatStackAlignment = FloatSAAlignment; + FloatGlobalAlignment = atoi(getToken(token,":").c_str()) / 8; + if (FloatGlobalAlignment == 0) + FloatGlobalAlignment = FloatSAAlignment; break; case 'l': - LongAlignment = atoi(getToken(token, ":").c_str()) / 8; + LongSAAlignment = atoi(getToken(token, ":").c_str()) / 8; + LongStackAlignment = atoi(getToken(token,":").c_str()) / 8; + if (LongStackAlignment == 0) + LongStackAlignment = LongSAAlignment; + LongGlobalAlignment = atoi(getToken(token,":").c_str()) / 8; + if (LongGlobalAlignment == 0) + LongGlobalAlignment = LongSAAlignment; break; case 'i': - IntAlignment = atoi(getToken(token, ":").c_str()) / 8; + IntSAAlignment = atoi(getToken(token, ":").c_str()) / 8; + IntStackAlignment = atoi(getToken(token,":").c_str()) / 8; + if (IntStackAlignment == 0) + IntStackAlignment = IntSAAlignment; + IntGlobalAlignment = atoi(getToken(token,":").c_str()) / 8; + if (IntGlobalAlignment == 0) + IntGlobalAlignment = IntSAAlignment; break; case 's': - ShortAlignment = atoi(getToken(token, ":").c_str()) / 8; + ShortSAAlignment = atoi(getToken(token, ":").c_str()) / 8; + ShortStackAlignment = atoi(getToken(token,":").c_str()) / 8; + if (ShortStackAlignment == 0) + ShortStackAlignment = ShortSAAlignment; + ShortGlobalAlignment = atoi(getToken(token,":").c_str()) / 8; + if (ShortGlobalAlignment == 0) + ShortGlobalAlignment = ShortSAAlignment; break; case 'b': - ByteAlignment = atoi(getToken(token, ":").c_str()) / 8; + ByteSAAlignment = atoi(getToken(token, ":").c_str()) / 8; + ByteStackAlignment = atoi(getToken(token,":").c_str()) / 8; + if (ByteStackAlignment == 0) + ByteStackAlignment = ByteSAAlignment; + ByteGlobalAlignment = atoi(getToken(token,":").c_str()) / 8; + if (ByteGlobalAlignment == 0) + ByteGlobalAlignment = ByteSAAlignment; break; case 'B': - BoolAlignment = atoi(getToken(token, ":").c_str()) / 8; + BoolSAAlignment = atoi(getToken(token, ":").c_str()) / 8; + BoolStackAlignment = atoi(getToken(token,":").c_str()) / 8; + if (BoolStackAlignment == 0) + BoolStackAlignment = BoolSAAlignment; + BoolGlobalAlignment = atoi(getToken(token,":").c_str()) / 8; + if (BoolGlobalAlignment == 0) + BoolGlobalAlignment = BoolSAAlignment; + break; + case 'A': + AggMinStackAlignment = atoi(getToken(token,":").c_str()) / 8; + if (AggMinStackAlignment == 0) + AggMinStackAlignment = 0; + AggMinGlobalAlignment = atoi(getToken(token,":").c_str()) / 8; + if (AggMinGlobalAlignment == 0) + AggMinGlobalAlignment = 0; break; default: break; @@ -153,16 +233,34 @@ } 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; + PointerSAAlignment = PointerMemSize; + DoubleSAAlignment = PointerMemSize; + FloatSAAlignment = 4; + LongSAAlignment = PointerMemSize; + IntSAAlignment = 4; + ShortSAAlignment = 2; + ByteSAAlignment = 1; + BoolSAAlignment = 1; + BoolStackAlignment = BoolSAAlignment; + ByteStackAlignment = ByteSAAlignment; + ShortStackAlignment = ShortSAAlignment; + IntStackAlignment = IntSAAlignment; + LongStackAlignment = LongSAAlignment; + FloatStackAlignment = FloatSAAlignment; + DoubleStackAlignment = DoubleSAAlignment; + PointerStackAlignment = PointerSAAlignment; + AggMinStackAlignment = 0; + BoolGlobalAlignment = BoolSAAlignment; + ByteGlobalAlignment = ByteSAAlignment; + ShortGlobalAlignment = ShortSAAlignment; + IntGlobalAlignment = IntSAAlignment; + LongGlobalAlignment = LongSAAlignment; + FloatGlobalAlignment = FloatSAAlignment; + DoubleGlobalAlignment = DoubleSAAlignment; + PointerGlobalAlignment = PointerSAAlignment; + AggMinGlobalAlignment = 0; } /// Layouts - The lazy cache of structure layout information maintained by @@ -195,14 +293,23 @@ 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) << ":" << (PointerSAAlignment * 8); + repr << "-d:" << (DoubleSAAlignment * 8) << ":" + << (DoubleStackAlignment * 8) << ":" << (DoubleGlobalAlignment * 8); + repr << "-f:" << (FloatSAAlignment * 8) << ":" + << (FloatStackAlignment * 8) << ":" << (FloatGlobalAlignment * 8); + repr << "-l:" << (LongSAAlignment * 8) << ":" + << (LongStackAlignment * 8) << ":" << (LongGlobalAlignment * 8); + repr << "-i:" << (IntSAAlignment * 8) << ":" + << (IntStackAlignment * 8) << ":" << (IntGlobalAlignment * 8); + repr << "-s:" << (ShortSAAlignment * 8) << ":" + << (ShortStackAlignment * 8) << ":" << (ShortGlobalAlignment * 8); + repr << "-b:" << (ByteSAAlignment * 8) << ":" + << (ByteStackAlignment * 8) << ":" << (ByteGlobalAlignment * 8); + repr << "-B:" << (BoolSAAlignment * 8) << ":" + << (BoolStackAlignment * 8) << ":" << (BoolGlobalAlignment * 8); + repr << "-A:" << (AggMinStackAlignment * 8) << ":" + << (AggMinGlobalAlignment * 8); return repr.str(); } @@ -237,41 +344,42 @@ -static inline void getTypeInfo(const Type *Ty, const TargetData *TD, - uint64_t &Size, unsigned char &Alignment) { +static inline void getTypeInfoStructArray(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->getByteSAAlignment(); } else if (BitWidth <= 16) { - Size = 2; Alignment = TD->getShortAlignment(); + Size = 2; Alignment = TD->getShortSAAlignment(); } else if (BitWidth <= 32) { - Size = 4; Alignment = TD->getIntAlignment(); + Size = 4; Alignment = TD->getIntSAAlignment(); } else if (BitWidth <= 64) { - Size = 8; Alignment = TD->getLongAlignment(); + Size = 8; Alignment = TD->getLongSAAlignment(); } 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->getByteSAAlignment(); return; + case Type::FloatTyID: Size = 4; Alignment = TD->getFloatSAAlignment(); return; + case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleSAAlignment(); return; case Type::LabelTyID: case Type::PointerTyID: - Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment(); + Size = TD->getPointerSize(); Alignment = TD->getPointerSAAlignment(); return; case Type::ArrayTyID: { const ArrayType *ATy = cast<ArrayType>(Ty); - getTypeInfo(ATy->getElementType(), TD, Size, Alignment); + getTypeInfoStructArray(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); + getTypeInfoStructArray(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 +400,166 @@ } } +static inline void getTypeInfoStack(const Type *Ty, const TargetData *TD, + uint64_t &Size, unsigned char &Alignment) { + assert(Ty->isSized() && "Cannot getTypeInfoStack() 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->getByteStackAlignment(); + } else if (BitWidth <= 16) { + Size = 2; Alignment = TD->getShortStackAlignment(); + } else if (BitWidth <= 32) { + Size = 4; Alignment = TD->getIntStackAlignment(); + } else if (BitWidth <= 64) { + Size = 8; Alignment = TD->getLongStackAlignment(); + } else + assert(0 && "Integer types > 64 bits not supported."); + return; + } + case Type::VoidTyID: + Size = 1; Alignment = TD->getByteStackAlignment(); + return; + case Type::FloatTyID: + Size = 4; Alignment = TD->getFloatStackAlignment(); + return; + case Type::DoubleTyID: + Size = 8; Alignment = TD->getDoubleStackAlignment(); + return; + case Type::LabelTyID: + case Type::PointerTyID: + Size = TD->getPointerSize(); Alignment = TD->getPointerStackAlignment(); + return; + case Type::ArrayTyID: { + const ArrayType *ATy = cast<ArrayType>(Ty); + getTypeInfoStack(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); + getTypeInfoStack(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->getAggMinStackAlignment()); + return; + } + + default: + assert(0 && "Bad type for getTypeInfoStack!!!"); + return; + } +} + +static inline void getTypeInfoGlobal(const Type *Ty, const TargetData *TD, + uint64_t &Size, unsigned char &Alignment) { + assert(Ty->isSized() && "Cannot getTypeInfoGlobal() 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->getByteGlobalAlignment(); + } else if (BitWidth <= 16) { + Size = 2; Alignment = TD->getShortGlobalAlignment(); + } else if (BitWidth <= 32) { + Size = 4; Alignment = TD->getIntGlobalAlignment(); + } else if (BitWidth <= 64) { + Size = 8; Alignment = TD->getLongGlobalAlignment(); + } else + assert(0 && "Integer types > 64 bits not supported."); + return; + } + case Type::VoidTyID: + Size = 1; Alignment = TD->getByteGlobalAlignment(); + return; + case Type::FloatTyID: + Size = 4; Alignment = TD->getFloatGlobalAlignment(); + return; + case Type::DoubleTyID: + Size = 8; Alignment = TD->getDoubleGlobalAlignment(); + return; + case Type::LabelTyID: + case Type::PointerTyID: + Size = TD->getPointerSize(); Alignment = TD->getPointerGlobalAlignment(); + return; + case Type::ArrayTyID: { + const ArrayType *ATy = cast<ArrayType>(Ty); + getTypeInfoGlobal(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); + getTypeInfoGlobal(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 global aggregate alignment: + const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty)); + Size = Layout->StructSize; + Alignment = std::max(Layout->StructAlignment, + (const unsigned int) TD->getAggMinGlobalAlignment()); + return; + } + + default: + assert(0 && "Bad type for getTypeInfoGlobal!!!"); + return; + } +} + + + uint64_t TargetData::getTypeSize(const Type *Ty) const { uint64_t Size; unsigned char Align; - getTypeInfo(Ty, this, Size, Align); + getTypeInfoStructArray(Ty, this, Size, Align); return Size; } -unsigned char TargetData::getTypeAlignment(const Type *Ty) const { +unsigned char TargetData::getTypeAlignmentStructArray(const Type *Ty) const { + uint64_t Size; + unsigned char Align; + getTypeInfoStructArray(Ty, this, Size, Align); + return Align; +} + +unsigned char TargetData::getTypeAlignmentStack(const Type *Ty) const { + uint64_t Size; + unsigned char Align; + getTypeInfoStack(Ty, this, Size, Align); + return Align; +} + +unsigned char TargetData::getTypeAlignmentGlobal(const Type *Ty) const { uint64_t Size; unsigned char Align; - getTypeInfo(Ty, this, Size, Align); + getTypeInfoGlobal(Ty, this, Size, Align); return Align; } unsigned char TargetData::getTypeAlignmentShift(const Type *Ty) const { - unsigned Align = getTypeAlignment(Ty); + unsigned Align = getTypeAlignmentStructArray(Ty); assert(!(Align & (Align-1)) && "Alignment is not a power of two!"); return Log2_32(Align); } --- old-llvm/lib/Target/X86/X86TargetMachine.cpp 2007-01-17 12:22:57.000000000 -0800 +++ new-llvm/lib/Target/X86/X86TargetMachine.cpp 2007-01-17 12:22:58.000000000 -0800 @@ -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-l:32") : - std::string("e-p:32:32-d:32-l:32")), + std::string("e-p:64:64-d:32:64:64-l:32") : + std::string("e-p:32:32-d:32:64:64-l:32")), FrameInfo(TargetFrameInfo::StackGrowsDown, Subtarget.getStackAlignment(), Subtarget.is64Bit() ? -8 : -4), InstrInfo(*this), JITInfo(*this), TLInfo(*this) { --- old-llvm/lib/Transforms/Scalar/InstructionCombining.cpp 2007-01-17 12:22:57.000000000 -0800 +++ new-llvm/lib/Transforms/Scalar/InstructionCombining.cpp 2007-01-17 12:22:58.000000000 -0800 @@ -5773,8 +5773,8 @@ 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->getTypeAlignmentStructArray(AllocElTy); + unsigned CastElTyAlign = TD->getTypeAlignmentStructArray(CastElTy); if (CastElTyAlign < AllocElTyAlign) return 0; // If the allocation has multiple uses, only promote it if we are strictly @@ -6872,18 +6872,22 @@ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) { unsigned Align = GV->getAlignment(); if (Align == 0 && TD) - Align = TD->getTypeAlignment(GV->getType()->getElementType()); + Align = TD->getTypeAlignmentGlobal(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->getTypeAlignmentStack(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->getTypeAlignmentStructArray(AI->getType()->getElementType()); + Align = + std::max(Align, + (unsigned)TD->getTypeAlignmentStructArray(Type::DoubleTy)); + Align = + std::max(Align, + (unsigned)TD->getTypeAlignmentStructArray(Type::Int64Ty)); } } return Align; @@ -6918,10 +6922,12 @@ 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->getTypeAlignmentStructArray(PtrTy->getElementType()) <= BaseAlignment) { const Type *GEPTy = GEPI->getType(); - return TD->getTypeAlignment(cast<PointerType>(GEPTy)->getElementType()); + const PointerType *GEPPtrTy = cast<PointerType>(GEPTy); + return TD->getTypeAlignmentStructArray(GEPPtrTy->getElementType()); } return 0; }
_______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits