diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2012-10-24 01:59:00 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2012-10-24 01:59:00 +0000 |
commit | fad28de40c545b053364528f1aa5864ab289e897 (patch) | |
tree | 747dbc20edae512ef1482b9d8a0fa6ea2c4d7609 /clang/lib/CodeGen/TargetInfo.cpp | |
parent | 077dd593715c6c869d8e092793f2d9b1d662fefc (diff) | |
download | bcm5719-llvm-fad28de40c545b053364528f1aa5864ab289e897.tar.gz bcm5719-llvm-fad28de40c545b053364528f1aa5864ab289e897.zip |
Add padding inreg registers to cause llvm to skip ecx when needed with
the x86_fastcallcc calling convention.
llvm-svn: 166538
Diffstat (limited to 'clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | clang/lib/CodeGen/TargetInfo.cpp | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp index 534c8f685d5..2c2d17df77b 100644 --- a/clang/lib/CodeGen/TargetInfo.cpp +++ b/clang/lib/CodeGen/TargetInfo.cpp @@ -531,7 +531,7 @@ class X86_32ABIInfo : public ABIInfo { ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs, bool IsFastCall) const; bool shouldUseInReg(QualType Ty, unsigned &FreeRegs, - bool IsFastCall) const; + bool IsFastCall, bool &NeedsPadding) const; public: @@ -807,7 +807,8 @@ X86_32ABIInfo::Class X86_32ABIInfo::classify(QualType Ty) const { } bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs, - bool IsFastCall) const { + bool IsFastCall, bool &NeedsPadding) const { + NeedsPadding = false; Class C = classify(Ty); if (C == Float) return false; @@ -838,6 +839,9 @@ bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs, if (Ty->isReferenceType()) return true; + if (FreeRegs) + NeedsPadding = true; + return false; } @@ -864,16 +868,18 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, if (isEmptyRecord(getContext(), Ty, true)) return ABIArgInfo::getIgnore(); - if (shouldUseInReg(Ty, FreeRegs, IsFastCall)) { + llvm::LLVMContext &LLVMContext = getVMContext(); + llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext); + bool NeedsPadding; + if (shouldUseInReg(Ty, FreeRegs, IsFastCall, NeedsPadding)) { unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32; - llvm::LLVMContext &LLVMContext = getVMContext(); - llvm::Type *Int32 = llvm::Type::getInt32Ty(LLVMContext); SmallVector<llvm::Type*, 3> Elements; for (unsigned I = 0; I < SizeInRegs; ++I) Elements.push_back(Int32); llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements); return ABIArgInfo::getDirectInReg(Result); } + llvm::IntegerType *PaddingType = NeedsPadding ? Int32 : 0; // Expand small (<= 128-bit) record types when we know that the stack layout // of those arguments will match the struct. This is important because the @@ -881,7 +887,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, // optimizations. if (getContext().getTypeSize(Ty) <= 4*32 && canExpandIndirectArgument(Ty, getContext())) - return ABIArgInfo::getExpand(); + return ABIArgInfo::getExpandWithPadding(IsFastCall, PaddingType); return getIndirectResult(Ty, true, FreeRegs); } @@ -914,7 +920,8 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, if (const EnumType *EnumTy = Ty->getAs<EnumType>()) Ty = EnumTy->getDecl()->getIntegerType(); - bool InReg = shouldUseInReg(Ty, FreeRegs, IsFastCall); + bool NeedsPadding; + bool InReg = shouldUseInReg(Ty, FreeRegs, IsFastCall, NeedsPadding); if (Ty->isPromotableIntegerType()) { if (InReg) |