aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-01-20 22:35:55 +0000
committerChris Lattner <sabre@nondot.org>2007-01-20 22:35:55 +0000
commit58092e35a3368e130438cbc793c8f9dce2e4fe0f (patch)
treec970c89150c10f0c2c19bc5670cd7df017ab0eae
parentc5633c235e94f69c6a77e894bcc84d8ba71106f0 (diff)
Teach TargetData to handle 'preferred' alignment for each target, and use
these alignment amounts to align scalars when we can. Patch by Scott Michel! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33409 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/TargetData.h181
-rw-r--r--lib/CodeGen/ELFWriter.cpp2
-rw-r--r--lib/CodeGen/MachOWriter.cpp2
-rw-r--r--lib/CodeGen/MachineFunction.cpp3
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp13
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp15
-rw-r--r--lib/ExecutionEngine/JIT/JIT.cpp2
-rw-r--r--lib/Target/Sparc/SparcAsmPrinter.cpp4
-rw-r--r--lib/Target/TargetData.cpp243
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp4
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp24
-rw-r--r--lib/VMCore/ValueTypes.cpp13
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") :</