mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 11:02:59 +02:00
Add support for having different alignment for objects on call frames.
The x86-64 ABI states that objects passed on the stack have 8 byte alignment. Implement that. llvm-svn: 41768
This commit is contained in:
parent
899c0c9c8d
commit
8c57e70f93
@ -38,7 +38,8 @@ enum AlignTypeEnum {
|
|||||||
INTEGER_ALIGN = 'i', ///< Integer type alignment
|
INTEGER_ALIGN = 'i', ///< Integer type alignment
|
||||||
VECTOR_ALIGN = 'v', ///< Vector type alignment
|
VECTOR_ALIGN = 'v', ///< Vector type alignment
|
||||||
FLOAT_ALIGN = 'f', ///< Floating point type alignment
|
FLOAT_ALIGN = 'f', ///< Floating point type alignment
|
||||||
AGGREGATE_ALIGN = 'a' ///< Aggregate alignment
|
AGGREGATE_ALIGN = 'a', ///< Aggregate alignment
|
||||||
|
STACK_ALIGN = 's' ///< Stack objects alignment
|
||||||
};
|
};
|
||||||
/// Target alignment element.
|
/// Target alignment element.
|
||||||
///
|
///
|
||||||
@ -166,6 +167,11 @@ public:
|
|||||||
/// specified type.
|
/// specified type.
|
||||||
unsigned char getABITypeAlignment(const Type *Ty) const;
|
unsigned char getABITypeAlignment(const Type *Ty) const;
|
||||||
|
|
||||||
|
/// getCallFrameTypeAlignment - Return the minimum ABI-required alignment
|
||||||
|
/// for the specified type when it is part of a call frame.
|
||||||
|
unsigned char getCallFrameTypeAlignment(const Type *Ty) const;
|
||||||
|
|
||||||
|
|
||||||
/// getPrefTypeAlignment - Return the preferred stack/global alignment for
|
/// getPrefTypeAlignment - Return the preferred stack/global alignment for
|
||||||
/// the specified type.
|
/// the specified type.
|
||||||
unsigned char getPrefTypeAlignment(const Type *Ty) const;
|
unsigned char getPrefTypeAlignment(const Type *Ty) const;
|
||||||
|
@ -3870,7 +3870,8 @@ TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
|
|||||||
Flags |= ISD::ParamFlags::ByVal;
|
Flags |= ISD::ParamFlags::ByVal;
|
||||||
const PointerType *Ty = cast<PointerType>(I->getType());
|
const PointerType *Ty = cast<PointerType>(I->getType());
|
||||||
const StructType *STy = cast<StructType>(Ty->getElementType());
|
const StructType *STy = cast<StructType>(Ty->getElementType());
|
||||||
unsigned StructAlign = Log2_32(getTargetData()->getABITypeAlignment(STy));
|
unsigned StructAlign =
|
||||||
|
Log2_32(getTargetData()->getCallFrameTypeAlignment(STy));
|
||||||
unsigned StructSize = getTargetData()->getTypeSize(STy);
|
unsigned StructSize = getTargetData()->getTypeSize(STy);
|
||||||
Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
|
Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
|
||||||
Flags |= (StructSize << ISD::ParamFlags::ByValSizeOffs);
|
Flags |= (StructSize << ISD::ParamFlags::ByValSizeOffs);
|
||||||
@ -3999,7 +4000,8 @@ TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
|
|||||||
Flags |= ISD::ParamFlags::ByVal;
|
Flags |= ISD::ParamFlags::ByVal;
|
||||||
const PointerType *Ty = cast<PointerType>(Args[i].Ty);
|
const PointerType *Ty = cast<PointerType>(Args[i].Ty);
|
||||||
const StructType *STy = cast<StructType>(Ty->getElementType());
|
const StructType *STy = cast<StructType>(Ty->getElementType());
|
||||||
unsigned StructAlign = Log2_32(getTargetData()->getABITypeAlignment(STy));
|
unsigned StructAlign =
|
||||||
|
Log2_32(getTargetData()->getCallFrameTypeAlignment(STy));
|
||||||
unsigned StructSize = getTargetData()->getTypeSize(STy);
|
unsigned StructSize = getTargetData()->getTypeSize(STy);
|
||||||
Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
|
Flags |= (StructAlign << ISD::ParamFlags::ByValAlignOffs);
|
||||||
Flags |= (StructSize << ISD::ParamFlags::ByValSizeOffs);
|
Flags |= (StructSize << ISD::ParamFlags::ByValSizeOffs);
|
||||||
|
@ -182,7 +182,8 @@ void TargetData::init(const std::string &TargetDescription) {
|
|||||||
setAlignment(VECTOR_ALIGN, 8, 8, 64); // v2i32
|
setAlignment(VECTOR_ALIGN, 8, 8, 64); // v2i32
|
||||||
setAlignment(VECTOR_ALIGN, 16, 16, 128); // v16i8, v8i16, v4i32, ...
|
setAlignment(VECTOR_ALIGN, 16, 16, 128); // v16i8, v8i16, v4i32, ...
|
||||||
setAlignment(AGGREGATE_ALIGN, 0, 8, 0); // struct, union, class, ...
|
setAlignment(AGGREGATE_ALIGN, 0, 8, 0); // struct, union, class, ...
|
||||||
|
setAlignment(STACK_ALIGN, 0, 8, 0); // objects on the stack
|
||||||
|
|
||||||
while (!temp.empty()) {
|
while (!temp.empty()) {
|
||||||
std::string token = getToken(temp, "-");
|
std::string token = getToken(temp, "-");
|
||||||
std::string arg0 = getToken(token, ":");
|
std::string arg0 = getToken(token, ":");
|
||||||
@ -204,10 +205,16 @@ void TargetData::init(const std::string &TargetDescription) {
|
|||||||
case 'i':
|
case 'i':
|
||||||
case 'v':
|
case 'v':
|
||||||
case 'f':
|
case 'f':
|
||||||
case 'a': {
|
case 'a':
|
||||||
AlignTypeEnum align_type =
|
case 's': {
|
||||||
(*p == 'i' ? INTEGER_ALIGN : (*p == 'f' ? FLOAT_ALIGN :
|
AlignTypeEnum align_type;
|
||||||
(*p == 'v' ? VECTOR_ALIGN : AGGREGATE_ALIGN)));
|
switch(*p) {
|
||||||
|
case 'i': align_type = INTEGER_ALIGN; break;
|
||||||
|
case 'v': align_type = VECTOR_ALIGN; break;
|
||||||
|
case 'f': align_type = FLOAT_ALIGN; break;
|
||||||
|
case 'a': align_type = AGGREGATE_ALIGN; break;
|
||||||
|
case 's': align_type = STACK_ALIGN; break;
|
||||||
|
}
|
||||||
uint32_t size = (uint32_t) atoi(++p);
|
uint32_t size = (uint32_t) atoi(++p);
|
||||||
unsigned char abi_align = atoi(getToken(token, ":").c_str()) / 8;
|
unsigned char abi_align = atoi(getToken(token, ":").c_str()) / 8;
|
||||||
unsigned char pref_align = atoi(getToken(token, ":").c_str()) / 8;
|
unsigned char pref_align = atoi(getToken(token, ":").c_str()) / 8;
|
||||||
@ -529,6 +536,14 @@ unsigned char TargetData::getABITypeAlignment(const Type *Ty) const {
|
|||||||
return getAlignment(Ty, true);
|
return getAlignment(Ty, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char TargetData::getCallFrameTypeAlignment(const Type *Ty) const {
|
||||||
|
for (unsigned i = 0, e = Alignments.size(); i != e; ++i)
|
||||||
|
if (Alignments[i].AlignType == STACK_ALIGN)
|
||||||
|
return Alignments[i].ABIAlign;
|
||||||
|
|
||||||
|
return getABITypeAlignment(Ty);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char TargetData::getPrefTypeAlignment(const Type *Ty) const {
|
unsigned char TargetData::getPrefTypeAlignment(const Type *Ty) const {
|
||||||
return getAlignment(Ty, false);
|
return getAlignment(Ty, false);
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ public:
|
|||||||
std::string getDataLayout() const {
|
std::string getDataLayout() const {
|
||||||
const char *p;
|
const char *p;
|
||||||
if (is64Bit())
|
if (is64Bit())
|
||||||
p = "e-p:64:64-f64:64:64-i64:64:64-f80:128:128";
|
p = "e-p:64:64-s:64-f64:64:64-i64:64:64-f80:128:128";
|
||||||
else {
|
else {
|
||||||
if (isTargetDarwin())
|
if (isTargetDarwin())
|
||||||
p = "e-p:32:32-f64:32:64-i64:32:64-f80:128:128";
|
p = "e-p:32:32-f64:32:64-i64:32:64-f80:128:128";
|
||||||
|
25
test/CodeGen/X86/byval3.ll
Normal file
25
test/CodeGen/X86/byval3.ll
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
; RUN: llvm-as < %s | llc -march=x86-64 | grep rep.movsl | count 2
|
||||||
|
|
||||||
|
%struct.s = type { i32, i32, i32, i32, i32, i32 }
|
||||||
|
|
||||||
|
define void @g(i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6) {
|
||||||
|
entry:
|
||||||
|
%d = alloca %struct.s, align 16
|
||||||
|
%tmp = getelementptr %struct.s* %d, i32 0, i32 0
|
||||||
|
store i32 %a1, i32* %tmp, align 16
|
||||||
|
%tmp2 = getelementptr %struct.s* %d, i32 0, i32 1
|
||||||
|
store i32 %a2, i32* %tmp2, align 16
|
||||||
|
%tmp4 = getelementptr %struct.s* %d, i32 0, i32 2
|
||||||
|
store i32 %a3, i32* %tmp4, align 16
|
||||||
|
%tmp6 = getelementptr %struct.s* %d, i32 0, i32 3
|
||||||
|
store i32 %a4, i32* %tmp6, align 16
|
||||||
|
%tmp8 = getelementptr %struct.s* %d, i32 0, i32 4
|
||||||
|
store i32 %a5, i32* %tmp8, align 16
|
||||||
|
%tmp10 = getelementptr %struct.s* %d, i32 0, i32 5
|
||||||
|
store i32 %a6, i32* %tmp10, align 16
|
||||||
|
call void @f( %struct.s* %d byval)
|
||||||
|
call void @f( %struct.s* %d byval)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @f(%struct.s* byval)
|
Loading…
Reference in New Issue
Block a user