diff options
-rw-r--r-- | include/llvm/Target/TargetData.h | 181 | ||||
-rw-r--r-- | lib/CodeGen/ELFWriter.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/MachOWriter.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/MachineFunction.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 13 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 15 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JIT.cpp | 2 | ||||
-rw-r--r-- | lib/Target/Sparc/SparcAsmPrinter.cpp | 4 | ||||
-rw-r--r-- | lib/Target/TargetData.cpp | 243 | ||||
-rw-r--r-- | lib/Target/X86/X86TargetMachine.cpp | 4 | ||||
-rw-r--r-- | lib/Transforms/Scalar/InstructionCombining.cpp | 24 | ||||
-rw-r--r-- | lib/VMCore/ValueTypes.cpp | 13 |
12 files changed, 365 insertions, 141 deletions
diff --git a/include/llvm/Target/TargetData.h b/include/llvm/Target/TargetData.h index aaae41c17c..42a40dd6c4 100644 --- a/include/llvm/Target/TargetData.h +++ b/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/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp index 4f988070fd..3b9653740c 100644 --- a/lib/CodeGen/ELFWriter.cpp +++ b/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/lib/CodeGen/MachOWriter.cpp b/lib/CodeGen/MachOWriter.cpp index 64e11010b3..82dcf1861b 100644 --- a/lib/CodeGen/MachOWriter.cpp +++ b/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/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index d26b3258fe..0cba1567e1 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/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/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index d83dcc4d50..c8804e907a 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/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/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 7e6a75d772..e8d58453c2 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/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/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp index 7fd62cc6e0..c88e393d6a 100644 --- a/lib/ExecutionEngine/JIT/JIT.cpp +++ b/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/lib/Target/Sparc/SparcAsmPrinter.cpp b/lib/Target/Sparc/SparcAsmPrinter.cpp index 3bb003ad3d..d0d34fca38 100644 --- a/lib/Target/Sparc/SparcAsmPrinter.cpp +++ b/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/lib/Target/TargetData.cpp b/lib/Target/TargetData.cpp index c0b0670b96..b1fe43dee8 100644 --- a/lib/Target/TargetData.cpp +++ b/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/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp index d8283a5f22..17bc7b14eb 100644 --- a/lib/Target/X86/X86TargetMachine.cpp +++ b/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/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 414ae794b1..04b06d28aa 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/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->ge |