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:
Chris Lattner 2007-02-14 05:52:17 +00:00
parent 879dfe1c9c
commit d2b7cec527
13 changed files with 442 additions and 399 deletions

View File

@ -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).

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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());

View File

@ -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

View File

@ -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 {

View File

@ -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) {}

View File

@ -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.

View File

@ -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() ||

View File

@ -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;
}

View File

@ -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) {

View File

@ -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)))