mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-02 07:32:52 +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/Support/DataTypes.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -31,45 +33,96 @@ class StructType;
|
||||
class StructLayout;
|
||||
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 {
|
||||
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
|
||||
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
|
||||
//! Where the primitive type alignment data is stored.
|
||||
/*!
|
||||
@sa init().
|
||||
@note Could support multiple size pointer alignments, e.g., 32-bit pointers
|
||||
vs. 64-bit pointers by extending TargetAlignment, but for now, we don't.
|
||||
*/
|
||||
SmallVector<TargetAlignElem, 16> Alignments;
|
||||
//! Alignment iterator shorthand
|
||||
typedef SmallVector<TargetAlignElem, 16>::iterator align_iterator;
|
||||
//! 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
|
||||
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
|
||||
//! Set/initialize target alignments
|
||||
void setAlignment(AlignTypeEnum align_type, unsigned char abi_align,
|
||||
unsigned char pref_align, short bit_width);
|
||||
//! Get TargetAlignElem from alignment type and bit width
|
||||
const TargetAlignElem &getAlignment(AlignTypeEnum, short) const;
|
||||
//! Internal helper method that returns requested alignment for type.
|
||||
unsigned char getAlignment(const Type *Ty, bool abi_or_pref) const;
|
||||
|
||||
/// Valid alignment predicate.
|
||||
///
|
||||
/// Predicate that tests a TargetAlignElem reference returned by get() against
|
||||
/// InvalidAlignmentElem.
|
||||
inline bool validAlignment(const TargetAlignElem &align) const {
|
||||
return (&align != &InvalidAlignmentElem);
|
||||
}
|
||||
|
||||
public:
|
||||
/// Default ctor - This has to exist, because this is a pass, but it should
|
||||
/// never be used.
|
||||
/// Default ctor.
|
||||
///
|
||||
/// @note This has to exist, because this is a pass, but it should never be
|
||||
/// used.
|
||||
TargetData() {
|
||||
assert(0 && "ERROR: Bad TargetData ctor used. "
|
||||
"Tool did not specify a TargetData to use?");
|
||||
abort();
|
||||
}
|
||||
|
||||
/// Constructs a TargetData from a string of the following format:
|
||||
/// "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.
|
||||
/// Constructs a TargetData from a specification string. See init().
|
||||
TargetData(const std::string &TargetDescription) {
|
||||
init(TargetDescription);
|
||||
}
|
||||
@ -80,143 +133,36 @@ public:
|
||||
TargetData(const TargetData &TD) :
|
||||
ImmutablePass(),
|
||||
LittleEndian(TD.isLittleEndian()),
|
||||
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()) {
|
||||
}
|
||||
PointerMemSize(TD.PointerMemSize),
|
||||
PointerABIAlign(TD.PointerABIAlign),
|
||||
PointerPrefAlign(TD.PointerPrefAlign),
|
||||
Alignments(TD.Alignments)
|
||||
{ }
|
||||
|
||||
~TargetData(); // Not virtual, do not subclass this class
|
||||
|
||||
/// Parse a target data layout string and initialize TargetData members.
|
||||
///
|
||||
/// 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.
|
||||
//! Parse a target data layout string and initialize TargetData alignments.
|
||||
void init(const std::string &TargetDescription);
|
||||
|
||||
|
||||
/// Target endianness...
|
||||
bool isLittleEndian() 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
|
||||
/// TargetData. This representation is in the same format accepted by the
|
||||
/// string constructor above.
|
||||
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
|
||||
/// type.
|
||||
///
|
||||
uint64_t getTypeSize(const Type *Ty) const;
|
||||
|
||||
/// getTypeSizeInBits - Return the number of bytes necessary to hold the
|
||||
@ -225,11 +171,11 @@ public:
|
||||
|
||||
/// getTypeAlignmentABI - Return the minimum ABI-required alignment for the
|
||||
/// specified type.
|
||||
unsigned char getTypeAlignmentABI(const Type *Ty) const;
|
||||
unsigned char getABITypeAlignment(const Type *Ty) const;
|
||||
|
||||
/// getTypeAlignmentPref - Return the preferred stack/global alignment for
|
||||
/// the specified type.
|
||||
unsigned char getTypeAlignmentPref(const Type *Ty) const;
|
||||
unsigned char getPrefTypeAlignment(const Type *Ty) const;
|
||||
|
||||
/// getPreferredTypeAlignmentShift - Return the preferred alignment for the
|
||||
/// 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();
|
||||
unsigned Align = TM.getTargetData()->getTypeAlignmentPref(GVType);
|
||||
unsigned Align = TM.getTargetData()->getPrefTypeAlignment(GVType);
|
||||
unsigned Size = TM.getTargetData()->getTypeSize(GVType);
|
||||
|
||||
// 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.
|
||||
unsigned FnAlign = F->getAlignment();
|
||||
unsigned TDAlign = TD->getTypeAlignmentPref(F->getType());
|
||||
unsigned TDAlign = TD->getPrefTypeAlignment(F->getType());
|
||||
unsigned Align = Log2_32(std::max(FnAlign, TDAlign));
|
||||
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 Align = GV->getAlignment();
|
||||
if (Align == 0)
|
||||
Align = TM.getTargetData()->getTypeAlignmentPref(Ty);
|
||||
Align = TM.getTargetData()->getPrefTypeAlignment(Ty);
|
||||
|
||||
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/MachineInstr.h"
|
||||
#include "llvm/CodeGen/SSARegMap.h"
|
||||
@ -123,7 +124,7 @@ 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.getIntABIAlignment()
|
||||
unsigned Alignment = IsPic ? TD.getABITypeAlignment(Type::Int32Ty)
|
||||
: TD.getPointerABIAlignment();
|
||||
JumpTableInfo = new MachineJumpTableInfo(EntrySize, Alignment);
|
||||
|
||||
|
@ -3056,7 +3056,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()->getTypeAlignmentPref(Ty);
|
||||
unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty);
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
int SSFI =
|
||||
MF.getFrameInfo()->CreateStackObject((unsigned)TySize, Align);
|
||||
@ -3979,7 +3979,7 @@ SDOperand SelectionDAGLegalize::CreateStackTemporary(MVT::ValueType VT) {
|
||||
MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
|
||||
unsigned ByteSize = MVT::getSizeInBits(VT)/8;
|
||||
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);
|
||||
return DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
|
||||
}
|
||||
@ -4289,7 +4289,7 @@ SDOperand SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
|
||||
MachineFunction &MF = DAG.getMachineFunction();
|
||||
const Type *F64Type = MVT::getTypeForValueType(MVT::f64);
|
||||
unsigned StackAlign =
|
||||
(unsigned)TLI.getTargetData()->getTypeAlignmentPref(F64Type);
|
||||
(unsigned)TLI.getTargetData()->getPrefTypeAlignment(F64Type);
|
||||
int SSFI = MF.getFrameInfo()->CreateStackObject(8, StackAlign);
|
||||
// get address of 8 byte buffer
|
||||
SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
|
||||
|
@ -244,7 +244,7 @@ FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli,
|
||||
const Type *Ty = AI->getAllocatedType();
|
||||
uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
|
||||
unsigned Align =
|
||||
std::max((unsigned)TLI.getTargetData()->getTypeAlignmentPref(Ty),
|
||||
std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty),
|
||||
AI->getAlignment());
|
||||
|
||||
TySize *= CUI->getZExtValue(); // Get total allocated size.
|
||||
@ -1733,7 +1733,7 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) {
|
||||
const Type *Ty = I.getAllocatedType();
|
||||
uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
|
||||
unsigned Align =
|
||||
std::max((unsigned)TLI.getTargetData()->getTypeAlignmentPref(Ty),
|
||||
std::max((unsigned)TLI.getTargetData()->getPrefTypeAlignment(Ty),
|
||||
I.getAlignment());
|
||||
|
||||
SDOperand AllocSize = getValue(I.getArraySize());
|
||||
@ -2934,7 +2934,7 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
||||
bool isInReg = FTy->paramHasAttr(j, FunctionType::InRegAttribute);
|
||||
bool isSRet = FTy->paramHasAttr(j, FunctionType::StructRetAttribute);
|
||||
unsigned OriginalAlignment =
|
||||
getTargetData()->getTypeAlignmentABI(I->getType());
|
||||
getTargetData()->getABITypeAlignment(I->getType());
|
||||
// Flags[31:27] -> OriginalAlignment
|
||||
// Flags[2] -> isSRet
|
||||
// Flags[1] -> isInReg
|
||||
@ -3120,7 +3120,7 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
||||
bool isInReg = Args[i].isInReg;
|
||||
bool isSRet = Args[i].isSRet;
|
||||
unsigned OriginalAlignment =
|
||||
getTargetData()->getTypeAlignmentABI(Args[i].Ty);
|
||||
getTargetData()->getABITypeAlignment(Args[i].Ty);
|
||||
// Flags[31:27] -> OriginalAlignment
|
||||
// Flags[2] -> isSRet
|
||||
// Flags[1] -> isInReg
|
||||
|
@ -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()->getTypeAlignmentPref(GlobalType);
|
||||
size_t A = getTargetData()->getPrefTypeAlignment(GlobalType);
|
||||
if (A <= 8) {
|
||||
Ptr = malloc(S);
|
||||
} else {
|
||||
|
@ -37,12 +37,14 @@ ARMTargetMachine::ARMTargetMachine(const Module &M, const std::string &FS)
|
||||
DataLayout(Subtarget.isAPCS_ABI() ?
|
||||
// APCS ABI
|
||||
(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-d:32:32-l:32:32")) :
|
||||
std::string("e-p:32:32-f64:32:32-i64: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
|
||||
(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-d:64:64-l:64:64"))),
|
||||
std::string("e-p:32:32-f64:64:64-i64: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),
|
||||
FrameInfo(Subtarget) {}
|
||||
|
||||
|
@ -104,8 +104,8 @@ public:
|
||||
/// getTargetDataString - Return the pointer size and type alignment
|
||||
/// properties of this subtarget.
|
||||
const char *getTargetDataString() const {
|
||||
return isPPC64() ? "E-p:64:64-d:32:64-l:32:64"
|
||||
: "E-p:32:32-d:32:64-l:32:64";
|
||||
return isPPC64() ? "E-p:64:64-f64:32:64-i64: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.
|
||||
|
@ -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->getTypeAlignmentPref(C->getType());
|
||||
unsigned Align = TD->getPrefTypeAlignment(C->getType());
|
||||
|
||||
if (C->isNullValue() &&
|
||||
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
|
||||
|
@ -36,12 +36,6 @@ namespace {
|
||||
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
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -54,11 +48,10 @@ StructLayout::StructLayout(const StructType *ST, const TargetData &TD) {
|
||||
// Loop over each of the elements, placing them in memory...
|
||||
for (unsigned i = 0, e = NumElements; i != e; ++i) {
|
||||
const Type *Ty = ST->getElementType(i);
|
||||
unsigned char A;
|
||||
unsigned TyAlign;
|
||||
uint64_t TySize;
|
||||
getTypeInfoABI(Ty, &TD, TySize, A);
|
||||
TyAlign = ST->isPacked() ? 1 : A;
|
||||
TyAlign = (unsigned) TD.getABITypeAlignment(Ty);
|
||||
TySize = (unsigned) TD.getTypeSize(Ty);
|
||||
|
||||
// Add padding if necessary to make the data element aligned properly...
|
||||
if (StructSize % TyAlign != 0)
|
||||
@ -95,39 +88,127 @@ unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
|
||||
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
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
/*!
|
||||
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) {
|
||||
std::string temp = TargetDescription;
|
||||
|
||||
LittleEndian = false;
|
||||
PointerMemSize = 8;
|
||||
PointerABIAlignment = 8;
|
||||
DoubleABIAlignment = 0;
|
||||
FloatABIAlignment = 4;
|
||||
LongABIAlignment = 0;
|
||||
IntABIAlignment = 4;
|
||||
ShortABIAlignment = 2;
|
||||
ByteABIAlignment = 1;
|
||||
BoolABIAlignment = 1;
|
||||
BoolPrefAlignment = BoolABIAlignment;
|
||||
BytePrefAlignment = ByteABIAlignment;
|
||||
ShortPrefAlignment = ShortABIAlignment;
|
||||
IntPrefAlignment = IntABIAlignment;
|
||||
LongPrefAlignment = 8;
|
||||
FloatPrefAlignment = FloatABIAlignment;
|
||||
DoublePrefAlignment = 8;
|
||||
PointerPrefAlignment = PointerABIAlignment;
|
||||
AggMinPrefAlignment = 0;
|
||||
PointerABIAlign = 8;
|
||||
PointerPrefAlign = PointerABIAlign;
|
||||
|
||||
// Default alignments
|
||||
setAlignment(INTEGER_ALIGN, 1, 1, 1); // Bool
|
||||
setAlignment(INTEGER_ALIGN, 1, 1, 8); // Byte
|
||||
setAlignment(INTEGER_ALIGN, 2, 2, 16); // short
|
||||
setAlignment(INTEGER_ALIGN, 4, 4, 32); // int
|
||||
setAlignment(INTEGER_ALIGN, 0, 8, 64); // long
|
||||
setAlignment(FLOAT_ALIGN, 4, 4, 32); // float
|
||||
setAlignment(FLOAT_ALIGN, 0, 8, 64); // double
|
||||
setAlignment(PACKED_ALIGN, 8, 8, 64); // v2i32
|
||||
setAlignment(PACKED_ALIGN, 16, 16, 128); // v16i8, v8i16, v4i32, ...
|
||||
setAlignment(AGGREGATE_ALIGN, 0, 0, 0); // struct, union, class, ...
|
||||
|
||||
while (!temp.empty()) {
|
||||
std::string token = getToken(temp, "-");
|
||||
|
||||
char signal = getToken(token, ":")[0];
|
||||
|
||||
switch(signal) {
|
||||
std::string arg0 = getToken(token, ":");
|
||||
const char *p = arg0.c_str();
|
||||
AlignTypeEnum align_type;
|
||||
short size;
|
||||
unsigned char abi_align;
|
||||
unsigned char pref_align;
|
||||
|
||||
switch(*p) {
|
||||
case 'E':
|
||||
LittleEndian = false;
|
||||
break;
|
||||
@ -136,56 +217,26 @@ void TargetData::init(const std::string &TargetDescription) {
|
||||
break;
|
||||
case 'p':
|
||||
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':
|
||||
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;
|
||||
PointerABIAlign = atoi(getToken(token,":").c_str()) / 8;
|
||||
PointerPrefAlign = atoi(getToken(token,":").c_str()) / 8;
|
||||
if (PointerPrefAlign == 0)
|
||||
PointerPrefAlign = PointerABIAlign;
|
||||
break;
|
||||
case 'i':
|
||||
IntABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
|
||||
IntPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
|
||||
if (IntPrefAlignment == 0)
|
||||
IntPrefAlignment = IntABIAlignment;
|
||||
break;
|
||||
case 's':
|
||||
ShortABIAlignment = atoi(getToken(token, ":").c_str()) / 8;
|
||||
ShortPrefAlignment = atoi(getToken(token,":").c_str()) / 8;
|
||||
if (ShortPrefAlignment == 0)
|
||||
ShortPrefAlignment = ShortABIAlignment;
|
||||
break;
|
||||
case 'b':
|
||||
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;
|
||||
case 'v':
|
||||
case 'f':
|
||||
case 'a': {
|
||||
align_type = (*p == 'i' ? INTEGER_ALIGN :
|
||||
(*p == 'f' ? FLOAT_ALIGN :
|
||||
(*p == 'v' ? PACKED_ALIGN : AGGREGATE_ALIGN)));
|
||||
size = (short) atoi(++p);
|
||||
abi_align = atoi(getToken(token, ":").c_str()) / 8;
|
||||
pref_align = atoi(getToken(token, ":").c_str()) / 8;
|
||||
if (pref_align == 0)
|
||||
pref_align = abi_align;
|
||||
setAlignment(align_type, abi_align, pref_align, size);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -193,16 +244,62 @@ void TargetData::init(const std::string &TargetDescription) {
|
||||
|
||||
// Unless explicitly specified, the alignments for longs and doubles is
|
||||
// capped by pointer size.
|
||||
if (LongABIAlignment == 0)
|
||||
LongABIAlignment = LongPrefAlignment = PointerMemSize;
|
||||
if (DoubleABIAlignment == 0)
|
||||
DoubleABIAlignment = DoublePrefAlignment = PointerMemSize;
|
||||
// FIXME: Is this still necessary?
|
||||
const TargetAlignElem &long_align = getAlignment(INTEGER_ALIGN, 64);
|
||||
if (long_align.ABIAlign == 0)
|
||||
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) {
|
||||
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
|
||||
/// TargetData. Note that the struct types must have been free'd before
|
||||
/// 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::stringstream repr;
|
||||
|
||||
|
||||
if (LittleEndian)
|
||||
repr << "e";
|
||||
else
|
||||
repr << "E";
|
||||
|
||||
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);
|
||||
|
||||
repr << "-p:" << (PointerMemSize * 8) << ":" << (PointerABIAlign * 8)
|
||||
<< ":" << (PointerPrefAlign * 8);
|
||||
std::copy(Alignments.begin(), Alignments.end(), hyphen_delimited(repr));
|
||||
return repr.str();
|
||||
}
|
||||
|
||||
|
||||
static inline void getTypeInfoABI(const Type *Ty, const TargetData *TD,
|
||||
uint64_t &Size, unsigned char &Alignment) {
|
||||
uint64_t TargetData::getTypeSize(const Type *Ty) const {
|
||||
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->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::PointerTyID:
|
||||
Size = TD->getPointerSize(); Alignment = TD->getPointerABIAlignment();
|
||||
return;
|
||||
return getPointerSize();
|
||||
case Type::ArrayTyID: {
|
||||
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;
|
||||
Size = 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;
|
||||
return AlignedSize*ATy->getNumElements();
|
||||
}
|
||||
case Type::StructTyID: {
|
||||
// Get the layout annotation... which is lazily created on demand.
|
||||
const StructLayout *Layout = TD->getStructLayout(cast<StructType>(Ty));
|
||||
Size = Layout->getSizeInBytes(); Alignment = Layout->getAlignment();
|
||||
return;
|
||||
const StructLayout *Layout = getStructLayout(cast<StructType>(Ty));
|
||||
return Layout->getSizeInBytes();
|
||||
}
|
||||
|
||||
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: {
|
||||
unsigned BitWidth = cast<IntegerType>(Ty)->getBitWidth();
|
||||
if (BitWidth <= 8) {
|
||||
Size = 1; Alignment = TD->getBytePrefAlignment();
|
||||
return 1;
|
||||
} else if (BitWidth <= 16) {
|
||||
Size = 2; Alignment = TD->getShortPrefAlignment();
|
||||
return 2;
|
||||
} else if (BitWidth <= 32) {
|
||||
Size = 4; Alignment = TD->getIntPrefAlignment();
|
||||
return 4;
|
||||
} else if (BitWidth <= 64) {
|
||||
Size = 8; Alignment = TD->getLongPrefAlignment();
|
||||
return 8;
|
||||
} else
|
||||
assert(0 && "Integer types > 64 bits not supported.");
|
||||
return;
|
||||
break;
|
||||
}
|
||||
case Type::VoidTyID:
|
||||
Size = 1; Alignment = TD->getBytePrefAlignment();
|
||||
return;
|
||||
return 1;
|
||||
case Type::FloatTyID:
|
||||
Size = 4; Alignment = TD->getFloatPrefAlignment();
|
||||
return;
|
||||
return 4;
|
||||
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;
|
||||
}
|
||||
return 8;
|
||||
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;
|
||||
return PTy->getBitWidth() / 8;
|
||||
}
|
||||
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:
|
||||
assert(0 && "Bad type for getTypeInfoPref!!!");
|
||||
return;
|
||||
assert(0 && "TargetData::getTypeSize(): Unsupported type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint64_t TargetData::getTypeSize(const Type *Ty) const {
|
||||
uint64_t Size;
|
||||
unsigned char Align;
|
||||
getTypeInfoABI(Ty, this, Size, Align);
|
||||
return Size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t TargetData::getTypeSizeInBits(const Type *Ty) const {
|
||||
if (Ty->isInteger())
|
||||
return cast<IntegerType>(Ty)->getBitWidth();
|
||||
|
||||
uint64_t Size;
|
||||
unsigned char Align;
|
||||
getTypeInfoABI(Ty, this, Size, Align);
|
||||
return Size * 8;
|
||||
else
|
||||
return getTypeSize(Ty) * 8;
|
||||
}
|
||||
|
||||
unsigned char TargetData::getTypeAlignmentABI(const Type *Ty) const {
|
||||
uint64_t Size;
|
||||
unsigned char Align;
|
||||
getTypeInfoABI(Ty, this, Size, Align);
|
||||
return Align;
|
||||
|
||||
/*!
|
||||
\param abi_or_pref Flag that determines which alignment is returned. true
|
||||
returns the ABI alignment, false returns the preferred alignment.
|
||||
\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 {
|
||||
uint64_t Size;
|
||||
unsigned char Align;
|
||||
getTypeInfoPref(Ty, this, Size, Align);
|
||||
return Align;
|
||||
unsigned char TargetData::getABITypeAlignment(const Type *Ty) const {
|
||||
return getAlignment(Ty, true);
|
||||
}
|
||||
|
||||
unsigned char TargetData::getPrefTypeAlignment(const Type *Ty) const {
|
||||
return getAlignment(Ty, false);
|
||||
}
|
||||
|
||||
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!");
|
||||
return Log2_32(Align);
|
||||
}
|
||||
@ -533,4 +627,3 @@ unsigned TargetData::getPreferredAlignmentLog(const GlobalVariable *GV) const {
|
||||
}
|
||||
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)
|
||||
: Subtarget(M, FS, is64Bit),
|
||||
DataLayout(Subtarget.is64Bit() ?
|
||||
std::string("e-p:64:64-d:32:64-l:32:64") :
|
||||
std::string("e-p:32:32-d:32:64-l:32:64")),
|
||||
std::string("e-p:64:64-f64:32:64-i64:32:64") :
|
||||
std::string("e-p:32:32-f64:32:64-i64:32:64")),
|
||||
FrameInfo(TargetFrameInfo::StackGrowsDown,
|
||||
Subtarget.getStackAlignment(), Subtarget.is64Bit() ? -8 : -4),
|
||||
InstrInfo(*this), JITInfo(*this), TLInfo(*this) {
|
||||
|
@ -366,7 +366,6 @@ static Value *getBitCastOperand(Value *V) {
|
||||
|
||||
/// This function is a wrapper around CastInst::isEliminableCastPair. It
|
||||
/// simply extracts arguments and returns what that function returns.
|
||||
/// @Determine if it is valid to eliminate a Convert pair
|
||||
static Instruction::CastOps
|
||||
isEliminableCastPair(
|
||||
const CastInst *CI, ///< The first cast instruction
|
||||
@ -5813,8 +5812,8 @@ Instruction *InstCombiner::PromoteCastOfAllocation(CastInst &CI,
|
||||
const Type *CastElTy = PTy->getElementType();
|
||||
if (!AllocElTy->isSized() || !CastElTy->isSized()) return 0;
|
||||
|
||||
unsigned AllocElTyAlign = TD->getTypeAlignmentABI(AllocElTy);
|
||||
unsigned CastElTyAlign = TD->getTypeAlignmentABI(CastElTy);
|
||||
unsigned AllocElTyAlign = TD->getABITypeAlignment(AllocElTy);
|
||||
unsigned CastElTyAlign = TD->getABITypeAlignment(CastElTy);
|
||||
if (CastElTyAlign < AllocElTyAlign) return 0;
|
||||
|
||||
// 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)) {
|
||||
unsigned Align = GV->getAlignment();
|
||||
if (Align == 0 && TD)
|
||||
Align = TD->getTypeAlignmentPref(GV->getType()->getElementType());
|
||||
Align = TD->getPrefTypeAlignment(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->getTypeAlignmentPref(AI->getType()->getElementType());
|
||||
Align = TD->getPrefTypeAlignment(AI->getType()->getElementType());
|
||||
else if (isa<MallocInst>(AI)) {
|
||||
// Malloc returns maximally aligned memory.
|
||||
Align = TD->getTypeAlignmentABI(AI->getType()->getElementType());
|
||||
Align = TD->getABITypeAlignment(AI->getType()->getElementType());
|
||||
Align =
|
||||
std::max(Align,
|
||||
(unsigned)TD->getTypeAlignmentABI(Type::DoubleTy));
|
||||
(unsigned)TD->getABITypeAlignment(Type::DoubleTy));
|
||||
Align =
|
||||
std::max(Align,
|
||||
(unsigned)TD->getTypeAlignmentABI(Type::Int64Ty));
|
||||
(unsigned)TD->getABITypeAlignment(Type::Int64Ty));
|
||||
}
|
||||
}
|
||||
return Align;
|
||||
@ -6954,11 +6953,11 @@ static unsigned GetKnownAlignment(Value *V, TargetData *TD) {
|
||||
|
||||
const Type *BasePtrTy = GEPI->getOperand(0)->getType();
|
||||
const PointerType *PtrTy = cast<PointerType>(BasePtrTy);
|
||||
if (TD->getTypeAlignmentABI(PtrTy->getElementType())
|
||||
if (TD->getABITypeAlignment(PtrTy->getElementType())
|
||||
<= BaseAlignment) {
|
||||
const Type *GEPTy = GEPI->getType();
|
||||
const PointerType *GEPPtrTy = cast<PointerType>(GEPTy);
|
||||
return TD->getTypeAlignmentABI(GEPPtrTy->getElementType());
|
||||
return TD->getABITypeAlignment(GEPPtrTy->getElementType());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -8550,8 +8549,10 @@ static bool CheapToScalarize(Value *V, bool isConstant) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/// getShuffleMask - Read and decode a shufflevector mask. It turns undef
|
||||
/// elements into values that are larger than the #elts in the input.
|
||||
/// Read and decode a shufflevector mask.
|
||||
///
|
||||
/// 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) {
|
||||
unsigned NElts = SVI->getType()->getNumElements();
|
||||
if (isa<ConstantAggregateZero>(SVI->getOperand(2)))
|
||||
|
Loading…
Reference in New Issue
Block a user