Skip to content

Commit 661f35b

Browse files
committed
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. llvm-svn: 199532
1 parent 0abb057 commit 661f35b

File tree

1 file changed

+60
-57
lines changed

1 file changed

+60
-57
lines changed

clang/lib/CodeGen/TargetInfo.cpp

Lines changed: 60 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,14 @@ static llvm::Type* X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF,
526526
// X86-32 ABI Implementation
527527
//===----------------------------------------------------------------------===//
528528

529+
/// \brief Similar to llvm::CCState, but for Clang.
530+
struct CCState {
531+
CCState(unsigned CC) : CC(CC), FreeRegs(0) {}
532+
533+
unsigned CC;
534+
unsigned FreeRegs;
535+
};
536+
529537
/// X86_32ABIInfo - The X86-32 ABI information.
530538
class X86_32ABIInfo : public ABIInfo {
531539
enum Class {
@@ -549,19 +557,17 @@ class X86_32ABIInfo : public ABIInfo {
549557

550558
/// getIndirectResult - Give a source type \arg Ty, return a suitable result
551559
/// such that the argument will be passed in memory.
552-
ABIArgInfo getIndirectResult(QualType Ty, bool ByVal,
553-
unsigned &FreeRegs) const;
560+
ABIArgInfo getIndirectResult(QualType Ty, bool ByVal, CCState &State) const;
561+
562+
ABIArgInfo getIndirectReturnResult(CCState &State) const;
554563

555564
/// \brief Return the alignment to use for the given type on the stack.
556565
unsigned getTypeStackAlignInBytes(QualType Ty, unsigned Align) const;
557566

558567
Class classify(QualType Ty) const;
559-
ABIArgInfo classifyReturnType(QualType RetTy,
560-
unsigned callingConvention) const;
561-
ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs,
562-
bool IsFastCall) const;
563-
bool shouldUseInReg(QualType Ty, unsigned &FreeRegs,
564-
bool IsFastCall, bool &NeedsPadding) const;
568+
ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const;
569+
ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const;
570+
bool shouldUseInReg(QualType Ty, CCState &State, bool &NeedsPadding) const;
565571

566572
public:
567573

@@ -677,8 +683,18 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
677683
return true;
678684
}
679685

680-
ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
681-
unsigned callingConvention) const {
686+
ABIArgInfo X86_32ABIInfo::getIndirectReturnResult(CCState &State) const {
687+
// If the return value is indirect, then the hidden argument is consuming one
688+
// integer register.
689+
if (State.FreeRegs) {
690+
--State.FreeRegs;
691+
return ABIArgInfo::getIndirectInReg(/*Align=*/0, /*ByVal=*/false);
692+
}
693+
return ABIArgInfo::getIndirect(/*Align=*/0, /*ByVal=*/false);
694+
}
695+
696+
ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
697+
CCState &State) const {
682698
if (RetTy->isVoidType())
683699
return ABIArgInfo::getIgnore();
684700

@@ -701,7 +717,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
701717
return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
702718
Size));
703719

704-
return ABIArgInfo::getIndirect(0);
720+
return getIndirectReturnResult(State);
705721
}
706722

707723
return ABIArgInfo::getDirect();
@@ -710,21 +726,21 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
710726
if (isAggregateTypeForABI(RetTy)) {
711727
if (const RecordType *RT = RetTy->getAs<RecordType>()) {
712728
if (isRecordReturnIndirect(RT, getCXXABI()))
713-
return ABIArgInfo::getIndirect(0, /*ByVal=*/false);
729+
return getIndirectReturnResult(State);
714730

715731
// Structures with flexible arrays are always indirect.
716732
if (RT->getDecl()->hasFlexibleArrayMember())
717-
return ABIArgInfo::getIndirect(0);
733+
return getIndirectReturnResult(State);
718734
}
719735

720736
// If specified, structs and unions are always indirect.
721737
if (!IsSmallStructInRegABI && !RetTy->isAnyComplexType())
722-
return ABIArgInfo::getIndirect(0);
738+
return getIndirectReturnResult(State);
723739

724740
// Small structures which are register sized are generally returned
725741
// in a register.
726-
if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext(),
727-
callingConvention)) {
742+
if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext(),
743+
State.CC)) {
728744
uint64_t Size = getContext().getTypeSize(RetTy);
729745

730746
// As a special-case, if the struct is a "single-element" struct, and
@@ -742,7 +758,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
742758
return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),Size));
743759
}
744760

745-
return ABIArgInfo::getIndirect(0);
761+
return getIndirectReturnResult(State);
746762
}
747763

748764
// Treat an enum type as its underlying type.
@@ -806,10 +822,10 @@ unsigned X86_32ABIInfo::getTypeStackAlignInBytes(QualType Ty,
806822
}
807823

