r199532 - Refactor ABI argument lowering a little
Reid Kleckner
reid at kleckner.net
Fri Jan 17 17:12:42 PST 2014
Author: rnk
Date: Fri Jan 17 19:12:41 2014
New Revision: 199532
URL: http://llvm.org/viewvc/llvm-project?rev=199532&view=rev
Log:
Refactor ABI argument lowering a little
Currently it tracks the number of free registers, but soon it will track
stack offsets for inalloca lowering.
No functional change.
Modified:
cfe/trunk/lib/CodeGen/TargetInfo.cpp
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=199532&r1=199531&r2=199532&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Fri Jan 17 19:12:41 2014
@@ -526,6 +526,14 @@ static llvm::Type* X86AdjustInlineAsmTyp
// X86-32 ABI Implementation
//===----------------------------------------------------------------------===//
+/// \brief Similar to llvm::CCState, but for Clang.
+struct CCState {
+ CCState(unsigned CC) : CC(CC), FreeRegs(0) {}
+
+ unsigned CC;
+ unsigned FreeRegs;
+};
+
/// X86_32ABIInfo - The X86-32 ABI information.
class X86_32ABIInfo : public ABIInfo {
enum Class {
@@ -549,19 +557,17 @@ class X86_32ABIInfo : public ABIInfo {
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
/// such that the argument will be passed in memory.
- ABIArgInfo getIndirectResult(QualType Ty, bool ByVal,
- unsigned &FreeRegs) const;
+ ABIArgInfo getIndirectResult(QualType Ty, bool ByVal, CCState &State) const;
+
+ ABIArgInfo getIndirectReturnResult(CCState &State) const;
/// \brief Return the alignment to use for the given type on the stack.
unsigned getTypeStackAlignInBytes(QualType Ty, unsigned Align) const;
Class classify(QualType Ty) const;
- ABIArgInfo classifyReturnType(QualType RetTy,
- unsigned callingConvention) const;
- ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs,
- bool IsFastCall) const;
- bool shouldUseInReg(QualType Ty, unsigned &FreeRegs,
- bool IsFastCall, bool &NeedsPadding) const;
+ ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const;
+ ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const;
+ bool shouldUseInReg(QualType Ty, CCState &State, bool &NeedsPadding) const;
public:
@@ -677,8 +683,18 @@ bool X86_32ABIInfo::shouldReturnTypeInRe
return true;
}
-ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
- unsigned callingConvention) const {
+ABIArgInfo X86_32ABIInfo::getIndirectReturnResult(CCState &State) const {
+ // If the return value is indirect, then the hidden argument is consuming one
+ // integer register.
+ if (State.FreeRegs) {
+ --State.FreeRegs;
+ return ABIArgInfo::getIndirectInReg(/*Align=*/0, /*ByVal=*/false);
+ }
+ return ABIArgInfo::getIndirect(/*Align=*/0, /*ByVal=*/false);
+}
+
+ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
+ CCState &State) const {
if (RetTy->isVoidType())
return ABIArgInfo::getIgnore();
@@ -701,7 +717,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturn
return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
Size));
- return ABIArgInfo::getIndirect(0);
+ return getIndirectReturnResult(State);
}
return ABIArgInfo::getDirect();
@@ -710,21 +726,21 @@ ABIArgInfo X86_32ABIInfo::classifyReturn
if (isAggregateTypeForABI(RetTy)) {
if (const RecordType *RT = RetTy->getAs<RecordType>()) {
if (isRecordReturnIndirect(RT, getCXXABI()))
- return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+ return getIndirectReturnResult(State);
// Structures with flexible arrays are always indirect.
if (RT->getDecl()->hasFlexibleArrayMember())
- return ABIArgInfo::getIndirect(0);
+ return getIndirectReturnResult(State);
}
// If specified, structs and unions are always indirect.
if (!IsSmallStructInRegABI && !RetTy->isAnyComplexType())
- return ABIArgInfo::getIndirect(0);
+ return getIndirectReturnResult(State);
// Small structures which are register sized are generally returned
// in a register.
- if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext(),
- callingConvention)) {
+ if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext(),
+ State.CC)) {
uint64_t Size = getContext().getTypeSize(RetTy);
// As a special-case, if the struct is a "single-element" struct, and
@@ -742,7 +758,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturn
return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),Size));
}
- return ABIArgInfo::getIndirect(0);
+ return getIndirectReturnResult(State);
}
// Treat an enum type as its underlying type.
@@ -806,10 +822,10 @@ unsigned X86_32ABIInfo::getTypeStackAlig
}
ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty, bool ByVal,
- unsigned &FreeRegs) const {
+ CCState &State) const {
if (!ByVal) {
- if (FreeRegs) {
- --FreeRegs; // Non-byval indirects just use one pointer.
+ if (State.FreeRegs) {
+ --State.FreeRegs; // Non-byval indirects just use one pointer.
return ABIArgInfo::getIndirectInReg(0, false);
}
return ABIArgInfo::getIndirect(0, false);
@@ -843,8 +859,8 @@ X86_32ABIInfo::Class X86_32ABIInfo::clas
return Integer;
}
-bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs,
- bool IsFastCall, bool &NeedsPadding) const {
+bool X86_32ABIInfo::shouldUseInReg(QualType Ty, CCState &State,
+ bool &NeedsPadding) const {
NeedsPadding = false;
Class C = classify(Ty);
if (C == Float)
@@ -856,14 +872,14 @@ bool X86_32ABIInfo::shouldUseInReg(QualT
if (SizeInRegs == 0)
return false;
- if (SizeInRegs > FreeRegs) {
- FreeRegs = 0;
+ if (SizeInRegs > State.FreeRegs) {
+ State.FreeRegs = 0;
return false;
}
- FreeRegs -= SizeInRegs;
+ State.FreeRegs -= SizeInRegs;
- if (IsFastCall) {
+ if (State.CC == llvm::CallingConv::X86_FastCall) {
if (Size > 32)
return false;
@@ -876,7 +892,7 @@ bool X86_32ABIInfo::shouldUseInReg(QualT
if (Ty->isReferenceType())
return true;
- if (FreeRegs)
+ if (State.FreeRegs)
NeedsPadding = true;
return false;
@@ -885,21 +901,20 @@ bool X86_32ABIInfo::shouldUseInReg(QualT
return true;
}
-ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
- unsigned &FreeRegs,
- bool IsFastCall) const {
+ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State) const {
// FIXME: Set alignment on indirect arguments.
if (isAggregateTypeForABI(Ty)) {
if (const RecordType *RT = Ty->getAs<RecordType>()) {
if (IsWin32StructABI)
- return getIndirectResult(Ty, true, FreeRegs);
+ return getIndirectResult(Ty, true, State);
if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI()))
- return getIndirectResult(Ty, RAA == CGCXXABI::RAA_DirectInMemory, FreeRegs);
+ return getIndirectResult(Ty, RAA == CGCXXABI::RAA_DirectInMemory,
+ State);
// Structures with flexible arrays are always indirect.
if (RT->getDecl()->hasFlexibleArrayMember())
- return getIndirectResult(Ty, true, FreeRegs);
+ return getIndirectResult(Ty, true, State);
}
// Ignore empty structs/unions.
@@ -909,7 +924,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgume
llvm::LLVMContext &LLVMContext = getVMContext();
llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext);
bool NeedsPadding;
- if (shouldUseInReg(Ty, FreeRegs, IsFastCall, NeedsPadding)) {
+ if (shouldUseInReg(Ty, State, NeedsPadding)) {
unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
SmallVector<llvm::Type*, 3> Elements(SizeInRegs, Int32);
llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements);
@@ -923,9 +938,10 @@ ABIArgInfo X86_32ABIInfo::classifyArgume
// optimizations.
if (getContext().getTypeSize(Ty) <= 4*32 &&
canExpandIndirectArgument(Ty, getContext()))
- return ABIArgInfo::getExpandWithPadding(IsFastCall, PaddingType);
+ return ABIArgInfo::getExpandWithPadding(
+ State.CC == llvm::CallingConv::X86_FastCall, PaddingType);
- return getIndirectResult(Ty, true, FreeRegs);
+ return getIndirectResult(Ty, true, State);
}
if (const VectorType *VT = Ty->getAs<VectorType>()) {
@@ -950,7 +966,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgume
Ty = EnumTy->getDecl()->getIntegerType();
bool NeedsPadding;
- bool InReg = shouldUseInReg(Ty, FreeRegs, IsFastCall, NeedsPadding);
+ bool InReg = shouldUseInReg(Ty, State, NeedsPadding);
if (Ty->isPromotableIntegerType()) {
if (InReg)
@@ -963,32 +979,19 @@ ABIArgInfo X86_32ABIInfo::classifyArgume
}
void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
- FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
- FI.getCallingConvention());
-
- unsigned CC = FI.getCallingConvention();
- bool IsFastCall = CC == llvm::CallingConv::X86_FastCall;
- unsigned FreeRegs;
- if (IsFastCall)
- FreeRegs = 2;
+ CCState State(FI.getCallingConvention());
+ if (State.CC == llvm::CallingConv::X86_FastCall)
+ State.FreeRegs = 2;
else if (FI.getHasRegParm())
- FreeRegs = FI.getRegParm();
+ State.FreeRegs = FI.getRegParm();
else
- FreeRegs = DefaultNumRegisterParameters;
+ State.FreeRegs = DefaultNumRegisterParameters;
- // If the return value is indirect, then the hidden argument is consuming one
- // integer register.
- if (FI.getReturnInfo().isIndirect() && FreeRegs) {
- --FreeRegs;
- ABIArgInfo &Old = FI.getReturnInfo();
- Old = ABIArgInfo::getIndirectInReg(Old.getIndirectAlign(),
- Old.getIndirectByVal(),
- Old.getIndirectRealign());
- }
+ FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), State);
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
it != ie; ++it)
- it->info = classifyArgumentType(it->type, FreeRegs, IsFastCall);
+ it->info = classifyArgumentType(it->type, State);
}
llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
More information about the cfe-commits
mailing list