mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-03 13:31:05 +00:00
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
This commit is contained in:
parent
c5633c235e
commit
58092e35a3
@ -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).
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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 {
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
getTypeInfo(Ty, this, Size, Align);
|
||||
getTypeInfoABI(Ty, this, Size, Align);
|
||||
return Align;
|
||||
}
|
||||
|
||||
unsigned char TargetData::getTypeAlignmentPref(const Type *Ty) const {
|
||||
uint64_t Size;
|
||||
unsigned char 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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -5779,8 +5779,8 @@ Instruction *InstCombiner::PromoteCastOfAllocation(CastInst &CI,
|
||||
const Type *CastElTy = PTy->getElementType();
|
||||
if (!AllocElTy->isSized() || !CastElTy->isSized()) return 0;
|
||||
|
||||
unsigned AllocElTyAlign = TD->getTypeAlignment(AllocElTy);
|
||||
unsigned CastElTyAlign = TD->getTypeAlignment(CastElTy);
|
||||
unsigned AllocElTyAlign = TD->getTypeAlignmentABI(AllocElTy);
|
||||
unsigned CastElTyAlign = TD->getTypeAlignmentABI(CastElTy);
|
||||
if (CastElTyAlign < AllocElTyAlign) return 0;
|
||||
|
||||
// If the allocation has multiple uses, only promote it if we are strictly
|
||||
@ -6878,18 +6878,22 @@ static unsigned GetKnownAlignment(Value *V, TargetData *TD) {
|
||||
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
|
||||
unsigned Align = GV->getAlignment();
|
||||
if (Align == 0 && TD)
|
||||
Align = TD->getTypeAlignment(GV->getType()->getElementType());
|
||||
Align = TD->getTypeAlignmentPref(GV->getType()->getElementType());
|
||||
return Align;
|
||||
} else if (AllocationInst *AI = dyn_cast<AllocationInst>(V)) {
|
||||
unsigned Align = AI->getAlignment();
|
||||
if (Align == 0 && TD) {
|
||||
if (isa<AllocaInst>(AI))
|
||||
Align = TD->getTypeAlignment(AI->getType()->getElementType());
|
||||
Align = TD->getTypeAlignmentPref(AI->getType()->getElementType());
|
||||
else if (isa<MallocInst>(AI)) {
|
||||
// Malloc returns maximally aligned memory.
|
||||
Align = TD->getTypeAlignment(AI->getType()->getElementType());
|
||||
Align = std::max(Align, (unsigned)TD->getTypeAlignment(Type::DoubleTy));
|
||||
Align = std::max(Align, (unsigned)TD->getTypeAlignment(Type::Int64Ty));
|
||||
Align = TD->getTypeAlignmentABI(AI->getType()->getElementType());
|
||||
Align =
|
||||
std::max(Align,
|
||||
(unsigned)TD->getTypeAlignmentABI(Type::DoubleTy));
|
||||
Align =
|
||||
std::max(Align,
|
||||
(unsigned)TD->getTypeAlignmentABI(Type::Int64Ty));
|
||||
}
|
||||
}
|
||||
return Align;
|
||||
@ -6924,10 +6928,12 @@ static unsigned GetKnownAlignment(Value *V, TargetData *TD) {
|
||||
if (!TD) return 0;
|
||||
|
||||
const Type *BasePtrTy = GEPI->getOperand(0)->getType();
|
||||
if (TD->getTypeAlignment(cast<PointerType>(BasePtrTy)->getElementType())
|
||||
const PointerType *PtrTy = cast<PointerType>(BasePtrTy);
|
||||
if (TD->getTypeAlignmentABI(PtrTy->getElementType())
|
||||
<= BaseAlignment) {
|
||||
const Type *GEPTy = GEPI->getType();
|
||||
return TD->getTypeAlignment(cast<PointerType>(GEPTy)->getElementType());
|
||||
const PointerType *GEPPtrTy = cast<PointerType>(GEPTy);
|
||||
return TD->getTypeAlignmentABI(GEPPtrTy->getElementType());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -82,8 +82,8 @@ MVT::ValueType MVT::getVectorType(ValueType VT, unsigned NumElements) {
|
||||
}
|
||||
|
||||
/// MVT::getTypeForValueType - This method returns an LLVM type corresponding
|
||||
/// to the specified ValueType. For integer types, this returns an unsigned
|
||||
/// type. Note that this will abort for types that cannot be represented.
|
||||
/// to the specified ValueType. Note that this will abort for types that cannot
|
||||
/// be represented.
|
||||
const Type *MVT::getTypeForValueType(MVT::ValueType VT) {
|
||||
switch (VT) {
|
||||
default: assert(0 && "ValueType does not correspond to LLVM type!");
|
||||
@ -95,5 +95,14 @@ const Type *MVT::getTypeForValueType(MVT::ValueType VT) {
|
||||
case MVT::i64: return Type::Int64Ty;
|
||||
case MVT::f32: return Type::FloatTy;
|
||||
case MVT::f64: return Type::DoubleTy;
|
||||
case MVT::v8i8: return PackedType::get(Type::Int8Ty, 8);
|
||||
case MVT::v4i16: return PackedType::get(Type::Int16Ty, 4);
|
||||
case MVT::v2i32: return PackedType::get(Type::Int32Ty, 2);
|
||||
case MVT::v16i8: return PackedType::get(Type::Int8Ty, 16);
|
||||
case MVT::v8i16: return PackedType::get(Type::Int16Ty, 8);
|
||||
case MVT::v4i32: return PackedType::get(Type::Int32Ty, 4);
|
||||
case MVT::v2i64: return PackedType::get(Type::Int64Ty, 2);
|
||||
case MVT::v4f32: return PackedType::get(Type::FloatTy, 4);
|
||||
case MVT::v2f64: return PackedType::get(Type::DoubleTy, 2);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user