808824
ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty, bool ByVal,
809-
unsigned &FreeRegs) const {
825+
CCState &State) const {
810826
if (!ByVal) {
811-
if (FreeRegs) {
812-
--FreeRegs; // Non-byval indirects just use one pointer.
827+
if (State.FreeRegs) {
828+
--State.FreeRegs; // Non-byval indirects just use one pointer.
813829
return ABIArgInfo::getIndirectInReg(0, false);
814830
}
815831
return ABIArgInfo::getIndirect(0, false);
@@ -843,8 +859,8 @@ X86_32ABIInfo::Class X86_32ABIInfo::classify(QualType Ty) const {
843859
return Integer;
844860
}
845861

846-
bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs,
847-
bool IsFastCall, bool &NeedsPadding) const {
862+
bool X86_32ABIInfo::shouldUseInReg(QualType Ty, CCState &State,
863+
bool &NeedsPadding) const {
848864
NeedsPadding = false;
849865
Class C = classify(Ty);
850866
if (C == Float)
@@ -856,14 +872,14 @@ bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs,
856872
if (SizeInRegs == 0)
857873
return false;
858874

859-
if (SizeInRegs > FreeRegs) {
860-
FreeRegs = 0;
875+
if (SizeInRegs > State.FreeRegs) {
876+
State.FreeRegs = 0;
861877
return false;
862878
}
863879

864-
FreeRegs -= SizeInRegs;
880+
State.FreeRegs -= SizeInRegs;
865881

866-
if (IsFastCall) {
882+
if (State.CC == llvm::CallingConv::X86_FastCall) {
867883
if (Size > 32)
868884
return false;
869885

@@ -876,7 +892,7 @@ bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs,
876892
if (Ty->isReferenceType())
877893
return true;
878894

879-
if (FreeRegs)
895+
if (State.FreeRegs)
880896
NeedsPadding = true;
881897

882898
return false;
@@ -885,21 +901,20 @@ bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs,
885901
return true;
886902
}
887903

888-
ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
889-
unsigned &FreeRegs,
890-
bool IsFastCall) const {
904+
ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State) const {
891905
// FIXME: Set alignment on indirect arguments.
892906
if (isAggregateTypeForABI(Ty)) {
893907
if (const RecordType *RT = Ty->getAs<RecordType>()) {
894908
if (IsWin32StructABI)
895-
return getIndirectResult(Ty, true, FreeRegs);
909+
return getIndirectResult(Ty, true, State);
896910

897911
if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI()))
898-
return getIndirectResult(Ty, RAA == CGCXXABI::RAA_DirectInMemory, FreeRegs);
912+
return getIndirectResult(Ty, RAA == CGCXXABI::RAA_DirectInMemory,
913+
State);
899914

900915
// Structures with flexible arrays are always indirect.
901916
if (RT->getDecl()->hasFlexibleArrayMember())
902-
return getIndirectResult(Ty, true, FreeRegs);
917+
return getIndirectResult(Ty, true, State);
903918
}
904919

905920
// Ignore empty structs/unions.
@@ -909,7 +924,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
909924
llvm::LLVMContext &LLVMContext = getVMContext();
910925
llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext);
911926
bool NeedsPadding;
912-
if (shouldUseInReg(Ty, FreeRegs, IsFastCall, NeedsPadding)) {
927+
if (shouldUseInReg(Ty, State, NeedsPadding)) {
913928
unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
914929
SmallVector<llvm::Type*, 3> Elements(SizeInRegs, Int32);
915930
llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements);
@@ -923,9 +938,10 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
923938
// optimizations.
924939
if (getContext().getTypeSize(Ty) <= 4*32 &&
925940
canExpandIndirectArgument(Ty, getContext()))
926-
return ABIArgInfo::getExpandWithPadding(IsFastCall, PaddingType);
941+
return ABIArgInfo::getExpandWithPadding(
942+
State.CC == llvm::CallingConv::X86_FastCall, PaddingType);
927943

928-
return getIndirectResult(Ty, true, FreeRegs);
944+
return getIndirectResult(Ty, true, State);
929945
}
930946

931947
if (const VectorType *VT = Ty->getAs<VectorType>()) {
@@ -950,7 +966,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
950966
Ty = EnumTy->getDecl()->getIntegerType();
951967

952968
bool NeedsPadding;
953-
bool InReg = shouldUseInReg(Ty, FreeRegs, IsFastCall, NeedsPadding);
969+
bool InReg = shouldUseInReg(Ty, State, NeedsPadding);
954970

955971
if (Ty->isPromotableIntegerType()) {
956972
if (InReg)
@@ -963,32 +979,19 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
963979
}
964980

965981
void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const {
966-
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(),
967-
FI.getCallingConvention());
968-
969-
unsigned CC = FI.getCallingConvention();
970-
bool IsFastCall = CC == llvm::CallingConv::X86_FastCall;
971-
unsigned FreeRegs;
972-
if (IsFastCall)
973-
FreeRegs = 2;
982+
CCState State(FI.getCallingConvention());
983+
if (State.CC == llvm::CallingConv::X86_FastCall)
984+
State.FreeRegs = 2;
974985
else if (FI.getHasRegParm())
975-
FreeRegs = FI.getRegParm();
986+
State.FreeRegs = FI.getRegParm();
976987
else
977-
FreeRegs = DefaultNumRegisterParameters;
988+
State.FreeRegs = DefaultNumRegisterParameters;
978989

979-
// If the return value is indirect, then the hidden argument is consuming one
980-
// integer register.
981-
if (FI.getReturnInfo().isIndirect() && FreeRegs) {
982-
--FreeRegs;
983-
ABIArgInfo &Old = FI.getReturnInfo();
984-
Old = ABIArgInfo::getIndirectInReg(Old.getIndirectAlign(),
985-
Old.getIndirectByVal(),
986-
Old.getIndirectRealign());
987-
}
990+
FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), State);
988991

989992
for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end();
990993
it != ie; ++it)
991-
it->info = classifyArgumentType(it->type, FreeRegs, IsFastCall);
994+
it->info = classifyArgumentType(it->type, State);
992995
}
993996

994997
llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,

0 commit comments

Comments
 (0)