mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
add the ability for TargetData to return information about legal integer
datatypes on a given CPU. This is intended to allow instcombine and other transformations to avoid converting big sequences of operations to an inconvenient width, and will help clean up after SRoA. See also "Adding legal integer sizes to TargetData" on Feb 1, 2009 on llvmdev, and PR3451. Comments welcome. llvm-svn: 86370
This commit is contained in:
parent
f99bf8cb76
commit
cdefc1c441
@ -1215,6 +1215,13 @@ target datalayout = "<i>layout specification</i>"
|
|||||||
<dt><tt>s<i>size</i>:<i>abi</i>:<i>pref</i></tt></dt>
|
<dt><tt>s<i>size</i>:<i>abi</i>:<i>pref</i></tt></dt>
|
||||||
<dd>This specifies the alignment for a stack object of a given bit
|
<dd>This specifies the alignment for a stack object of a given bit
|
||||||
<i>size</i>.</dd>
|
<i>size</i>.</dd>
|
||||||
|
|
||||||
|
<dt><tt>n<i>size1</i>:<i>size2</i>:<i>size3</i>...</tt></dt>
|
||||||
|
<dd>This specifies a set of native integer widths for the target CPU
|
||||||
|
in bits. For example, it might contain "n32" for 32-bit PowerPC,
|
||||||
|
"n32:64" for PowerPC 64, or "n8:16:32:64" for X86-64. Elements of
|
||||||
|
this set are considered to support most general arithmetic
|
||||||
|
operations efficiently.</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
<p>When constructing the data layout for a given target, LLVM starts with a
|
<p>When constructing the data layout for a given target, LLVM starts with a
|
||||||
|
@ -70,6 +70,8 @@ private:
|
|||||||
unsigned char PointerABIAlign; ///< Pointer ABI alignment
|
unsigned char PointerABIAlign; ///< Pointer ABI alignment
|
||||||
unsigned char PointerPrefAlign; ///< Pointer preferred alignment
|
unsigned char PointerPrefAlign; ///< Pointer preferred alignment
|
||||||
|
|
||||||
|
SmallVector<unsigned char, 8> LegalIntWidths; ///< Legal Integers.
|
||||||
|
|
||||||
/// Alignments- Where the primitive type alignment data is stored.
|
/// Alignments- Where the primitive type alignment data is stored.
|
||||||
///
|
///
|
||||||
/// @sa init().
|
/// @sa init().
|
||||||
@ -78,12 +80,8 @@ private:
|
|||||||
/// we don't.
|
/// we don't.
|
||||||
SmallVector<TargetAlignElem, 16> Alignments;
|
SmallVector<TargetAlignElem, 16> Alignments;
|
||||||
|
|
||||||
|
/// InvalidAlignmentElem - This member is a signal that a requested alignment
|
||||||
|
/// type and bit width were not found in the SmallVector.
|
||||||
/*!
|
|
||||||
This member is a signal that a requested alignment type and bit width were
|
|
||||||
not found in the SmallVector.
|
|
||||||
*/
|
|
||||||
static const TargetAlignElem InvalidAlignmentElem;
|
static const TargetAlignElem InvalidAlignmentElem;
|
||||||
|
|
||||||
// Opaque pointer for the StructType -> StructLayout map.
|
// Opaque pointer for the StructType -> StructLayout map.
|
||||||
@ -127,6 +125,7 @@ public:
|
|||||||
PointerMemSize(TD.PointerMemSize),
|
PointerMemSize(TD.PointerMemSize),
|
||||||
PointerABIAlign(TD.PointerABIAlign),
|
PointerABIAlign(TD.PointerABIAlign),
|
||||||
PointerPrefAlign(TD.PointerPrefAlign),
|
PointerPrefAlign(TD.PointerPrefAlign),
|
||||||
|
LegalIntWidths(TD.LegalIntWidths),
|
||||||
Alignments(TD.Alignments),
|
Alignments(TD.Alignments),
|
||||||
LayoutMap(0)
|
LayoutMap(0)
|
||||||
{ }
|
{ }
|
||||||
@ -137,13 +136,33 @@ public:
|
|||||||
void init(StringRef TargetDescription);
|
void init(StringRef TargetDescription);
|
||||||
|
|
||||||
/// Target endianness...
|
/// Target endianness...
|
||||||
bool isLittleEndian() const { return LittleEndian; }
|
bool isLittleEndian() const { return LittleEndian; }
|
||||||
bool isBigEndian() const { return !LittleEndian; }
|
bool isBigEndian() const { return !LittleEndian; }
|
||||||
|
|
||||||
/// getStringRepresentation - Return the string representation of the
|
/// getStringRepresentation - Return the string representation of the
|
||||||
/// TargetData. This representation is in the same format accepted by the
|
/// TargetData. This representation is in the same format accepted by the
|
||||||
/// string constructor above.
|
/// string constructor above.
|
||||||
std::string getStringRepresentation() const;
|
std::string getStringRepresentation() const;
|
||||||
|
|
||||||
|
|
||||||
|
/// isIllegalInteger - This function returns true if the specified type is
|
||||||
|
/// known to not be a native integer type supported by the CPU. For example,
|
||||||
|
/// i64 is not native on most 32-bit CPUs and i37 is not native on any known
|
||||||
|
/// one. This returns false if the integer width is legal or we don't know.
|
||||||
|
///
|
||||||
|
/// The width is specified in bits.
|
||||||
|
///
|
||||||
|
bool isIllegalInteger(unsigned Width) const {
|
||||||
|
// If we don't have information about legal integer types, don't claim the
|
||||||
|
// type is illegal.
|
||||||
|
if (LegalIntWidths.empty()) return false;
|
||||||
|
|
||||||
|
for (unsigned i = 0, e = LegalIntWidths.size(); i != e; ++i)
|
||||||
|
if (LegalIntWidths[i] == Width)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// Target pointer alignment
|
/// Target pointer alignment
|
||||||
unsigned char getPointerABIAlignment() const { return PointerABIAlign; }
|
unsigned char getPointerABIAlignment() const { return PointerABIAlign; }
|
||||||
/// Return target's alignment for stack-based pointers
|
/// Return target's alignment for stack-based pointers
|
||||||
|
@ -139,45 +139,7 @@ static unsigned getInt(StringRef R) {
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
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><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><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:@verbatim<size>:<abi_align>:<pref_align>@endverbatim</i>: Pointer size,
|
|
||||||
ABI and preferred alignment.
|
|
||||||
<br><br>
|
|
||||||
<i>@verbatim<type><size>:<abi_align>:<pref_align>@endverbatim</i>: Numeric type
|
|
||||||
alignment. Type is
|
|
||||||
one of <i>i|f|v|a</i>, corresponding to integer, floating point, vector, 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:8-f32:32:32-f64:64:64"
|
|
||||||
"-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32: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(StringRef Desc) {
|
void TargetData::init(StringRef Desc) {
|
||||||
|
|
||||||
LayoutMap = 0;
|
LayoutMap = 0;
|
||||||
LittleEndian = false;
|
LittleEndian = false;
|
||||||
PointerMemSize = 8;
|
PointerMemSize = 8;
|
||||||
@ -210,7 +172,7 @@ void TargetData::init(StringRef Desc) {
|
|||||||
|
|
||||||
assert(!Specifier.empty() && "Can't be empty here");
|
assert(!Specifier.empty() && "Can't be empty here");
|
||||||
|
|
||||||
switch(Specifier[0]) {
|
switch (Specifier[0]) {
|
||||||
case 'E':
|
case 'E':
|
||||||
LittleEndian = false;
|
LittleEndian = false;
|
||||||
break;
|
break;
|
||||||
@ -252,6 +214,17 @@ void TargetData::init(StringRef Desc) {
|
|||||||
setAlignment(AlignType, ABIAlign, PrefAlign, Size);
|
setAlignment(AlignType, ABIAlign, PrefAlign, Size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'n': // Native integer types.
|
||||||
|
Specifier = Specifier.substr(1);
|
||||||
|
do {
|
||||||
|
if (unsigned Width = getInt(Specifier))
|
||||||
|
LegalIntWidths.push_back(Width);
|
||||||
|
Split = Token.split(':');
|
||||||
|
Specifier = Split.first;
|
||||||
|
Token = Split.second;
|
||||||
|
} while (!Specifier.empty() || !Token.empty());
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user