mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-22 03:39:03 +00:00
Generalize TargetData strings, to support more interesting forms of data.
Patch by Scott Michel. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34266 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
879dfe1c9c
commit
d2b7cec527
@ -22,6 +22,8 @@
|
|||||||
|
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/DataTypes.h"
|
#include "llvm/Support/DataTypes.h"
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -31,45 +33,96 @@ class StructType;
|
|||||||
class StructLayout;
|
class StructLayout;
|
||||||
class GlobalVariable;
|
class GlobalVariable;
|
||||||
|
|
||||||
|
/// Enum used to categorize the alignment types stored by TargetAlignElem
|
||||||
|
enum AlignTypeEnum {
|
||||||
|
INTEGER_ALIGN = 'i', ///< Integer type alignment
|
||||||
|
PACKED_ALIGN = 'v', ///< Vector type alignment
|
||||||
|
FLOAT_ALIGN = 'f', ///< Floating point type alignment
|
||||||
|
AGGREGATE_ALIGN = 'a' ///< Aggregate alignment
|
||||||
|
};
|
||||||
|
/// Target alignment element.
|
||||||
|
///
|
||||||
|
/// Stores the alignment data associated with a given alignment type (pointer,
|
||||||
|
/// integer, packed/vector, float) and type bit width.
|
||||||
|
///
|
||||||
|
/// @note The unusual order of elements in the structure attempts to reduce
|
||||||
|
/// padding and make the structure slightly more cache friendly.
|
||||||
|
struct TargetAlignElem {
|
||||||
|
unsigned char AlignType; //< Alignment type (AlignTypeEnum)
|
||||||
|
unsigned char ABIAlign; //< ABI alignment for this type/bitw
|
||||||
|
unsigned char PrefAlign; //< Pref. alignment for this type/bitw
|
||||||
|
short TypeBitWidth; //< Type bit width
|
||||||
|
|
||||||
|
/// Initializer
|
||||||
|
static TargetAlignElem get(AlignTypeEnum align_type, unsigned char abi_align,
|
||||||
|
unsigned char pref_align, short bit_width);
|
||||||
|
/// Less-than predicate
|
||||||
|
bool operator<(const TargetAlignElem &rhs) const;
|
||||||
|
/// Equality predicate
|
||||||
|
bool operator==(const TargetAlignElem &rhs) const;
|
||||||
|
/// output stream operator
|
||||||
|
std::ostream &dump(std::ostream &os) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! TargetAlignElem output stream inserter
|
||||||
|
/*!
|
||||||
|
@sa TargetAlignElem::dump()
|
||||||
|
*/
|
||||||
|
std::ostream &operator<<(std::ostream &os, const TargetAlignElem &elem);
|
||||||
|
|
||||||
class TargetData : public ImmutablePass {
|
class TargetData : public ImmutablePass {
|
||||||
bool LittleEndian; // Defaults to false
|
private:
|
||||||
|
bool LittleEndian; ///< Defaults to false
|
||||||
|
unsigned char PointerMemSize; ///< Pointer size in bytes
|
||||||
|
unsigned char PointerABIAlign; ///< Pointer ABI alignment
|
||||||
|
unsigned char PointerPrefAlign; ///< Pointer preferred global alignment
|
||||||
|
|
||||||
// ABI alignments
|
//! Where the primitive type alignment data is stored.
|
||||||
unsigned char BoolABIAlignment; // Defaults to 1 byte
|
/*!
|
||||||
unsigned char ByteABIAlignment; // Defaults to 1 byte
|
@sa init().
|
||||||
unsigned char ShortABIAlignment; // Defaults to 2 bytes
|
@note Could support multiple size pointer alignments, e.g., 32-bit pointers
|
||||||
unsigned char IntABIAlignment; // Defaults to 4 bytes
|
vs. 64-bit pointers by extending TargetAlignment, but for now, we don't.
|
||||||
unsigned char LongABIAlignment; // Defaults to 8 bytes
|
*/
|
||||||
unsigned char FloatABIAlignment; // Defaults to 4 bytes
|
SmallVector<TargetAlignElem, 16> Alignments;
|
||||||
unsigned char DoubleABIAlignment; // Defaults to 8 bytes
|
//! Alignment iterator shorthand
|
||||||
unsigned char PointerMemSize; // Defaults to 8 bytes
|
typedef SmallVector<TargetAlignElem, 16>::iterator align_iterator;
|
||||||
unsigned char PointerABIAlignment; // Defaults to 8 bytes
|
//! Constant alignment iterator shorthand
|
||||||
|
typedef SmallVector<TargetAlignElem, 16>::const_iterator align_const_iterator;
|
||||||
|
//! Invalid alignment.
|
||||||
|
/*!
|
||||||
|
This member is a signal that a requested alignment type and bit width were
|
||||||
|
not found in the SmallVector.
|
||||||
|
*/
|
||||||
|
static const TargetAlignElem InvalidAlignmentElem;
|
||||||
|
|
||||||
// Preferred stack/global type alignments
|
//! Set/initialize target alignments
|
||||||
unsigned char BoolPrefAlignment; // Defaults to BoolABIAlignment
|
void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
|
||||||
unsigned char BytePrefAlignment; // Defaults to ByteABIAlignment
|
unsigned char pref_align, short bit_width);
|
||||||
unsigned char ShortPrefAlignment; // Defaults to ShortABIAlignment
|
//! Get TargetAlignElem from alignment type and bit width
|
||||||
unsigned char IntPrefAlignment; // Defaults to IntABIAlignment
|
const TargetAlignElem &getAlignment(AlignTypeEnum, short) const;
|
||||||
unsigned char LongPrefAlignment; // Defaults to LongABIAlignment
|
//! Internal helper method that returns requested alignment for type.
|
||||||
unsigned char FloatPrefAlignment; // Defaults to FloatABIAlignment
|
unsigned char getAlignment(const Type *Ty, bool abi_or_pref) const;
|
||||||
unsigned char DoublePrefAlignment; // Defaults to DoubleABIAlignment
|
|
||||||
unsigned char PointerPrefAlignment; // Defaults to PointerABIAlignment
|
/// Valid alignment predicate.
|
||||||
unsigned char AggMinPrefAlignment; // Defaults to 0 bytes
|
///
|
||||||
|
/// Predicate that tests a TargetAlignElem reference returned by get() against
|
||||||
|
/// InvalidAlignmentElem.
|
||||||
|
inline bool validAlignment(const TargetAlignElem &align) const {
|
||||||
|
return (&align != &InvalidAlignmentElem);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Default ctor - This has to exist, because this is a pass, but it should
|
/// Default ctor.
|
||||||
/// never be used.
|
///
|
||||||
|
/// @note This has to exist, because this is a pass, but it should never be
|
||||||
|
/// used.
|
||||||
TargetData() {
|
TargetData() {
|
||||||
assert(0 && "ERROR: Bad TargetData ctor used. "
|
assert(0 && "ERROR: Bad TargetData ctor used. "
|
||||||
"Tool did not specify a TargetData to use?");
|
"Tool did not specify a TargetData to use?");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a TargetData from a string of the following format:
|
/// Constructs a TargetData from a specification string. See init().
|
||||||
/// "E-p:64:64-d:64-f:32-l:64-i:32-s:16-b:8-B:8"
|
|
||||||
/// The above string is considered the default, and any values not specified
|
|
||||||
/// in the string will be assumed to be as above, with the caveat that unspecified
|
|
||||||
/// values are always assumed to be smaller than the size of a pointer.
|
|
||||||
TargetData(const std::string &TargetDescription) {
|
TargetData(const std::string &TargetDescription) {
|
||||||
init(TargetDescription);
|
init(TargetDescription);
|
||||||
}
|
}
|
||||||
@ -80,143 +133,36 @@ public:
|
|||||||
TargetData(const TargetData &TD) :
|
TargetData(const TargetData &TD) :
|
||||||
ImmutablePass(),
|
ImmutablePass(),
|
||||||
LittleEndian(TD.isLittleEndian()),
|
LittleEndian(TD.isLittleEndian()),
|
||||||
BoolABIAlignment(TD.getBoolABIAlignment()),
|
PointerMemSize(TD.PointerMemSize),
|
||||||
ByteABIAlignment(TD.getByteABIAlignment()),
|
PointerABIAlign(TD.PointerABIAlign),
|
||||||
ShortABIAlignment(TD.getShortABIAlignment()),
|
PointerPrefAlign(TD.PointerPrefAlign),
|
||||||
IntABIAlignment(TD.getIntABIAlignment()),
|
Alignments(TD.Alignments)
|
||||||
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
|
~TargetData(); // Not virtual, do not subclass this class
|
||||||
|
|
||||||
/// Parse a target data layout string and initialize TargetData members.
|
//! Parse a target data layout string and initialize TargetData alignments.
|
||||||
///
|
|
||||||
/// 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 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>
|
|
||||||
/// <em>E</em> specifies big endian architecture (1234) [default]<br>
|
|
||||||
/// <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]:[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>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);
|
void init(const std::string &TargetDescription);
|
||||||
|
|
||||||
|
|
||||||
/// Target endianness...
|
/// Target endianness...
|
||||||
bool isLittleEndian() const { return LittleEndian; }
|
bool isLittleEndian() const { return LittleEndian; }
|
||||||
bool isBigEndian() const { return !LittleEndian; }
|
bool isBigEndian() const { return !LittleEndian; }
|
||||||
|
|
||||||
/// 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
|
/// getStringRepresentation - Return the string representation of the
|
||||||
/// TargetData. This representation is in the same format accepted by the
|
/// TargetData. This representation is in the same format accepted by the
|
||||||
/// string constructor above.
|
/// string constructor above.
|
||||||
std::string getStringRepresentation() const;
|
std::string getStringRepresentation() const;
|
||||||
|
/// Target pointer alignment
|
||||||
|
unsigned char getPointerABIAlignment() const { return PointerABIAlign; }
|
||||||
|
/// Return target's alignment for stack-based pointers
|
||||||
|
unsigned char getPointerPrefAlignment() const { return PointerPrefAlign; }
|
||||||
|
/// Target pointer size
|
||||||
|
unsigned char getPointerSize() const { return PointerMemSize; }
|
||||||
|
/// Target pointer size, in bits
|
||||||
|
unsigned char getPointerSizeInBits() const { return 8*PointerMemSize; }
|
||||||
|
|
||||||
/// getTypeSize - Return the number of bytes necessary to hold the specified
|
/// getTypeSize - Return the number of bytes necessary to hold the specified
|
||||||
/// type.
|
/// type.
|
||||||
///
|
|
||||||
uint64_t getTypeSize(const Type *Ty) const;
|
uint64_t getTypeSize(const Type *Ty) const;
|
||||||
|
|
||||||
/// getTypeSizeInBits - Return the number of bytes necessary to hold the
|
/// getTypeSizeInBits - Return the number of bytes necessary to hold the
|
||||||
@ -225,11 +171,11 @@ public:
|
|||||||
|
|
||||||
/// getTypeAlignmentABI - Return the minimum ABI-required alignment for the
|
/// getTypeAlignmentABI - Return the minimum ABI-required alignment for the
|
||||||
/// specified type.
|
/// specified type.
|
||||||
unsigned char getTypeAlignmentABI(const Type *Ty) const;
|
unsigned char getABITypeAlignment(const Type *Ty) const;
|
||||||
|
|
||||||
/// getTypeAlignmentPref - Return the preferred stack/global alignment for
|
/// getTypeAlignmentPref - Return the preferred stack/global alignment for
|
||||||
/// the specified type.
|
/// the specified type.
|
||||||
unsigned char getTypeAlignmentPref(const Type *Ty) const;
|
unsigned char getPrefTypeAlignment(const Type *Ty) const;
|
||||||
|
|
||||||
/// getPreferredTypeAlignmentShift - Return the preferred alignment for the
|
/// getPreferredTypeAlignmentShift - Return the preferred alignment for the
|
||||||
/// specified type, returned as log2 of the value (a shift amount).
|
/// specified type, returned as log2 of the value (a shift amount).
|
||||||
|
@ -255,7 +255,7 @@ void ELFWriter::EmitGlobal(GlobalVariable *GV) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Type *GVType = (const Type*)GV->getType();
|
const Type *GVType = (const Type*)GV->getType();
|
||||||
unsigned Align = TM.getTargetData()->getTypeAlignmentPref(GVType);
|
unsigned Align = TM.getTargetData()->getPrefTypeAlignment(GVType);
|
||||||
unsigned Size = TM.getTargetData()->getTypeSize(GVType);
|
unsigned Size = TM.getTargetData()->getTypeSize(GVType);
|
||||||
|
|
||||||
// If this global has a zero initializer, it is part of the .bss or common
|
// If this global has a zero initializer, it is part of the .bss or common
|
||||||
|
@ -147,7 +147,7 @@ void MachOCodeEmitter::startFunction(MachineFunction &MF) {
|
|||||||
|
|
||||||
// Align the output buffer to the appropriate alignment, power of 2.
|
// Align the output buffer to the appropriate alignment, power of 2.
|
||||||
unsigned FnAlign = F->getAlignment();
|
unsigned FnAlign = F->getAlignment();
|
||||||
unsigned TDAlign = TD->getTypeAlignmentPref(F->getType());
|
unsigned TDAlign = TD->getPrefTypeAlignment(F->getType());
|
||||||
unsigned Align = Log2_32(std::max(FnAlign, TDAlign));
|
unsigned Align = Log2_32(std::max(FnAlign, TDAlign));
|
||||||
assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
|
assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
|
||||||
|
|
||||||
@ -332,7 +332,7 @@ void MachOWriter::AddSymbolToSection(MachOSection *Sec, GlobalVariable *GV) {
|
|||||||
unsigned Size = TM.getTargetData()->getTypeSize(Ty);
|
unsigned Size = TM.getTargetData()->getTypeSize(Ty);
|
||||||
unsigned Align = GV->getAlignment();
|
unsigned Align = GV->getAlignment();
|
||||||
if (Align == 0)
|
if (Align == 0)
|
||||||
Align = TM.getTargetData()->getTypeAlignmentPref(Ty);
|
Align = TM.getTargetData()->getPrefTypeAlignment(Ty);
|
||||||
|
|
||||||
MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TM);
|
MachOSym Sym(GV, Mang->getValueName(GV), Sec->Index, TM);
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/DerivedTypes.h"
|
||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
#include "llvm/CodeGen/MachineInstr.h"
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
#include "llvm/CodeGen/SSARegMap.h"
|
#include "llvm/CodeGen/SSARegMap.h"
|
||||||
@ -123,7 +124,7 @@ MachineFunction::MachineFunction(const Function *F,
|
|||||||
const TargetData &TD = *TM.getTargetData();
|
const TargetData &TD = *TM.getTargetData();
|
||||||
bool IsPic = TM.getRelocationModel() == Reloc::PIC_;
|
bool IsPic = TM.getRelocationModel() == Reloc::PIC_;
|
||||||
unsigned EntrySize = IsPic ? 4 : TD.getPointerSize();
|
unsigned EntrySize = IsPic ? 4 : TD.getPointerSize();
|
||||||
unsigned Alignment = IsPic ? TD.getIntABIAlignment()
|
unsigned Alignment = IsPic ? TD.getABITypeAlignment(Type::Int32Ty)
|
||||||
: TD.getPointerABIAlignment();
|
: TD.getPointerABIAlignment();
|
||||||
JumpTableInfo = new MachineJumpTableInfo(EntrySize, Alignment);
|
JumpTableInfo = new MachineJumpTableInfo(EntrySize, Alignment);
|
||||||
|
|
||||||
|
@ -3056,7 +3056,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||||||
// new ones, as reuse may inhibit scheduling.
|
// new ones, as reuse may inhibit scheduling.
|
||||||
const Type *Ty = MVT::getTypeForValueType(ExtraVT);
|
const Type *Ty = MVT::getTypeForValueType(ExtraVT);
|
||||||
unsigned TySize = (unsigned)TLI.getTargetData()->getTypeSize(Ty);
|
unsigned TySize = (unsigned)TLI.getTargetData()->getTypeSize(Ty);
|
||||||
unsigned Align = TLI.getTargetData()->getTypeAlignmentPref(Ty);
|
unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty);
|
||||||
MachineFunction &MF = DAG.getMachineFunction();
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
int SSFI =
|
int SSFI =
|
||||||
MF.getFrameInfo()->CreateStackObject((unsigned)TySize, Align);
|
MF.getFrameInfo()->CreateStackObject((unsigned)TySize, Align);
|
||||||
@ -3979,7 +3979,7 @@ SDOperand SelectionDAGLegalize::CreateStackTemporary(MVT::ValueType VT) {
|
|||||||
MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
|
MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
|
||||||
unsigned ByteSize = MVT::getSizeInBits(VT)/8;
|
unsigned ByteSize = MVT::getSizeInBits(VT)/8;
|
||||||
const Type *Ty = MVT::getTypeForValueType(VT);
|
const Type *Ty = MVT::getTypeForValueType(VT);
|
||||||
unsigned StackAlign = (unsigned)TLI.getTargetData()->getTypeAlignmentPref(Ty);
|
unsigned StackAlign = (unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty);
|
||||||
int FrameIdx = FrameInfo->CreateStackObject(ByteSize, StackAlign);
|
int FrameIdx = FrameInfo->CreateStackObject(ByteSize, StackAlign);
|
||||||
return DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
|
return DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
|
||||||
}
|
}
|
||||||
@ -4289,7 +4289,7 @@ SDOperand SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
|
|||||||
MachineFunction &MF = DAG.getMachineFunction();
|
MachineFunction &MF = DAG.getMachineFunction();
|
||||||
const Type *F64Type = MVT::getTypeForValueType(MVT::f64);
|
const Type *F64Type = MVT::getTypeForValueType(MVT::f64);
|
||||||
unsigned StackAlign =
|
unsigned StackAlign =
|
||||||
(unsigned)TLI.getTargetData()->getTypeAlignmentPref(F64Type);
|
(unsigned)TLI.getTargetData()->getPrefTypeAlignment(F64Type);
|
||||||
int SSFI = MF.getFrameInfo()->CreateStackObject(8, StackAlign);
|
int SSFI = MF.getFrameInfo()->CreateStackObject(8, StackAlign);
|
||||||
// get address of 8 byte buffer
|
// get address of 8 byte buffer
|
||||||
SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
|
SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
|
||||||
|
@ -244,7 +244,7 @@ FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli,
|
|||||||
const Type *Ty = AI->getAllocatedType();
|
const Type *Ty = AI->getAllocatedType();
|
||||||
uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
|
uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
|
||||||
unsigned Align =
|
unsigned Align =
|
||||||
std::max((unsigned)TLI.getTargetData()->getTypeAlignmentPref(Ty),
|
std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty),
|
||||||
AI->getAlignment());
|
AI->getAlignment());
|
||||||
|
|
||||||
TySize *= CUI->getZExtValue(); // Get total allocated size.
|
TySize *= CUI->getZExtValue(); // Get total allocated size.
|
||||||
@ -1733,7 +1733,7 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) {
|
|||||||
const Type *Ty = I.getAllocatedType();
|
const Type *Ty = I.getAllocatedType();
|
||||||
uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
|
uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
|
||||||
unsigned Align =
|
unsigned Align =
|
||||||
std::max((unsigned)TLI.getTargetData()->getTypeAlignmentPref(Ty),
|
std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty),
|
||||||
I.getAlignment());
|
I.getAlignment());
|
||||||
|
|
||||||
SDOperand AllocSize = getValue(I.getArraySize());
|
SDOperand AllocSize = getValue(I.getArraySize());
|
||||||
@ -2934,7 +2934,7 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||||||
bool isInReg = FTy->paramHasAttr(j, FunctionType::InRegAttribute);
|
bool isInReg = FTy->paramHasAttr(j, FunctionType::InRegAttribute);
|
||||||
bool isSRet = FTy->paramHasAttr(j, FunctionType::StructRetAttribute);
|
bool isSRet = FTy->paramHasAttr(j, FunctionType::StructRetAttribute);
|
||||||
unsigned OriginalAlignment =
|
unsigned OriginalAlignment =
|
||||||
getTargetData()->getTypeAlignmentABI(I->getType());
|
getTargetData()->getABITypeAlignment(I->getType());
|
||||||
// Flags[31:27] -> OriginalAlignment
|
// Flags[31:27] -> OriginalAlignment
|
||||||
// Flags[2] -> isSRet
|
// Flags[2] -> isSRet
|
||||||
// Flags[1] -> isInReg
|
// Flags[1] -> isInReg
|
||||||
@ -3120,7 +3120,7 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||||||
bool isInReg = Args[i].isInReg;
|
bool isInReg = Args[i].isInReg;
|
||||||
bool isSRet = Args[i].isSRet;
|
bool isSRet = Args[i].isSRet;
|
||||||
unsigned OriginalAlignment =
|
unsigned OriginalAlignment =
|
||||||
getTargetData()->getTypeAlignmentABI(Args[i].Ty);
|
getTargetData()->getABITypeAlignment(Args[i].Ty);
|
||||||
// Flags[31:27] -> OriginalAlignment
|
// Flags[31:27] -> OriginalAlignment
|
||||||
// Flags[2] -> isSRet
|
// Flags[2] -> isSRet
|
||||||
// Flags[1] -> isInReg
|
// Flags[1] -> isInReg
|
||||||
|
@ -338,7 +338,7 @@ void *JIT::getOrEmitGlobalVariable(const GlobalVariable *GV) {
|
|||||||
// compilation.
|
// compilation.
|
||||||
const Type *GlobalType = GV->getType()->getElementType();
|
const Type *GlobalType = GV->getType()->getElementType();
|
||||||
size_t S = getTargetData()->getTypeSize(GlobalType);
|
size_t S = getTargetData()->getTypeSize(GlobalType);
|
||||||
size_t A = getTargetData()->getTypeAlignmentPref(GlobalType);
|
size_t A = getTargetData()->getPrefTypeAlignment(GlobalType);
|
||||||
if (A <= 8) {
|
if (A <= 8) {
|
||||||
Ptr = malloc(S);
|
Ptr = malloc(S);
|
||||||
} else {
|
} else {
|
||||||
|
@ -37,12 +37,14 @@ ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS)
|
|||||||
DataLayout(Subtarget.isAPCS_ABI() ?
|
DataLayout(Subtarget.isAPCS_ABI() ?
|
||||||
// APCS ABI
|
// APCS ABI
|
||||||
(Subtarget.isThumb() ?
|
(Subtarget.isThumb() ?
|
||||||
std::string("e-p:32:32-d:32:32-l:32:32-s:16:32-b:8:32-B:8:32-A:32") :
|
std::string("e-p:32:32-f64:32:32-i64:32:32-"
|
||||||
std::string("e-p:32:32-d:32:32-l:32:32")) :
|
"i16:16:32-i8:8:32-i1:8:32-a:0:32") :
|
||||||
|
std::string("e-p:32:32-f64:32:32-i64:32:32")) :
|
||||||
// AAPCS ABI
|
// AAPCS ABI
|
||||||
(Subtarget.isThumb() ?
|
(Subtarget.isThumb() ?
|
||||||
std::string("e-p:32:32-d:64:64-l:64:64-s:16:32-b:8:32-B:8:32-A:32") :
|
std::string("e-p:32:32-f64:64:64-i64:64:64-"
|
||||||
std::string("e-p:32:32-d:64:64-l:64:64"))),
|
"i16:16:32-i8:8:32-i1:8:32-a:0:32") :
|
||||||
|
std::string("e-p:32:32-f64:64:64-i64:64:64"))),
|
||||||
InstrInfo(Subtarget),
|
InstrInfo(Subtarget),
|
||||||
FrameInfo(Subtarget) {}
|
FrameInfo(Subtarget) {}
|
||||||
|
|
||||||
|
@ -104,8 +104,8 @@ public:
|
|||||||
/// getTargetDataString - Return the pointer size and type alignment
|
/// getTargetDataString - Return the pointer size and type alignment
|
||||||
/// properties of this subtarget.
|
/// properties of this subtarget.
|
||||||
const char *getTargetDataString() const {
|
const char *getTargetDataString() const {
|
||||||
return isPPC64() ? "E-p:64:64-d:32:64-l:32:64"
|
return isPPC64() ? "E-p:64:64-f64:32:64-i64:32:64"
|
||||||
: "E-p:32:32-d:32:64-l:32:64";
|
: "E-p:32:32-f64:32:64-i64:32:64";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isPPC64 - Return true if we are generating code for 64-bit pointer mode.
|
/// isPPC64 - Return true if we are generating code for 64-bit pointer mode.
|
||||||
|
@ -229,7 +229,7 @@ bool SparcAsmPrinter::doFinalization(Module &M) {
|
|||||||
std::string name = Mang->getValueName(I);
|
std::string name = Mang->getValueName(I);
|
||||||
Constant *C = I->getInitializer();
|
Constant *C = I->getInitializer();
|
||||||
unsigned Size = TD->getTypeSize(C->getType());
|
unsigned Size = TD->getTypeSize(C->getType());
|
||||||
unsigned Align = TD->getTypeAlignmentPref(C->getType());
|
unsigned Align = TD->getPrefTypeAlignment(C->getType());
|
||||||
|
|
||||||
if (C->isNullValue() &&
|
if (C->isNullValue() &&
|
||||||
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
|
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
|
||||||
|
@ -36,12 +36,6 @@ namespace {
|
|||||||
RegisterPass<TargetData> X("targetdata", "Target Data Layout");
|
RegisterPass<TargetData> X("targetdata", "Target Data Layout");
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// Support for StructLayout
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -54,11 +48,10 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
|
|||||||
// Loop over each of the elements, placing them in memory...
|
// Loop over each of the elements, placing them in memory...
|
||||||
for (unsigned i = 0, e = NumElements; i != e; ++i) {
|
for (unsigned i = 0, e = NumElements; i != e; ++i) {
|
||||||
const Type *Ty = ST->getElementType(i);
|
const Type *Ty = ST->getElementType(i);
|
||||||
unsigned char A;
|
|
||||||
unsigned TyAlign;
|
unsigned TyAlign;
|
||||||
uint64_t TySize;
|
uint64_t TySize;
|
||||||
getTypeInfoABI(Ty, &TD, TySize, A);
|
TyAlign = (unsigned) TD.getABITypeAlignment(Ty);
|
||||||
TyAlign = ST->isPacked() ? 1 : A;
|
TySize = (unsigned) TD.getTypeSize(Ty);
|
||||||
|
|
||||||
// Add padding if necessary to make the data element aligned properly...
|
// Add padding if necessary to make the data element aligned properly...
|
||||||
if (StructSize % TyAlign != 0)
|
if (StructSize % TyAlign != 0)
|
||||||
@ -95,39 +88,127 @@ unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
|
|||||||
return SI-&MemberOffsets[0];
|
return SI-&MemberOffsets[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// TargetAlignElem, TargetAlign support
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
TargetAlignElem
|
||||||
|
TargetAlignElem::get(AlignTypeEnum align_type, unsigned char abi_align,
|
||||||
|
unsigned char pref_align, short bit_width)
|
||||||
|
{
|
||||||
|
TargetAlignElem retval;
|
||||||
|
retval.AlignType = align_type;
|
||||||
|
retval.ABIAlign = abi_align;
|
||||||
|
retval.PrefAlign = pref_align;
|
||||||
|
retval.TypeBitWidth = bit_width;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TargetAlignElem::operator<(const TargetAlignElem &rhs) const
|
||||||
|
{
|
||||||
|
return ((AlignType < rhs.AlignType)
|
||||||
|
|| (AlignType == rhs.AlignType && TypeBitWidth < rhs.TypeBitWidth));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
TargetAlignElem::operator==(const TargetAlignElem &rhs) const
|
||||||
|
{
|
||||||
|
return (AlignType == rhs.AlignType
|
||||||
|
&& ABIAlign == rhs.ABIAlign
|
||||||
|
&& PrefAlign == rhs.PrefAlign
|
||||||
|
&& TypeBitWidth == rhs.TypeBitWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &
|
||||||
|
TargetAlignElem::dump(std::ostream &os) const
|
||||||
|
{
|
||||||
|
return os << AlignType
|
||||||
|
<< TypeBitWidth
|
||||||
|
<< ":" << (int) (ABIAlign * 8)
|
||||||
|
<< ":" << (int) (PrefAlign * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream &
|
||||||
|
llvm::operator<<(std::ostream &os, const TargetAlignElem &elem)
|
||||||
|
{
|
||||||
|
return elem.dump(os);
|
||||||
|
}
|
||||||
|
|
||||||
|
const TargetAlignElem TargetData::InvalidAlignmentElem =
|
||||||
|
TargetAlignElem::get((AlignTypeEnum) -1, 0, 0, 0);
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// TargetData Class Implementation
|
// TargetData Class Implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/*!
|
||||||
|
A TargetDescription string consists of a sequence of hyphen-delimited
|
||||||
|
specifiers for target endianness, pointer size and alignments, and various
|
||||||
|
primitive type sizes and alignments. A typical string looks something like:
|
||||||
|
<br>
|
||||||
|
"E-p:32:32:32-i1:8:8-i8:8:8-i32:32:32-i64:32:64-f32:32:32-f64:32:64"
|
||||||
|
<br>
|
||||||
|
(note: this string is not fully specified and is only an example.)
|
||||||
|
\p
|
||||||
|
Alignments come in two flavors: ABI and preferred. ABI alignment (abi_align,
|
||||||
|
below) dictates how a type will be aligned within an aggregate and when used
|
||||||
|
as an argument. Preferred alignment (pref_align, below) determines a type's
|
||||||
|
alignment when emitted as a global.
|
||||||
|
\p
|
||||||
|
Specifier string details:
|
||||||
|
<br><br>
|
||||||
|
<i>[E|e]</i>: Endianness. "E" specifies a big-endian target data model, "e"
|
||||||
|
specifies a little-endian target data model.
|
||||||
|
<br><br>
|
||||||
|
<i>p:<size>:<abi_align>:<pref_align></i>: Pointer size, ABI and preferred
|
||||||
|
alignment.
|
||||||
|
<br><br>
|
||||||
|
<i><type><size>:<abi_align>:<pref_align></i>: Numeric type alignment. Type is
|
||||||
|
one of <i>i|f|v|a</i>, corresponding to integer, floating point, vector (aka
|
||||||
|
packed) or aggregate. Size indicates the size, e.g., 32 or 64 bits.
|
||||||
|
\p
|
||||||
|
The default string, fully specified is:
|
||||||
|
<br><br>
|
||||||
|
"E-p:64:64:64-a0:0:0-f32:32:32-f64:0:64"
|
||||||
|
"-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:0:64"
|
||||||
|
"-v64:64:64-v128:128:128"
|
||||||
|
<br><br>
|
||||||
|
Note that in the case of aggregates, 0 is the default ABI and preferred
|
||||||
|
alignment. This is a special case, where the aggregate's computed worst-case
|
||||||
|
alignment will be used.
|
||||||
|
*/
|
||||||
void TargetData::init(const std::string &TargetDescription) {
|
void TargetData::init(const std::string &TargetDescription) {
|
||||||
std::string temp = TargetDescription;
|
std::string temp = TargetDescription;
|
||||||
|
|
||||||
LittleEndian = false;
|
LittleEndian = false;
|
||||||
PointerMemSize = 8;
|
PointerMemSize = 8;
|
||||||
PointerABIAlignment = 8;
|
PointerABIAlign = 8;
|
||||||
DoubleABIAlignment = 0;
|
PointerPrefAlign = PointerABIAlign;
|
||||||
FloatABIAlignment = 4;
|
|
||||||
LongABIAlignment = 0;
|
// Default alignments
|
||||||
IntABIAlignment = 4;
|
setAlignment(INTEGER_ALIGN, 1, 1, 1); // Bool
|
||||||
ShortABIAlignment = 2;
|
setAlignment(INTEGER_ALIGN, 1, 1, 8); // Byte
|
||||||
ByteABIAlignment = 1;
|
setAlignment(INTEGER_ALIGN, 2, 2, 16); // short
|
||||||
BoolABIAlignment = 1;
|
setAlignment(INTEGER_ALIGN, 4, 4, 32); // int
|
||||||
BoolPrefAlignment = BoolABIAlignment;
|
setAlignment(INTEGER_ALIGN, 0, 8, 64); // long
|
||||||
BytePrefAlignment = ByteABIAlignment;
|
setAlignment(FLOAT_ALIGN, 4, 4, 32); // float
|
||||||
ShortPrefAlignment = ShortABIAlignment;
|
setAlignment(FLOAT_ALIGN, 0, 8, 64); // double
|
||||||
IntPrefAlignment = IntABIAlignment;
|
setAlignment(PACKED_ALIGN, 8, 8, 64); // v2i32
|
||||||
LongPrefAlignment = 8;
|
setAlignment(PACKED_ALIGN, 16, 16, 128); // v16i8, v8i16, v4i32, ...
|
||||||
FloatPrefAlignment = FloatABIAlignment;
|
setAlignment(AGGREGATE_ALIGN, 0, 0, 0); // struct, union, class, ...
|
||||||
DoublePrefAlignment = 8;
|
|
||||||
PointerPrefAlignment = PointerABIAlignment;
|
|
||||||
AggMinPrefAlignment = 0;
|
|
||||||
|
|
||||||
while (!temp.empty()) {
|
while (!temp.empty()) {
|
||||||
std::string token = getToken(temp, "-");
|
std::string token = getToken(temp, "-");
|
||||||
|
|
||||||
char signal = getToken(token, ":")[0];
|
std::string arg0 = getToken(token, ":");
|
||||||
|
const char *p = arg0.c_str();
|
||||||
switch(signal) {
|
AlignTypeEnum align_type;
|
||||||
|
short size;
|
||||||
|
unsigned char abi_align;
|
||||||
|
unsigned char pref_align;
|
||||||
|
|
||||||
|
switch(*p) {
|
||||||
case 'E':
|
case 'E':
|
||||||
LittleEndian = false;
|
LittleEndian = false;
|
||||||
break;
|
break;
|
||||||
@ -136,56 +217,26 @@ void TargetData::init(const std::string &TargetDescription) {
|
|||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
PointerMemSize = atoi(getToken(token,":").c_str()) / 8;
|
PointerMemSize = atoi(getToken(token,":").c_str()) / 8;
|
||||||
PointerABIAlignment = atoi(getToken(token,":").c_str()) / 8;
|
PointerABIAlign = atoi(getToken(token,":").c_str()) / 8;
|
||||||
PointerPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
|
PointerPrefAlign = atoi(getToken(token,":").c_str()) / 8;
|
||||||
if (PointerPrefAlignment == 0)
|
if (PointerPrefAlign == 0)
|
||||||
PointerPrefAlignment = PointerABIAlignment;
|
PointerPrefAlign = PointerABIAlign;
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
DoubleABIAlignment = atoi(getToken(token,":").c_str()) / 8;
|
|
||||||
DoublePrefAlignment = atoi(getToken(token,":").c_str()) / 8;
|
|
||||||
if (DoublePrefAlignment == 0)
|
|
||||||
DoublePrefAlignment = DoubleABIAlignment;
|
|
||||||
break;
|
|
||||||
case 'f':
|
|
||||||
FloatABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
|
|
||||||
FloatPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
|
|
||||||
if (FloatPrefAlignment == 0)
|
|
||||||
FloatPrefAlignment = FloatABIAlignment;
|
|
||||||
break;
|
|
||||||
case 'l':
|
|
||||||
LongABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
|
|
||||||
LongPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
|
|
||||||
if (LongPrefAlignment == 0)
|
|
||||||
LongPrefAlignment = LongABIAlignment;
|
|
||||||
break;
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
IntABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
|
case 'v':
|
||||||
IntPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
|
case 'f':
|
||||||
if (IntPrefAlignment == 0)
|
case 'a': {
|
||||||
IntPrefAlignment = IntABIAlignment;
|
align_type = (*p == 'i' ? INTEGER_ALIGN :
|
||||||
break;
|
(*p == 'f' ? FLOAT_ALIGN :
|
||||||
case 's':
|
(*p == 'v' ? PACKED_ALIGN : AGGREGATE_ALIGN)));
|
||||||
ShortABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
|
size = (short) atoi(++p);
|
||||||
ShortPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
|
abi_align = atoi(getToken(token, ":").c_str()) / 8;
|
||||||
if (ShortPrefAlignment == 0)
|
pref_align = atoi(getToken(token, ":").c_str()) / 8;
|
||||||
ShortPrefAlignment = ShortABIAlignment;
|
if (pref_align == 0)
|
||||||
break;
|
pref_align = abi_align;
|
||||||
case 'b':
|
setAlignment(align_type, abi_align, pref_align, size);
|
||||||
ByteABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
|
|
||||||
BytePrefAlignment = atoi(getToken(token,":").c_str()) / 8;
|
|
||||||
if (BytePrefAlignment == 0)
|
|
||||||
BytePrefAlignment = ByteABIAlignment;
|
|
||||||
break;
|
|
||||||
case 'B':
|
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -193,16 +244,62 @@ void TargetData::init(const std::string &TargetDescription) {
|
|||||||
|
|
||||||
// Unless explicitly specified, the alignments for longs and doubles is
|
// Unless explicitly specified, the alignments for longs and doubles is
|
||||||
// capped by pointer size.
|
// capped by pointer size.
|
||||||
if (LongABIAlignment == 0)
|
// FIXME: Is this still necessary?
|
||||||
LongABIAlignment = LongPrefAlignment = PointerMemSize;
|
const TargetAlignElem &long_align = getAlignment(INTEGER_ALIGN, 64);
|
||||||
if (DoubleABIAlignment == 0)
|
if (long_align.ABIAlign == 0)
|
||||||
DoubleABIAlignment = DoublePrefAlignment = PointerMemSize;
|
setAlignment(INTEGER_ALIGN, PointerMemSize, PointerMemSize, 64);
|
||||||
|
|
||||||
|
const TargetAlignElem &double_align = getAlignment(FLOAT_ALIGN, 64);
|
||||||
|
if (double_align.ABIAlign == 0)
|
||||||
|
setAlignment(FLOAT_ALIGN, PointerMemSize, PointerMemSize, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetData::TargetData(const Module *M) {
|
TargetData::TargetData(const Module *M) {
|
||||||
init(M->getDataLayout());
|
init(M->getDataLayout());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TargetData::setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
|
||||||
|
unsigned char pref_align, short bit_width) {
|
||||||
|
TargetAlignElem elt = TargetAlignElem::get(align_type, abi_align,
|
||||||
|
pref_align, bit_width);
|
||||||
|
std::pair<align_iterator, align_iterator> ins_result =
|
||||||
|
std::equal_range(Alignments.begin(), Alignments.end(), elt);
|
||||||
|
align_iterator I = ins_result.first;
|
||||||
|
if (I->AlignType == align_type && I->TypeBitWidth == bit_width) {
|
||||||
|
// Update the abi, preferred alignments.
|
||||||
|
I->ABIAlign = abi_align;
|
||||||
|
I->PrefAlign = pref_align;
|
||||||
|
} else
|
||||||
|
Alignments.insert(I, elt);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// Keep around for debugging and testing...
|
||||||
|
align_iterator E = ins_result.second;
|
||||||
|
|
||||||
|
cerr << "setAlignment(" << elt << ")\n";
|
||||||
|
cerr << "I = " << (I - Alignments.begin())
|
||||||
|
<< ", E = " << (E - Alignments.begin()) << "\n";
|
||||||
|
std::copy(Alignments.begin(), Alignments.end(),
|
||||||
|
std::ostream_iterator<TargetAlignElem>(*cerr, "\n"));
|
||||||
|
cerr << "=====\n";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const TargetAlignElem &
|
||||||
|
TargetData::getAlignment(AlignTypeEnum align_type, short bit_width) const
|
||||||
|
{
|
||||||
|
std::pair<align_const_iterator, align_const_iterator> find_result =
|
||||||
|
std::equal_range(Alignments.begin(), Alignments.end(),
|
||||||
|
TargetAlignElem::get(align_type, 0, 0,
|
||||||
|
bit_width));
|
||||||
|
align_const_iterator I = find_result.first;
|
||||||
|
|
||||||
|
// Note: This may not be reasonable if variable-width integer sizes are
|
||||||
|
// passed, at which point, more sophisticated searching will need to be done.
|
||||||
|
return *I;
|
||||||
|
}
|
||||||
|
|
||||||
/// LayoutInfo - The lazy cache of structure layout information maintained by
|
/// LayoutInfo - The lazy cache of structure layout information maintained by
|
||||||
/// TargetData. Note that the struct types must have been free'd before
|
/// TargetData. Note that the struct types must have been free'd before
|
||||||
/// llvm_shutdown is called (and thus this is deallocated) because all the
|
/// llvm_shutdown is called (and thus this is deallocated) because all the
|
||||||
@ -280,190 +377,187 @@ void TargetData::InvalidateStructLayoutInfo(const StructType *Ty) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct hyphen_delimited :
|
||||||
|
public std::iterator<std::output_iterator_tag, void, void, void, void>
|
||||||
|
{
|
||||||
|
std::ostream &o;
|
||||||
|
|
||||||
|
hyphen_delimited(std::ostream &os) :
|
||||||
|
o(os)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
hyphen_delimited &operator=(const TargetAlignElem &elem)
|
||||||
|
{
|
||||||
|
o << "-" << elem;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
hyphen_delimited &operator*()
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
hyphen_delimited &operator++()
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
std::string TargetData::getStringRepresentation() const {
|
std::string TargetData::getStringRepresentation() const {
|
||||||
std::stringstream repr;
|
std::stringstream repr;
|
||||||
|
|
||||||
if (LittleEndian)
|
if (LittleEndian)
|
||||||
repr << "e";
|
repr << "e";
|
||||||
else
|
else
|
||||||
repr << "E";
|
repr << "E";
|
||||||
|
repr << "-p:" << (PointerMemSize * 8) << ":" << (PointerABIAlign * 8)
|
||||||
repr << "-p:" << (PointerMemSize * 8) << ":" << (PointerABIAlignment * 8);
|
<< ":" << (PointerPrefAlign * 8);
|
||||||
repr << "-d:" << (DoubleABIAlignment * 8) << ":"
|
std::copy(Alignments.begin(), Alignments.end(), hyphen_delimited(repr));
|
||||||
<< (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();
|
return repr.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void getTypeInfoABI(const Type *Ty, const TargetData *TD,
|
uint64_t TargetData::getTypeSize(const Type *Ty) const {
|
||||||
uint64_t &Size, unsigned char &Alignment) {
|
|
||||||
assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
|
assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
|
||||||
switch (Ty->getTypeID()) {
|
switch (Ty->getTypeID()) {
|
||||||
case Type::IntegerTyID: {
|
|
||||||
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
|
|
||||||
if (BitWidth <= 8) {
|
|
||||||
Size = 1; Alignment = TD->getByteABIAlignment();
|
|
||||||
} else if (BitWidth <= 16) {
|
|
||||||
Size = 2; Alignment = TD->getShortABIAlignment();
|
|
||||||
} else if (BitWidth <= 32) {
|
|
||||||
Size = 4; Alignment = TD->getIntABIAlignment();
|
|
||||||
} else if (BitWidth <= 64) {
|
|
||||||
Size = 8; Alignment = TD->getLongABIAlignment();
|
|
||||||
} else {
|
|
||||||
Size = ((BitWidth + 7) / 8) & ~1;
|
|
||||||
Alignment = TD->getLongABIAlignment();
|
|
||||||
}
|
|
||||||
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::LabelTyID:
|
||||||
case Type::PointerTyID:
|
case Type::PointerTyID:
|
||||||
Size = TD->getPointerSize(); Alignment = TD->getPointerABIAlignment();
|
return getPointerSize();
|
||||||
return;
|
|
||||||
case Type::ArrayTyID: {
|
case Type::ArrayTyID: {
|
||||||
const ArrayType *ATy = cast<ArrayType>(Ty);
|
const ArrayType *ATy = cast<ArrayType>(Ty);
|
||||||
getTypeInfoABI(ATy->getElementType(), TD, Size, Alignment);
|
uint64_t Size;
|
||||||
|
unsigned char Alignment;
|
||||||
|
Size = getTypeSize(ATy->getElementType());
|
||||||
|
Alignment = getABITypeAlignment(ATy->getElementType());
|
||||||
unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
|
unsigned AlignedSize = (Size + Alignment - 1)/Alignment*Alignment;
|
||||||
Size = AlignedSize*ATy->getNumElements();
|
return AlignedSize*ATy->getNumElements();
|
||||||
return;
|
|
||||||
}
|
|
||||||
case Type::PackedTyID: {
|
|
||||||
const PackedType *PTy = cast<PackedType>(Ty);
|
|
||||||
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.
|
|
||||||
// For now, just set it to be equal to Size.
|
|
||||||
Alignment = Size;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
case Type::StructTyID: {
|
case Type::StructTyID: {
|
||||||
// Get the layout annotation... which is lazily created on demand.
|
// Get the layout annotation... which is lazily created on demand.
|
||||||
const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
|
const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
|
||||||
Size = Layout->getSizeInBytes(); Alignment = Layout->getAlignment();
|
return Layout->getSizeInBytes();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
|
||||||
assert(0 && "Bad type for getTypeInfo!!!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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: {
|
case Type::IntegerTyID: {
|
||||||
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
|
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
|
||||||
if (BitWidth <= 8) {
|
if (BitWidth <= 8) {
|
||||||
Size = 1; Alignment = TD->getBytePrefAlignment();
|
return 1;
|
||||||
} else if (BitWidth <= 16) {
|
} else if (BitWidth <= 16) {
|
||||||
Size = 2; Alignment = TD->getShortPrefAlignment();
|
return 2;
|
||||||
} else if (BitWidth <= 32) {
|
} else if (BitWidth <= 32) {
|
||||||
Size = 4; Alignment = TD->getIntPrefAlignment();
|
return 4;
|
||||||
} else if (BitWidth <= 64) {
|
} else if (BitWidth <= 64) {
|
||||||
Size = 8; Alignment = TD->getLongPrefAlignment();
|
return 8;
|
||||||
} else
|
} else
|
||||||
assert(0 && "Integer types > 64 bits not supported.");
|
assert(0 && "Integer types > 64 bits not supported.");
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
case Type::VoidTyID:
|
case Type::VoidTyID:
|
||||||
Size = 1; Alignment = TD->getBytePrefAlignment();
|
return 1;
|
||||||
return;
|
|
||||||
case Type::FloatTyID:
|
case Type::FloatTyID:
|
||||||
Size = 4; Alignment = TD->getFloatPrefAlignment();
|
return 4;
|
||||||
return;
|
|
||||||
case Type::DoubleTyID:
|
case Type::DoubleTyID:
|
||||||
Size = 8; Alignment = TD->getDoublePrefAlignment();
|
return 8;
|
||||||
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: {
|
case Type::PackedTyID: {
|
||||||
const PackedType *PTy = cast<PackedType>(Ty);
|
const PackedType *PTy = cast<PackedType>(Ty);
|
||||||
getTypeInfoPref(PTy->getElementType(), TD, Size, Alignment);
|
return PTy->getBitWidth() / 8;
|
||||||
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->getSizeInBytes();
|
|
||||||
Alignment = std::max(Layout->getAlignment(),
|
|
||||||
(const unsigned int)TD->getAggMinPrefAlignment());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(0 && "Bad type for getTypeInfoPref!!!");
|
assert(0 && "TargetData::getTypeSize(): Unsupported type");
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
}
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
uint64_t TargetData::getTypeSize(const Type *Ty) const {
|
|
||||||
uint64_t Size;
|
|
||||||
unsigned char Align;
|
|
||||||
getTypeInfoABI(Ty, this, Size, Align);
|
|
||||||
return Size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t TargetData::getTypeSizeInBits(const Type *Ty) const {
|
uint64_t TargetData::getTypeSizeInBits(const Type *Ty) const {
|
||||||
if (Ty->isInteger())
|
if (Ty->isInteger())
|
||||||
return cast<IntegerType>(Ty)->getBitWidth();
|
return cast<IntegerType>(Ty)->getBitWidth();
|
||||||
|
else
|
||||||
uint64_t Size;
|
return getTypeSize(Ty) * 8;
|
||||||
unsigned char Align;
|
|
||||||
getTypeInfoABI(Ty, this, Size, Align);
|
|
||||||
return Size * 8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char TargetData::getTypeAlignmentABI(const Type *Ty) const {
|
|
||||||
uint64_t Size;
|
/*!
|
||||||
unsigned char Align;
|
\param abi_or_pref Flag that determines which alignment is returned. true
|
||||||
getTypeInfoABI(Ty, this, Size, Align);
|
returns the ABI alignment, false returns the preferred alignment.
|
||||||
return Align;
|
\param Ty The underlying type for which alignment is determined.
|
||||||
|
|
||||||
|
Get the ABI (\a abi_or_pref == true) or preferred alignment (\a abi_or_pref
|
||||||
|
== false) for the requested type \a Ty.
|
||||||
|
*/
|
||||||
|
unsigned char TargetData::getAlignment(const Type *Ty, bool abi_or_pref) const
|
||||||
|
{
|
||||||
|
int AlignType = -1;
|
||||||
|
|
||||||
|
assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
|
||||||
|
switch (Ty->getTypeID()) {
|
||||||
|
/* Early escape for the non-numeric types */
|
||||||
|
case Type::LabelTyID:
|
||||||
|
case Type::PointerTyID:
|
||||||
|
return (abi_or_pref
|
||||||
|
? getPointerABIAlignment()
|
||||||
|
: getPointerPrefAlignment());
|
||||||
|
case Type::ArrayTyID: {
|
||||||
|
const ArrayType *ATy = cast<ArrayType>(Ty);
|
||||||
|
return (abi_or_pref
|
||||||
|
? getABITypeAlignment(ATy->getElementType())
|
||||||
|
: getPrefTypeAlignment(ATy->getElementType()));
|
||||||
|
}
|
||||||
|
case Type::StructTyID: {
|
||||||
|
// Get the layout annotation... which is lazily created on demand.
|
||||||
|
const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
|
||||||
|
const TargetAlignElem &elem = getAlignment(AGGREGATE_ALIGN, 0);
|
||||||
|
assert(validAlignment(elem)
|
||||||
|
&& "Aggregate alignment return invalid in getAlignment");
|
||||||
|
if (abi_or_pref) {
|
||||||
|
return (elem.ABIAlign < Layout->getAlignment()
|
||||||
|
? Layout->StructAlignment
|
||||||
|
: elem.ABIAlign);
|
||||||
|
} else {
|
||||||
|
return (elem.PrefAlign < Layout->getAlignment()
|
||||||
|
? Layout->StructAlignment
|
||||||
|
: elem.PrefAlign);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case Type::IntegerTyID:
|
||||||
|
case Type::VoidTyID:
|
||||||
|
AlignType = INTEGER_ALIGN;
|
||||||
|
break;
|
||||||
|
case Type::FloatTyID:
|
||||||
|
case Type::DoubleTyID:
|
||||||
|
AlignType = FLOAT_ALIGN;
|
||||||
|
break;
|
||||||
|
case Type::PackedTyID:
|
||||||
|
AlignType = PACKED_ALIGN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0 && "Bad type for getAlignment!!!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TargetAlignElem &elem = getAlignment((AlignTypeEnum) AlignType,
|
||||||
|
getTypeSize(Ty) * 8);
|
||||||
|
if (validAlignment(elem))
|
||||||
|
return (abi_or_pref ? elem.ABIAlign : elem.PrefAlign);
|
||||||
|
else {
|
||||||
|
cerr << "TargetData::getAlignment: align type " << AlignType
|
||||||
|
<< " size " << getTypeSize(Ty) << " not found in Alignments.\n";
|
||||||
|
abort();
|
||||||
|
/*NOTREACHED*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char TargetData::getTypeAlignmentPref(const Type *Ty) const {
|
unsigned char TargetData::getABITypeAlignment(const Type *Ty) const {
|
||||||
uint64_t Size;
|
return getAlignment(Ty, true);
|
||||||
unsigned char Align;
|
}
|
||||||
getTypeInfoPref(Ty, this, Size, Align);
|
|
||||||
return Align;
|
unsigned char TargetData::getPrefTypeAlignment(const Type *Ty) const {
|
||||||
|
return getAlignment(Ty, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char TargetData::getPreferredTypeAlignmentShift(const Type *Ty) const {
|
unsigned char TargetData::getPreferredTypeAlignmentShift(const Type *Ty) const {
|
||||||
unsigned Align = getTypeAlignmentPref(Ty);
|
unsigned Align = (unsigned) getPrefTypeAlignment(Ty);
|
||||||
assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
|
assert(!(Align & (Align-1)) && "Alignment is not a power of two!");
|
||||||
return Log2_32(Align);
|
return Log2_32(Align);
|
||||||
}
|
}
|
||||||
@ -533,4 +627,3 @@ unsigned TargetData::getPreferredAlignmentLog(const GlobalVariable *GV) const {
|
|||||||
}
|
}
|
||||||
return Alignment;
|
return Alignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
X86TargetMachine::X86TargetMachine(const Module &M, const std::string &FS, bool is64Bit)
|
||||||
: Subtarget(M, FS, is64Bit),
|
: Subtarget(M, FS, is64Bit),
|
||||||
DataLayout(Subtarget.is64Bit() ?
|
DataLayout(Subtarget.is64Bit() ?
|
||||||
std::string("e-p:64:64-d:32:64-l:32:64") :
|
std::string("e-p:64:64-f64:32:64-i64:32:64") :
|
||||||
std::string("e-p:32:32-d:32:64-l:32:64")),
|
std::string("e-p:32:32-f64:32:64-i64:32:64")),
|
||||||
FrameInfo(TargetFrameInfo::StackGrowsDown,
|
FrameInfo(TargetFrameInfo::StackGrowsDown,
|
||||||
Subtarget.getStackAlignment(), Subtarget.is64Bit() ? -8 : -4),
|
Subtarget.getStackAlignment(), Subtarget.is64Bit() ? -8 : -4),
|
||||||
InstrInfo(*this), JITInfo(*this), TLInfo(*this) {
|
InstrInfo(*this), JITInfo(*this), TLInfo(*this) {
|
||||||
|
@ -366,7 +366,6 @@ static Value *getBitCastOperand(Value *V) {
|
|||||||
|
|
||||||
/// This function is a wrapper around CastInst::isEliminableCastPair. It
|
/// This function is a wrapper around CastInst::isEliminableCastPair. It
|
||||||
/// simply extracts arguments and returns what that function returns.
|
/// simply extracts arguments and returns what that function returns.
|
||||||
/// @Determine if it is valid to eliminate a Convert pair
|
|
||||||
static Instruction::CastOps
|
static Instruction::CastOps
|
||||||
isEliminableCastPair(
|
isEliminableCastPair(
|
||||||
const CastInst *CI, ///< The first cast instruction
|
const CastInst *CI, ///< The first cast instruction
|
||||||
@ -5813,8 +5812,8 @@ Instruction *InstCombiner::PromoteCastOfAllocation(CastInst &CI,
|
|||||||
const Type *CastElTy = PTy->getElementType();
|
const Type *CastElTy = PTy->getElementType();
|
||||||
if (!AllocElTy->isSized() || !CastElTy->isSized()) return 0;
|
if (!AllocElTy->isSized() || !CastElTy->isSized()) return 0;
|
||||||
|
|
||||||
unsigned AllocElTyAlign = TD->getTypeAlignmentABI(AllocElTy);
|
unsigned AllocElTyAlign = TD->getABITypeAlignment(AllocElTy);
|
||||||
unsigned CastElTyAlign = TD->getTypeAlignmentABI(CastElTy);
|
unsigned CastElTyAlign = TD->getABITypeAlignment(CastElTy);
|
||||||
if (CastElTyAlign < AllocElTyAlign) return 0;
|
if (CastElTyAlign < AllocElTyAlign) return 0;
|
||||||
|
|
||||||
// If the allocation has multiple uses, only promote it if we are strictly
|
// If the allocation has multiple uses, only promote it if we are strictly
|
||||||
@ -6903,22 +6902,22 @@ static unsigned GetKnownAlignment(Value *V, TargetData *TD) {
|
|||||||
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
|
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) {
|
||||||
unsigned Align = GV->getAlignment();
|
unsigned Align = GV->getAlignment();
|
||||||
if (Align == 0 && TD)
|
if (Align == 0 && TD)
|
||||||
Align = TD->getTypeAlignmentPref(GV->getType()->getElementType());
|
Align = TD->getPrefTypeAlignment(GV->getType()->getElementType());
|
||||||
return Align;
|
return Align;
|
||||||
} else if (AllocationInst *AI = dyn_cast<AllocationInst>(V)) {
|
} else if (AllocationInst *AI = dyn_cast<AllocationInst>(V)) {
|
||||||
unsigned Align = AI->getAlignment();
|
unsigned Align = AI->getAlignment();
|
||||||
if (Align == 0 && TD) {
|
if (Align == 0 && TD) {
|
||||||
if (isa<AllocaInst>(AI))
|
if (isa<AllocaInst>(AI))
|
||||||
Align = TD->getTypeAlignmentPref(AI->getType()->getElementType());
|
Align = TD->getPrefTypeAlignment(AI->getType()->getElementType());
|
||||||
else if (isa<MallocInst>(AI)) {
|
else if (isa<MallocInst>(AI)) {
|
||||||
// Malloc returns maximally aligned memory.
|
// Malloc returns maximally aligned memory.
|
||||||
Align = TD->getTypeAlignmentABI(AI->getType()->getElementType());
|
Align = TD->getABITypeAlignment(AI->getType()->getElementType());
|
||||||
Align =
|
Align =
|
||||||
std::max(Align,
|
std::max(Align,
|
||||||
(unsigned)TD->getTypeAlignmentABI(Type::DoubleTy));
|
(unsigned)TD->getABITypeAlignment(Type::DoubleTy));
|
||||||
Align =
|
Align =
|
||||||
std::max(Align,
|
std::max(Align,
|
||||||
(unsigned)TD->getTypeAlignmentABI(Type::Int64Ty));
|
(unsigned)TD->getABITypeAlignment(Type::Int64Ty));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Align;
|
return Align;
|
||||||
@ -6954,11 +6953,11 @@ static unsigned GetKnownAlignment(Value *V, TargetData *TD) {
|
|||||||
|
|
||||||
const Type *BasePtrTy = GEPI->getOperand(0)->getType();
|
const Type *BasePtrTy = GEPI->getOperand(0)->getType();
|
||||||
const PointerType *PtrTy = cast<PointerType>(BasePtrTy);
|
const PointerType *PtrTy = cast<PointerType>(BasePtrTy);
|
||||||
if (TD->getTypeAlignmentABI(PtrTy->getElementType())
|
if (TD->getABITypeAlignment(PtrTy->getElementType())
|
||||||
<= BaseAlignment) {
|
<= BaseAlignment) {
|
||||||
const Type *GEPTy = GEPI->getType();
|
const Type *GEPTy = GEPI->getType();
|
||||||
const PointerType *GEPPtrTy = cast<PointerType>(GEPTy);
|
const PointerType *GEPPtrTy = cast<PointerType>(GEPTy);
|
||||||
return TD->getTypeAlignmentABI(GEPPtrTy->getElementType());
|
return TD->getABITypeAlignment(GEPPtrTy->getElementType());
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -8550,8 +8549,10 @@ static bool CheapToScalarize(Value *V, bool isConstant) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getShuffleMask - Read and decode a shufflevector mask. It turns undef
|
/// Read and decode a shufflevector mask.
|
||||||
/// elements into values that are larger than the #elts in the input.
|
///
|
||||||
|
/// It turns undef elements into values that are larger than the number of
|
||||||
|
/// elements in the input.
|
||||||
static std::vector<unsigned> getShuffleMask(const ShuffleVectorInst *SVI) {
|
static std::vector<unsigned> getShuffleMask(const ShuffleVectorInst *SVI) {
|
||||||
unsigned NElts = SVI->getType()->getNumElements();
|
unsigned NElts = SVI->getType()->getNumElements();
|
||||||
if (isa<ConstantAggregateZero>(SVI->getOperand(2)))
|
if (isa<ConstantAggregateZero>(SVI->getOperand(2)))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user