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 | e4aeeaae8ee93ad5e07c646046c650d594f2775e (patch) | |
| tree | 15e86fddafdfc5456abaa521b5f6ed41e8ecd381 /lib/CodeGen/TargetInfo.cpp | |
| parent | b6932692234eba2472ef85a38434496e9342fd38 (diff) | |
Add padding inreg registers to cause llvm to skip ecx when needed with
the x86_fastcallcc calling convention.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166538 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/TargetInfo.cpp')
| -rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 534c8f685d..2c2d17df77 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/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) |
