diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp | 2963 |
1 files changed, 2079 insertions, 884 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp index 45eaec6..5da22c3 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp @@ -23,6 +23,9 @@ #include "llvm/IR/DataLayout.h" #include "llvm/IR/Type.h" #include "llvm/Support/raw_ostream.h" + +#include <algorithm> // std::sort + using namespace clang; using namespace CodeGen; @@ -45,22 +48,6 @@ static bool isAggregateTypeForABI(QualType T) { ABIInfo::~ABIInfo() {} -static bool isRecordReturnIndirect(const RecordType *RT, - CGCXXABI &CXXABI) { - const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); - if (!RD) - return false; - return CXXABI.isReturnTypeIndirect(RD); -} - - -static bool isRecordReturnIndirect(QualType T, CGCXXABI &CXXABI) { - const RecordType *RT = T->getAs<RecordType>(); - if (!RT) - return false; - return isRecordReturnIndirect(RT, CXXABI); -} - static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI) { const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); @@ -114,6 +101,9 @@ void ABIArgInfo::dump() const { case Ignore: OS << "Ignore"; break; + case InAlloca: + OS << "InAlloca Offset=" << getInAllocaFieldIndex(); + break; case Indirect: OS << "Indirect Align=" << getIndirectAlign() << " ByVal=" << getIndirectByVal() @@ -206,14 +196,12 @@ static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) { // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) - for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(), - e = CXXRD->bases_end(); i != e; ++i) - if (!isEmptyRecord(Context, i->getType(), true)) + for (const auto &I : CXXRD->bases()) + if (!isEmptyRecord(Context, I.getType(), true)) return false; - for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); - i != e; ++i) - if (!isEmptyField(Context, *i, AllowArrays)) + for (const auto *I : RD->fields()) + if (!isEmptyField(Context, I, AllowArrays)) return false; return true; } @@ -229,38 +217,35 @@ static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) { static const Type *isSingleElementStruct(QualType T, ASTContext &Context) { const RecordType *RT = T->getAsStructureType(); if (!RT) - return 0; + return nullptr; const RecordDecl *RD = RT->getDecl(); if (RD->hasFlexibleArrayMember()) - return 0; + return nullptr; - const Type *Found = 0; + const Type *Found = nullptr; // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { - for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(), - e = CXXRD->bases_end(); i != e; ++i) { + for (const auto &I : CXXRD->bases()) { // Ignore empty records. - if (isEmptyRecord(Context, i->getType(), true)) + if (isEmptyRecord(Context, I.getType(), true)) continue; // If we already found an element then this isn't a single-element struct. if (Found) - return 0; + return nullptr; // If this is non-empty and not a single element struct, the composite // cannot be a single element struct. - Found = isSingleElementStruct(i->getType(), Context); + Found = isSingleElementStruct(I.getType(), Context); if (!Found) - return 0; + return nullptr; } } // Check for single element. - for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); - i != e; ++i) { - const FieldDecl *FD = *i; + for (const auto *FD : RD->fields()) { QualType FT = FD->getType(); // Ignore empty fields. @@ -270,7 +255,7 @@ static const Type *isSingleElementStruct(QualType T, ASTContext &Context) { // If we already found an element then this isn't a single-element // struct. if (Found) - return 0; + return nullptr; // Treat single element arrays as the element. while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) { @@ -284,14 +269,14 @@ static const Type *isSingleElementStruct(QualType T, ASTContext &Context) { } else { Found = isSingleElementStruct(FT, Context); if (!Found) - return 0; + return nullptr; } } // We don't consider a struct a single-element struct if it has // padding beyond the element type. if (Found && Context.getTypeSize(Found) != Context.getTypeSize(T)) - return 0; + return nullptr; return Found; } @@ -336,10 +321,7 @@ static bool canExpandIndirectArgument(QualType Ty, ASTContext &Context) { uint64_t Size = 0; - for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); - i != e; ++i) { - const FieldDecl *FD = *i; - + for (const auto *FD : RD->fields()) { if (!is32Or64BitBasicType(FD->getType(), Context)) return false; @@ -371,15 +353,15 @@ public: ABIArgInfo classifyReturnType(QualType RetTy) const; ABIArgInfo classifyArgumentType(QualType RetTy) const; - virtual void computeInfo(CGFunctionInfo &FI) const { - FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); - it != ie; ++it) - it->info = classifyArgumentType(it->type); + void computeInfo(CGFunctionInfo &FI) const override { + if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + for (auto &I : FI.arguments()) + I.info = classifyArgumentType(I.type); } - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; }; class DefaultTargetCodeGenInfo : public TargetCodeGenInfo { @@ -390,18 +372,12 @@ public: llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const { - return 0; + return nullptr; } ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { - if (isAggregateTypeForABI(Ty)) { - // Records with non trivial destructors/constructors should not be passed - // by value. - if (isRecordReturnIndirect(Ty, getCXXABI())) - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); - + if (isAggregateTypeForABI(Ty)) return ABIArgInfo::getIndirect(0); - } // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs<EnumType>()) @@ -440,9 +416,9 @@ class PNaClABIInfo : public ABIInfo { ABIArgInfo classifyReturnType(QualType RetTy) const; ABIArgInfo classifyArgumentType(QualType RetTy) const; - virtual void computeInfo(CGFunctionInfo &FI) const; - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + void computeInfo(CGFunctionInfo &FI) const override; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; }; class PNaClTargetCodeGenInfo : public TargetCodeGenInfo { @@ -452,16 +428,16 @@ class PNaClTargetCodeGenInfo : public TargetCodeGenInfo { }; void PNaClABIInfo::computeInfo(CGFunctionInfo &FI) const { + if (!getCXXABI().classifyReturnType(FI)) FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); - it != ie; ++it) - it->info = classifyArgumentType(it->type); - } + for (auto &I : FI.arguments()) + I.info = classifyArgumentType(I.type); +} llvm::Value *PNaClABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const { - return 0; + return nullptr; } /// \brief Classify argument of given type \p Ty. @@ -512,7 +488,7 @@ static llvm::Type* X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF, if ((Constraint == "y" || Constraint == "&y") && Ty->isVectorTy()) { if (cast<llvm::VectorType>(Ty)->getBitWidth() != 64) { // Invalid MMX constraint - return 0; + return nullptr; } return llvm::Type::getX86_MMXTy(CGF.getLLVMContext()); @@ -526,6 +502,16 @@ static llvm::Type* X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF, // 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; + unsigned StackOffset; + bool UseInAlloca; +}; + /// X86_32ABIInfo - The X86-32 ABI information. class X86_32ABIInfo : public ABIInfo { enum Class { @@ -544,30 +530,35 @@ class X86_32ABIInfo : public ABIInfo { return (Size == 8 || Size == 16 || Size == 32 || Size == 64); } - static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context, - unsigned callingConvention); + bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context) const; /// 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; + + /// \brief Rewrite the function info so that all memory arguments use + /// inalloca. + void rewriteWithInAlloca(CGFunctionInfo &FI) const; + + void addFieldToArgStruct(SmallVector<llvm::Type *, 6> &FrameFields, + unsigned &StackOffset, ABIArgInfo &Info, + QualType Type) const; public: - virtual void computeInfo(CGFunctionInfo &FI) const; - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + void computeInfo(CGFunctionInfo &FI) const override; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool w, unsigned r) @@ -585,24 +576,25 @@ public: const llvm::Triple &Triple, const CodeGenOptions &Opts); void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, - CodeGen::CodeGenModule &CGM) const; + CodeGen::CodeGenModule &CGM) const override; - int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const { + int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override { // Darwin uses different dwarf register numbers for EH. if (CGM.getTarget().getTriple().isOSDarwin()) return 5; return 4; } bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, - llvm::Value *Address) const; + llvm::Value *Address) const override; llvm::Type* adjustInlineAsmType(CodeGen::CodeGenFunction &CGF, StringRef Constraint, - llvm::Type* Ty) const { + llvm::Type* Ty) const override { return X86AdjustInlineAsmType(CGF, Constraint, Ty); } - llvm::Constant *getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const { + llvm::Constant * + getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override { unsigned Sig = (0xeb << 0) | // jmp rel8 (0x06 << 8) | // .+0x08 ('F' << 16) | @@ -617,8 +609,7 @@ public: /// shouldReturnTypeInRegister - Determine if the given type should be /// passed in a register (for the Darwin ABI). bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty, - ASTContext &Context, - unsigned callingConvention) { + ASTContext &Context) const { uint64_t Size = Context.getTypeSize(Ty); // Type must be register sized. @@ -643,8 +634,7 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty, // Arrays are treated like records. if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) - return shouldReturnTypeInRegister(AT->getElementType(), Context, - callingConvention); + return shouldReturnTypeInRegister(AT->getElementType(), Context); // Otherwise, it must be a record type. const RecordType *RT = Ty->getAs<RecordType>(); @@ -652,33 +642,31 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty, // FIXME: Traverse bases here too. - // For thiscall conventions, structures will never be returned in - // a register. This is for compatibility with the MSVC ABI - if (callingConvention == llvm::CallingConv::X86_ThisCall && - RT->isStructureType()) { - return false; - } - // Structure types are passed in register if all fields would be // passed in a register. - for (RecordDecl::field_iterator i = RT->getDecl()->field_begin(), - e = RT->getDecl()->field_end(); i != e; ++i) { - const FieldDecl *FD = *i; - + for (const auto *FD : RT->getDecl()->fields()) { // Empty fields are ignored. if (isEmptyField(Context, FD, true)) continue; // Check fields recursively. - if (!shouldReturnTypeInRegister(FD->getType(), Context, - callingConvention)) + if (!shouldReturnTypeInRegister(FD->getType(), Context)) return false; } 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 +689,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size)); - return ABIArgInfo::getIndirect(0); + return getIndirectReturnResult(State); } return ABIArgInfo::getDirect(); @@ -709,22 +697,18 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, if (isAggregateTypeForABI(RetTy)) { if (const RecordType *RT = RetTy->getAs<RecordType>()) { - if (isRecordReturnIndirect(RT, getCXXABI())) - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); - // 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 (shouldReturnTypeInRegister(RetTy, getContext())) { uint64_t Size = getContext().getTypeSize(RetTy); // As a special-case, if the struct is a "single-element" struct, and @@ -742,7 +726,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),Size)); } - return ABIArgInfo::getIndirect(0); + return getIndirectReturnResult(State); } // Treat an enum type as its underlying type. @@ -765,13 +749,11 @@ static bool isRecordWithSSEVectorType(ASTContext &Context, QualType Ty) { // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) - for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(), - e = CXXRD->bases_end(); i != e; ++i) - if (!isRecordWithSSEVectorType(Context, i->getType())) + for (const auto &I : CXXRD->bases()) + if (!isRecordWithSSEVectorType(Context, I.getType())) return false; - for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); - i != e; ++i) { + for (const auto *i : RD->fields()) { QualType FT = i->getType(); if (isSSEVectorType(Context, FT)) @@ -806,10 +788,10 @@ unsigned X86_32ABIInfo::getTypeStackAlignInBytes(QualType Ty, } 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); @@ -819,15 +801,12 @@ ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty, bool ByVal, unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8; unsigned StackAlign = getTypeStackAlignInBytes(Ty, TypeAlign); if (StackAlign == 0) - return ABIArgInfo::getIndirect(4); + return ABIArgInfo::getIndirect(4, /*ByVal=*/true); // If the stack alignment is less than the type alignment, realign the // argument. - if (StackAlign < TypeAlign) - return ABIArgInfo::getIndirect(StackAlign, /*ByVal=*/true, - /*Realign=*/true); - - return ABIArgInfo::getIndirect(StackAlign); + bool Realign = TypeAlign > StackAlign; + return ABIArgInfo::getIndirect(StackAlign, /*ByVal=*/true, Realign); } X86_32ABIInfo::Class X86_32ABIInfo::classify(QualType Ty) const { @@ -843,8 +822,8 @@ X86_32ABIInfo::Class X86_32ABIInfo::classify(QualType Ty) const { 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 +835,14 @@ bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs, 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 +855,7 @@ bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs, if (Ty->isReferenceType()) return true; - if (FreeRegs) + if (State.FreeRegs) NeedsPadding = true; return false; @@ -886,20 +865,26 @@ bool X86_32ABIInfo::shouldUseInReg(QualType Ty, unsigned &FreeRegs, } ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, - unsigned &FreeRegs, - bool IsFastCall) const { + 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); + // Check with the C++ ABI first. + CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI()); + if (RAA == CGCXXABI::RAA_Indirect) { + return getIndirectResult(Ty, false, State); + } else if (RAA == CGCXXABI::RAA_DirectInMemory) { + // The field index doesn't matter, we'll fix it up later. + return ABIArgInfo::getInAlloca(/*FieldIndex=*/0); + } - if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI())) - return getIndirectResult(Ty, RAA == CGCXXABI::RAA_DirectInMemory, FreeRegs); + // Structs are always byval on win32, regardless of what they contain. + if (IsWin32StructABI) + return getIndirectResult(Ty, true, 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,13 +894,13 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, 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); return ABIArgInfo::getDirectInReg(Result); } - llvm::IntegerType *PaddingType = NeedsPadding ? Int32 : 0; + llvm::IntegerType *PaddingType = NeedsPadding ? Int32 : nullptr; // 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 @@ -923,9 +908,10 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, // 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 +936,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, 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 +949,105 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, } 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 (!getCXXABI().classifyReturnType(FI)) { + FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), State); + } else if (FI.getReturnInfo().isIndirect()) { + // The C++ ABI is not aware of register usage, so we have to check if the + // return value was sret and put it in a register ourselves if appropriate. + if (State.FreeRegs) { + --State.FreeRegs; // The sret parameter consumes a register. + FI.getReturnInfo().setInReg(true); + } + } - // 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()); + bool UsedInAlloca = false; + for (auto &I : FI.arguments()) { + I.info = classifyArgumentType(I.type, State); + UsedInAlloca |= (I.info.getKind() == ABIArgInfo::InAlloca); } - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); - it != ie; ++it) - it->info = classifyArgumentType(it->type, FreeRegs, IsFastCall); + // If we needed to use inalloca for any argument, do a second pass and rewrite + // all the memory arguments to use inalloca. + if (UsedInAlloca) + rewriteWithInAlloca(FI); +} + +void +X86_32ABIInfo::addFieldToArgStruct(SmallVector<llvm::Type *, 6> &FrameFields, + unsigned &StackOffset, + ABIArgInfo &Info, QualType Type) const { + assert(StackOffset % 4U == 0 && "unaligned inalloca struct"); + Info = ABIArgInfo::getInAlloca(FrameFields.size()); + FrameFields.push_back(CGT.ConvertTypeForMem(Type)); + StackOffset += getContext().getTypeSizeInChars(Type).getQuantity(); + + // Insert padding bytes to respect alignment. For x86_32, each argument is 4 + // byte aligned. + if (StackOffset % 4U) { + unsigned OldOffset = StackOffset; + StackOffset = llvm::RoundUpToAlignment(StackOffset, 4U); + unsigned NumBytes = StackOffset - OldOffset; + assert(NumBytes); + llvm::Type *Ty = llvm::Type::getInt8Ty(getVMContext()); + Ty = llvm::ArrayType::get(Ty, NumBytes); + FrameFields.push_back(Ty); + } +} + +void X86_32ABIInfo::rewriteWithInAlloca(CGFunctionInfo &FI) const { + assert(IsWin32StructABI && "inalloca only supported on win32"); + + // Build a packed struct type for all of the arguments in memory. + SmallVector<llvm::Type *, 6> FrameFields; + + unsigned StackOffset = 0; + + // Put the sret parameter into the inalloca struct if it's in memory. + ABIArgInfo &Ret = FI.getReturnInfo(); + if (Ret.isIndirect() && !Ret.getInReg()) { + CanQualType PtrTy = getContext().getPointerType(FI.getReturnType()); + addFieldToArgStruct(FrameFields, StackOffset, Ret, PtrTy); + // On Windows, the hidden sret parameter is always returned in eax. + Ret.setInAllocaSRet(IsWin32StructABI); + } + + // Skip the 'this' parameter in ecx. + CGFunctionInfo::arg_iterator I = FI.arg_begin(), E = FI.arg_end(); + if (FI.getCallingConvention() == llvm::CallingConv::X86_ThisCall) + ++I; + + // Put arguments passed in memory into the struct. + for (; I != E; ++I) { + + // Leave ignored and inreg arguments alone. + switch (I->info.getKind()) { + case ABIArgInfo::Indirect: + assert(I->info.getIndirectByVal()); + break; + case ABIArgInfo::Ignore: + continue; + case ABIArgInfo::Direct: + case ABIArgInfo::Extend: + if (I->info.getInReg()) + continue; + break; + default: + break; + } + + addFieldToArgStruct(FrameFields, StackOffset, I->info, I->type); + } + + FI.setArgStruct(llvm::StructType::get(getVMContext(), FrameFields, + /*isPacked=*/true)); } llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, @@ -1031,6 +1090,44 @@ llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, return AddrTyped; } +bool X86_32TargetCodeGenInfo::isStructReturnInRegABI( + const llvm::Triple &Triple, const CodeGenOptions &Opts) { + assert(Triple.getArch() == llvm::Triple::x86); + + switch (Opts.getStructReturnConvention()) { + case CodeGenOptions::SRCK_Default: + break; + case CodeGenOptions::SRCK_OnStack: // -fpcc-struct-return + return false; + case CodeGenOptions::SRCK_InRegs: // -freg-struct-return + return true; + } + + if (Triple.isOSDarwin()) + return true; + + switch (Triple.getOS()) { + case llvm::Triple::AuroraUX: + case llvm::Triple::DragonFly: + case llvm::Triple::FreeBSD: + case llvm::Triple::OpenBSD: + case llvm::Triple::Bitrig: + return true; + case llvm::Triple::Win32: + switch (Triple.getEnvironment()) { + case llvm::Triple::UnknownEnvironment: + case llvm::Triple::Cygnus: + case llvm::Triple::GNU: + case llvm::Triple::MSVC: + return true; + default: + return false; + } + default: + return false; + } +} + void X86_32TargetCodeGenInfo::SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const { @@ -1219,10 +1316,10 @@ public: return false; } - virtual void computeInfo(CGFunctionInfo &FI) const; + void computeInfo(CGFunctionInfo &FI) const override; - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; }; /// WinX86_64ABIInfo - The Windows X86_64 ABI information. @@ -1233,10 +1330,10 @@ class WinX86_64ABIInfo : public ABIInfo { public: WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {} - virtual void computeInfo(CGFunctionInfo &FI) const; + void computeInfo(CGFunctionInfo &FI) const override; - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; }; class X86_64TargetCodeGenInfo : public TargetCodeGenInfo { @@ -1248,12 +1345,12 @@ public: return static_cast<const X86_64ABIInfo&>(TargetCodeGenInfo::getABIInfo()); } - int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const { + int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override { return 7; } bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, - llvm::Value *Address) const { + llvm::Value *Address) const override { llvm::Value *Eight8 = llvm::ConstantInt::get(CGF.Int8Ty, 8); // 0-15 are the 16 integer registers. @@ -1264,12 +1361,12 @@ public: llvm::Type* adjustInlineAsmType(CodeGen::CodeGenFunction &CGF, StringRef Constraint, - llvm::Type* Ty) const { + llvm::Type* Ty) const override { return X86AdjustInlineAsmType(CGF, Constraint, Ty); } bool isNoProtoCallVariadic(const CallArgList &args, - const FunctionNoProtoType *fnType) const { + const FunctionNoProtoType *fnType) const override { // The default CC on x86-64 sets %al to the number of SSA // registers used, and GCC sets this when calling an unprototyped // function, so we override the default behavior. However, don't do @@ -1293,7 +1390,8 @@ public: return TargetCodeGenInfo::isNoProtoCallVariadic(args, fnType); } - llvm::Constant *getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const { + llvm::Constant * + getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override { unsigned Sig = (0xeb << 0) | // jmp rel8 (0x0a << 8) | // .+0x0c ('F' << 16) | @@ -1319,14 +1417,14 @@ public: : X86_32TargetCodeGenInfo(CGT, d, p, w, RegParms) {} void getDependentLibraryOption(llvm::StringRef Lib, - llvm::SmallString<24> &Opt) const { + llvm::SmallString<24> &Opt) const override { Opt = "/DEFAULTLIB:"; Opt += qualifyWindowsLibrary(Lib); } void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value, - llvm::SmallString<32> &Opt) const { + llvm::SmallString<32> &Opt) const override { Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\""; } }; @@ -1336,12 +1434,12 @@ public: WinX86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT) : TargetCodeGenInfo(new WinX86_64ABIInfo(CGT)) {} - int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const { + int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override { return 7; } bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, - llvm::Value *Address) const { + llvm::Value *Address) const override { llvm::Value *Eight8 = llvm::ConstantInt::get(CGF.Int8Ty, 8); // 0-15 are the 16 integer registers. @@ -1351,14 +1449,14 @@ public: } void getDependentLibraryOption(llvm::StringRef Lib, - llvm::SmallString<24> &Opt) const { + llvm::SmallString<24> &Opt) const override { Opt = "/DEFAULTLIB:"; Opt += qualifyWindowsLibrary(Lib); } void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value, - llvm::SmallString<32> &Opt) const { + llvm::SmallString<32> &Opt) const override { Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\""; } }; @@ -1642,12 +1740,11 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, // If this is a C++ record, classify the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { - for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(), - e = CXXRD->bases_end(); i != e; ++i) { - assert(!i->isVirtual() && !i->getType()->isDependentType() && + for (const auto &I : CXXRD->bases()) { + assert(!I.isVirtual() && !I.getType()->isDependentType() && "Unexpected base class!"); const CXXRecordDecl *Base = - cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); + cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl()); // Classify this field. // @@ -1657,7 +1754,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class FieldLo, FieldHi; uint64_t Offset = OffsetBase + getContext().toBits(Layout.getBaseClassOffset(Base)); - classify(i->getType(), Offset, FieldLo, FieldHi, isNamedArg); + classify(I.getType(), Offset, FieldLo, FieldHi, isNamedArg); Lo = merge(Lo, FieldLo); Hi = merge(Hi, FieldHi); if (Lo == Memory || Hi == Memory) @@ -1887,19 +1984,18 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit, // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { - for (CXXRecordDecl::base_class_const_iterator i = CXXRD->bases_begin(), - e = CXXRD->bases_end(); i != e; ++i) { - assert(!i->isVirtual() && !i->getType()->isDependentType() && + for (const auto &I : CXXRD->bases()) { + assert(!I.isVirtual() && !I.getType()->isDependentType() && "Unexpected base class!"); const CXXRecordDecl *Base = - cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); + cast<CXXRecordDecl>(I.getType()->getAs<RecordType>()->getDecl()); // If the base is after the span we care about, ignore it. unsigned BaseOffset = Context.toBits(Layout.getBaseClassOffset(Base)); if (BaseOffset >= EndBit) continue; unsigned BaseStart = BaseOffset < StartBit ? StartBit-BaseOffset :0; - if (!BitsContainNoUserData(i->getType(), BaseStart, + if (!BitsContainNoUserData(I.getType(), BaseStart, EndBit-BaseOffset, Context)) return false; } @@ -1995,7 +2091,7 @@ GetSSETypeAtOffset(llvm::Type *IRType, unsigned IROffset, /// the source type. IROffset is an offset in bytes into the LLVM IR type that /// the 8-byte value references. PrefType may be null. /// -/// SourceTy is the source level type for the entire argument. SourceOffset is +/// SourceTy is the source-level type for the entire argument. SourceOffset is /// an offset into this that we're processing (which is always either 0 or 8). /// llvm::Type *X86_64ABIInfo:: @@ -2114,7 +2210,7 @@ classifyReturnType(QualType RetTy) const { assert((Hi != Memory || Lo == Memory) && "Invalid memory classification."); assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp classification."); - llvm::Type *ResType = 0; + llvm::Type *ResType = nullptr; switch (Lo) { case NoClass: if (Hi == NoClass) @@ -2175,7 +2271,7 @@ classifyReturnType(QualType RetTy) const { break; } - llvm::Type *HighPart = 0; + llvm::Type *HighPart = nullptr; switch (Hi) { // Memory was handled previously and X87 should // never occur as a hi class. @@ -2247,7 +2343,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType( neededInt = 0; neededSSE = 0; - llvm::Type *ResType = 0; + llvm::Type *ResType = nullptr; switch (Lo) { case NoClass: if (Hi == NoClass) @@ -2308,7 +2404,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType( } } - llvm::Type *HighPart = 0; + llvm::Type *HighPart = nullptr; switch (Hi) { // Memory was handled previously, ComplexX87 and X87 should // never occur as hi classes, and X87Up must be preceded by X87, @@ -2361,7 +2457,8 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType( void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { - FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); // Keep track of the number of assigned registers. unsigned freeIntRegs = 6, freeSSERegs = 8; @@ -2482,9 +2579,9 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, // NOTE: 304 is a typo, there are (6 * 8 + 8 * 16) = 176 bytes of // register save space). - llvm::Value *InRegs = 0; - llvm::Value *gp_offset_p = 0, *gp_offset = 0; - llvm::Value *fp_offset_p = 0, *fp_offset = 0; + llvm::Value *InRegs = nullptr; + llvm::Value *gp_offset_p = nullptr, *gp_offset = nullptr; + llvm::Value *fp_offset_p = nullptr, *fp_offset = nullptr; if (neededInt) { gp_offset_p = CGF.Builder.CreateStructGEP(VAListAddr, 0, "gp_offset_p"); gp_offset = CGF.Builder.CreateLoad(gp_offset_p, "gp_offset"); @@ -2539,8 +2636,8 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, llvm::Type *PTyHi = llvm::PointerType::getUnqual(TyHi); llvm::Value *GPAddr = CGF.Builder.CreateGEP(RegAddr, gp_offset); llvm::Value *FPAddr = CGF.Builder.CreateGEP(RegAddr, fp_offset); - llvm::Value *RegLoAddr = TyLo->isFloatingPointTy() ? FPAddr : GPAddr; - llvm::Value *RegHiAddr = TyLo->isFloatingPointTy() ? GPAddr : FPAddr; + llvm::Value *RegLoAddr = TyLo->isFPOrFPVectorTy() ? FPAddr : GPAddr; + llvm::Value *RegHiAddr = TyLo->isFPOrFPVectorTy() ? GPAddr : FPAddr; llvm::Value *V = CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegLoAddr, PTyLo)); CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0)); @@ -2630,11 +2727,9 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, bool IsReturnType) const { uint64_t Size = getContext().getTypeSize(Ty); - if (const RecordType *RT = Ty->getAs<RecordType>()) { - if (IsReturnType) { - if (isRecordReturnIndirect(RT, getCXXABI())) - return ABIArgInfo::getIndirect(0, false); - } else { + const RecordType *RT = Ty->getAs<RecordType>(); + if (RT) { + if (!IsReturnType) { if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI())) return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); } @@ -2643,18 +2738,27 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, bool IsReturnType) const { return ABIArgInfo::getIndirect(0, /*ByVal=*/false); // FIXME: mingw-w64-gcc emits 128-bit struct as i128 - if (Size == 128 && getTarget().getTriple().getOS() == llvm::Triple::MinGW32) + if (Size == 128 && getTarget().getTriple().isWindowsGNUEnvironment()) return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size)); + } + + if (Ty->isMemberPointerType()) { + // If the member pointer is represented by an LLVM int or ptr, pass it + // directly. + llvm::Type *LLTy = CGT.ConvertType(Ty); + if (LLTy->isPointerTy() || LLTy->isIntegerTy()) + return ABIArgInfo::getDirect(); + } + if (RT || Ty->isMemberPointerType()) { // MS x64 ABI requirement: "Any argument that doesn't fit in 8 bytes, or is // not 1, 2, 4, or 8 bytes, must be passed by reference." - if (Size <= 64 && - (Size & (Size - 1)) == 0) - return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), - Size)); + if (Size > 64 || !llvm::isPowerOf2_64(Size)) + return ABIArgInfo::getIndirect(0, /*ByVal=*/false); - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + // Otherwise, coerce it to a small integer. + return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size)); } if (Ty->isPromotableIntegerType()) @@ -2664,13 +2768,11 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, bool IsReturnType) const { } void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { + if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classify(FI.getReturnType(), true); - QualType RetTy = FI.getReturnType(); - FI.getReturnInfo() = classify(RetTy, true); - - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); - it != ie; ++it) - it->info = classify(it->type, false); + for (auto &I : FI.arguments()) + I.info = classify(I.type, false); } llvm::Value *WinX86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, @@ -2701,9 +2803,9 @@ class NaClX86_64ABIInfo : public ABIInfo { public: NaClX86_64ABIInfo(CodeGen::CodeGenTypes &CGT, bool HasAVX) : ABIInfo(CGT), PInfo(CGT), NInfo(CGT, HasAVX) {} - virtual void computeInfo(CGFunctionInfo &FI) const; - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + void computeInfo(CGFunctionInfo &FI) const override; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; private: PNaClABIInfo PInfo; // Used for generating calls with pnaclcall callingconv. X86_64ABIInfo NInfo; // Used for everything else. @@ -2739,13 +2841,13 @@ class PPC32TargetCodeGenInfo : public DefaultTargetCodeGenInfo { public: PPC32TargetCodeGenInfo(CodeGenTypes &CGT) : DefaultTargetCodeGenInfo(CGT) {} - int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { + int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { // This is recovered from gcc output. return 1; // r1 is the dedicated stack pointer } bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, - llvm::Value *Address) const; + llvm::Value *Address) const override; }; } @@ -2796,11 +2898,24 @@ PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, namespace { /// PPC64_SVR4_ABIInfo - The 64-bit PowerPC ELF (SVR4) ABI information. class PPC64_SVR4_ABIInfo : public DefaultABIInfo { +public: + enum ABIKind { + ELFv1 = 0, + ELFv2 + }; + +private: + static const unsigned GPRBits = 64; + ABIKind Kind; public: - PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} + PPC64_SVR4_ABIInfo(CodeGen::CodeGenTypes &CGT, ABIKind Kind) + : DefaultABIInfo(CGT), Kind(Kind) {} bool isPromotableTypeForABI(QualType Ty) const; + bool isAlignedParamType(QualType Ty) const; + bool isHomogeneousAggregate(QualType Ty, const Type *&Base, + uint64_t &Members) const; ABIArgInfo classifyReturnType(QualType RetTy) const; ABIArgInfo classifyArgumentType(QualType Ty) const; @@ -2811,56 +2926,57 @@ public: // floating-point value) to avoid pushing them to memory on function // entry. This would require changing the logic in PPCISelLowering // when lowering the parameters in the caller and args in the callee. - virtual void computeInfo(CGFunctionInfo &FI) const { - FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); - it != ie; ++it) { + void computeInfo(CGFunctionInfo &FI) const override { + if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + for (auto &I : FI.arguments()) { // We rely on the default argument classification for the most part. // One exception: An aggregate containing a single floating-point // or vector item must be passed in a register if one is available. - const Type *T = isSingleElementStruct(it->type, getContext()); + const Type *T = isSingleElementStruct(I.type, getContext()); if (T) { const BuiltinType *BT = T->getAs<BuiltinType>(); - if (T->isVectorType() || (BT && BT->isFloatingPoint())) { + if ((T->isVectorType() && getContext().getTypeSize(T) == 128) || + (BT && BT->isFloatingPoint())) { QualType QT(T, 0); - it->info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT)); + I.info = ABIArgInfo::getDirectInReg(CGT.ConvertType(QT)); continue; } } - it->info = classifyArgumentType(it->type); + I.info = classifyArgumentType(I.type); } } - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, - QualType Ty, - CodeGenFunction &CGF) const; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; }; class PPC64_SVR4_TargetCodeGenInfo : public TargetCodeGenInfo { public: - PPC64_SVR4_TargetCodeGenInfo(CodeGenTypes &CGT) - : TargetCodeGenInfo(new PPC64_SVR4_ABIInfo(CGT)) {} + PPC64_SVR4_TargetCodeGenInfo(CodeGenTypes &CGT, + PPC64_SVR4_ABIInfo::ABIKind Kind) + : TargetCodeGenInfo(new PPC64_SVR4_ABIInfo(CGT, Kind)) {} - int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { + int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { // This is recovered from gcc output. return 1; // r1 is the dedicated stack pointer } bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, - llvm::Value *Address) const; + llvm::Value *Address) const override; }; class PPC64TargetCodeGenInfo : public DefaultTargetCodeGenInfo { public: PPC64TargetCodeGenInfo(CodeGenTypes &CGT) : DefaultTargetCodeGenInfo(CGT) {} - int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { + int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { // This is recovered from gcc output. return 1; // r1 is the dedicated stack pointer } bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, - llvm::Value *Address) const; + llvm::Value *Address) const override; }; } @@ -2891,16 +3007,205 @@ PPC64_SVR4_ABIInfo::isPromotableTypeForABI(QualType Ty) const { return false; } +/// isAlignedParamType - Determine whether a type requires 16-byte +/// alignment in the parameter area. +bool +PPC64_SVR4_ABIInfo::isAlignedParamType(QualType Ty) const { + // Complex types are passed just like their elements. + if (const ComplexType *CTy = Ty->getAs<ComplexType>()) + Ty = CTy->getElementType(); + + // Only vector types of size 16 bytes need alignment (larger types are + // passed via reference, smaller types are not aligned). + if (Ty->isVectorType()) + return getContext().getTypeSize(Ty) == 128; + + // For single-element float/vector structs, we consider the whole type + // to have the same alignment requirements as its single element. + const Type *AlignAsType = nullptr; + const Type *EltType = isSingleElementStruct(Ty, getContext()); + if (EltType) { + const BuiltinType *BT = EltType->getAs<BuiltinType>(); + if ((EltType->isVectorType() && + getContext().getTypeSize(EltType) == 128) || + (BT && BT->isFloatingPoint())) + AlignAsType = EltType; + } + + // Likewise for ELFv2 homogeneous aggregates. + const Type *Base = nullptr; + uint64_t Members = 0; + if (!AlignAsType && Kind == ELFv2 && + isAggregateTypeForABI(Ty) && isHomogeneousAggregate(Ty, Base, Members)) + AlignAsType = Base; + + // With special case aggregates, only vector base types need alignment. + if (AlignAsType) + return AlignAsType->isVectorType(); + + // Otherwise, we only need alignment for any aggregate type that + // has an alignment requirement of >= 16 bytes. + if (isAggregateTypeForABI(Ty) && getContext().getTypeAlign(Ty) >= 128) + return true; + + return false; +} + +/// isHomogeneousAggregate - Return true if a type is an ELFv2 homogeneous +/// aggregate. Base is set to the base element type, and Members is set +/// to the number of base elements. +bool +PPC64_SVR4_ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base, + uint64_t &Members) const { + if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) { + uint64_t NElements = AT->getSize().getZExtValue(); + if (NElements == 0) + return false; + if (!isHomogeneousAggregate(AT->getElementType(), Base, Members)) + return false; + Members *= NElements; + } else if (const RecordType *RT = Ty->getAs<RecordType>()) { + const RecordDecl *RD = RT->getDecl(); + if (RD->hasFlexibleArrayMember()) + return false; + + Members = 0; + for (const auto *FD : RD->fields()) { + // Ignore (non-zero arrays of) empty records. + QualType FT = FD->getType(); + while (const ConstantArrayType *AT = + getContext().getAsConstantArrayType(FT)) { + if (AT->getSize().getZExtValue() == 0) + return false; + FT = AT->getElementType(); + } + if (isEmptyRecord(getContext(), FT, true)) + continue; + + // For compatibility with GCC, ignore empty bitfields in C++ mode. + if (getContext().getLangOpts().CPlusPlus && + FD->isBitField() && FD->getBitWidthValue(getContext()) == 0) + continue; + + uint64_t FldMembers; + if (!isHomogeneousAggregate(FD->getType(), Base, FldMembers)) + return false; + + Members = (RD->isUnion() ? + std::max(Members, FldMembers) : Members + FldMembers); + } + + if (!Base) + return false; + + // Ensure there is no padding. + if (getContext().getTypeSize(Base) * Members != + getContext().getTypeSize(Ty)) + return false; + } else { + Members = 1; + if (const ComplexType *CT = Ty->getAs<ComplexType>()) { + Members = 2; + Ty = CT->getElementType(); + } + + // Homogeneous aggregates for ELFv2 must have base types of float, + // double, long double, or 128-bit vectors. + if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { + if (BT->getKind() != BuiltinType::Float && + BT->getKind() != BuiltinType::Double && + BT->getKind() != BuiltinType::LongDouble) + return false; + } else if (const VectorType *VT = Ty->getAs<VectorType>()) { + if (getContext().getTypeSize(VT) != 128) + return false; + } else { + return false; + } + + // The base type must be the same for all members. Types that + // agree in both total size and mode (float vs. vector) are + // treated as being equivalent here. + const Type *TyPtr = Ty.getTypePtr(); + if (!Base) + Base = TyPtr; + + if (Base->isVectorType() != TyPtr->isVectorType() || + getContext().getTypeSize(Base) != getContext().getTypeSize(TyPtr)) + return false; + } + + // Vector types require one register, floating point types require one + // or two registers depending on their size. + uint32_t NumRegs = Base->isVectorType() ? 1 : + (getContext().getTypeSize(Base) + 63) / 64; + + // Homogeneous Aggregates may occupy at most 8 registers. + return (Members > 0 && Members * NumRegs <= 8); +} + ABIArgInfo PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { if (Ty->isAnyComplexType()) return ABIArgInfo::getDirect(); + // Non-Altivec vector types are passed in GPRs (smaller than 16 bytes) + // or via reference (larger than 16 bytes). + if (Ty->isVectorType()) { + uint64_t Size = getContext().getTypeSize(Ty); + if (Size > 128) + return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + else if (Size < 128) { + llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size); + return ABIArgInfo::getDirect(CoerceTy); + } + } + if (isAggregateTypeForABI(Ty)) { if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); - return ABIArgInfo::getIndirect(0); + uint64_t ABIAlign = isAlignedParamType(Ty)? 16 : 8; + uint64_t TyAlign = getContext().getTypeAlign(Ty) / 8; + + // ELFv2 homogeneous aggregates are passed as array types. + const Type *Base = nullptr; + uint64_t Members = 0; + if (Kind == ELFv2 && + isHomogeneousAggregate(Ty, Base, Members)) { + llvm::Type *BaseTy = CGT.ConvertType(QualType(Base, 0)); + llvm::Type *CoerceTy = llvm::ArrayType::get(BaseTy, Members); + return ABIArgInfo::getDirect(CoerceTy); + } + + // If an aggregate may end up fully in registers, we do not + // use the ByVal method, but pass the aggregate as array. + // This is usually beneficial since we avoid forcing the + // back-end to store the argument to memory. + uint64_t Bits = getContext().getTypeSize(Ty); + if (Bits > 0 && Bits <= 8 * GPRBits) { + llvm::Type *CoerceTy; + + // Types up to 8 bytes are passed as integer type (which will be + // properly aligned in the argument save area doubleword). + if (Bits <= GPRBits) + CoerceTy = llvm::IntegerType::get(getVMContext(), + llvm::RoundUpToAlignment(Bits, 8)); + // Larger types are passed as arrays, with the base type selected + // according to the required alignment in the save area. + else { + uint64_t RegBits = ABIAlign * 8; + uint64_t NumRegs = llvm::RoundUpToAlignment(Bits, RegBits) / RegBits; + llvm::Type *RegTy = llvm::IntegerType::get(getVMContext(), RegBits); + CoerceTy = llvm::ArrayType::get(RegTy, NumRegs); + } + + return ABIArgInfo::getDirect(CoerceTy); + } + + // All other aggregates are passed ByVal. + return ABIArgInfo::getIndirect(ABIAlign, /*ByVal=*/true, + /*Realign=*/TyAlign > ABIAlign); } return (isPromotableTypeForABI(Ty) ? @@ -2915,8 +3220,48 @@ PPC64_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const { if (RetTy->isAnyComplexType()) return ABIArgInfo::getDirect(); - if (isAggregateTypeForABI(RetTy)) + // Non-Altivec vector types are returned in GPRs (smaller than 16 bytes) + // or via reference (larger than 16 bytes). + if (RetTy->isVectorType()) { + uint64_t Size = getContext().getTypeSize(RetTy); + if (Size > 128) + return ABIArgInfo::getIndirect(0); + else if (Size < 128) { + llvm::Type *CoerceTy = llvm::IntegerType::get(getVMContext(), Size); + return ABIArgInfo::getDirect(CoerceTy); + } + } + + if (isAggregateTypeForABI(RetTy)) { + // ELFv2 homogeneous aggregates are returned as array types. + const Type *Base = nullptr; + uint64_t Members = 0; + if (Kind == ELFv2 && + isHomogeneousAggregate(RetTy, Base, Members)) { + llvm::Type *BaseTy = CGT.ConvertType(QualType(Base, 0)); + llvm::Type *CoerceTy = llvm::ArrayType::get(BaseTy, Members); + return ABIArgInfo::getDirect(CoerceTy); + } + + // ELFv2 small aggregates are returned in up to two registers. + uint64_t Bits = getContext().getTypeSize(RetTy); + if (Kind == ELFv2 && Bits <= 2 * GPRBits) { + if (Bits == 0) + return ABIArgInfo::getIgnore(); + + llvm::Type *CoerceTy; + if (Bits > GPRBits) { + CoerceTy = llvm::IntegerType::get(getVMContext(), GPRBits); + CoerceTy = llvm::StructType::get(CoerceTy, CoerceTy, NULL); + } else + CoerceTy = llvm::IntegerType::get(getVMContext(), + llvm::RoundUpToAlignment(Bits, 8)); + return ABIArgInfo::getDirect(CoerceTy); + } + + // All other aggregates are returned indirectly. return ABIArgInfo::getIndirect(0); + } return (isPromotableTypeForABI(RetTy) ? ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); @@ -2933,6 +3278,14 @@ llvm::Value *PPC64_SVR4_ABIInfo::EmitVAArg(llvm::Value *VAListAddr, llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap"); llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); + // Handle types that require 16-byte alignment in the parameter save area. + if (isAlignedParamType(Ty)) { + llvm::Value *AddrAsInt = Builder.CreatePtrToInt(Addr, CGF.Int64Ty); + AddrAsInt = Builder.CreateAdd(AddrAsInt, Builder.getInt64(15)); + AddrAsInt = Builder.CreateAnd(AddrAsInt, Builder.getInt64(-16)); + Addr = Builder.CreateIntToPtr(AddrAsInt, BP, "ap.align"); + } + // Update the va_list pointer. The pointer should be bumped by the // size of the object. We can trust getTypeSize() except for a complex // type whose base type is smaller than a doubleword. For these, the @@ -2963,8 +3316,12 @@ llvm::Value *PPC64_SVR4_ABIInfo::EmitVAArg(llvm::Value *VAListAddr, if (CplxBaseSize && CplxBaseSize < 8) { llvm::Value *RealAddr = Builder.CreatePtrToInt(Addr, CGF.Int64Ty); llvm::Value *ImagAddr = RealAddr; - RealAddr = Builder.CreateAdd(RealAddr, Builder.getInt64(8 - CplxBaseSize)); - ImagAddr = Builder.CreateAdd(ImagAddr, Builder.getInt64(16 - CplxBaseSize)); + if (CGF.CGM.getDataLayout().isBigEndian()) { + RealAddr = Builder.CreateAdd(RealAddr, Builder.getInt64(8 - CplxBaseSize)); + ImagAddr = Builder.CreateAdd(ImagAddr, Builder.getInt64(16 - CplxBaseSize)); + } else { + ImagAddr = Builder.CreateAdd(ImagAddr, Builder.getInt64(8)); + } llvm::Type *PBaseTy = llvm::PointerType::getUnqual(CGF.ConvertType(BaseTy)); RealAddr = Builder.CreateIntToPtr(RealAddr, PBaseTy); ImagAddr = Builder.CreateIntToPtr(ImagAddr, PBaseTy); @@ -2982,7 +3339,7 @@ llvm::Value *PPC64_SVR4_ABIInfo::EmitVAArg(llvm::Value *VAListAddr, // If the argument is smaller than 8 bytes, it is right-adjusted in // its doubleword slot. Adjust the pointer to pick it up from the // correct offset. - if (SizeInBytes < 8) { + if (SizeInBytes < 8 && CGF.CGM.getDataLayout().isBigEndian()) { llvm::Value *AddrAsInt = Builder.CreatePtrToInt(Addr, CGF.Int64Ty); AddrAsInt = Builder.CreateAdd(AddrAsInt, Builder.getInt64(8 - SizeInBytes)); Addr = Builder.CreateIntToPtr(AddrAsInt, BP); @@ -3049,6 +3406,598 @@ PPC64TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, } //===----------------------------------------------------------------------===// +// AArch64 ABI Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class AArch64ABIInfo : public ABIInfo { +public: + enum ABIKind { + AAPCS = 0, + DarwinPCS + }; + +private: + ABIKind Kind; + +public: + AArch64ABIInfo(CodeGenTypes &CGT, ABIKind Kind) : ABIInfo(CGT), Kind(Kind) {} + +private: + ABIKind getABIKind() const { return Kind; } + bool isDarwinPCS() const { return Kind == DarwinPCS; } + + ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &AllocatedVFP, + bool &IsHA, unsigned &AllocatedGPR, + bool &IsSmallAggr, bool IsNamedArg) const; + bool isIllegalVectorType(QualType Ty) const; + + virtual void computeInfo(CGFunctionInfo &FI) const { + // To correctly handle Homogeneous Aggregate, we need to keep track of the + // number of SIMD and Floating-point registers allocated so far. + // If the argument is an HFA or an HVA and there are sufficient unallocated + // SIMD and Floating-point registers, then the argument is allocated to SIMD + // and Floating-point Registers (with one register per member of the HFA or + // HVA). Otherwise, the NSRN is set to 8. + unsigned AllocatedVFP = 0; + + // To correctly handle small aggregates, we need to keep track of the number + // of GPRs allocated so far. If the small aggregate can't all fit into + // registers, it will be on stack. We don't allow the aggregate to be + // partially in registers. + unsigned AllocatedGPR = 0; + + // Find the number of named arguments. Variadic arguments get special + // treatment with the Darwin ABI. + unsigned NumRequiredArgs = (FI.isVariadic() ? + FI.getRequiredArgs().getNumRequiredArgs() : + FI.arg_size()); + + if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); + it != ie; ++it) { + unsigned PreAllocation = AllocatedVFP, PreGPR = AllocatedGPR; + bool IsHA = false, IsSmallAggr = false; + const unsigned NumVFPs = 8; + const unsigned NumGPRs = 8; + bool IsNamedArg = ((it - FI.arg_begin()) < + static_cast<signed>(NumRequiredArgs)); + it->info = classifyArgumentType(it->type, AllocatedVFP, IsHA, + AllocatedGPR, IsSmallAggr, IsNamedArg); + + // Under AAPCS the 64-bit stack slot alignment means we can't pass HAs + // as sequences of floats since they'll get "holes" inserted as + // padding by the back end. + if (IsHA && AllocatedVFP > NumVFPs && !isDarwinPCS() && + getContext().getTypeAlign(it->type) < 64) { + uint32_t NumStackSlots = getContext().getTypeSize(it->type); + NumStackSlots = llvm::RoundUpToAlignment(NumStackSlots, 64) / 64; + + llvm::Type *CoerceTy = llvm::ArrayType::get( + llvm::Type::getDoubleTy(getVMContext()), NumStackSlots); + it->info = ABIArgInfo::getDirect(CoerceTy); + } + + // If we do not have enough VFP registers for the HA, any VFP registers + // that are unallocated are marked as unavailable. To achieve this, we add + // padding of (NumVFPs - PreAllocation) floats. + if (IsHA && AllocatedVFP > NumVFPs && PreAllocation < NumVFPs) { + llvm::Type *PaddingTy = llvm::ArrayType::get( + llvm::Type::getFloatTy(getVMContext()), NumVFPs - PreAllocation); + it->info.setPaddingType(PaddingTy); + } + + // If we do not have enough GPRs for the small aggregate, any GPR regs + // that are unallocated are marked as unavailable. + if (IsSmallAggr && AllocatedGPR > NumGPRs && PreGPR < NumGPRs) { + llvm::Type *PaddingTy = llvm::ArrayType::get( + llvm::Type::getInt32Ty(getVMContext()), NumGPRs - PreGPR); + it->info = + ABIArgInfo::getDirect(it->info.getCoerceToType(), 0, PaddingTy); + } + } + } + + llvm::Value *EmitDarwinVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const; + + llvm::Value *EmitAAPCSVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const; + + virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const { + return isDarwinPCS() ? EmitDarwinVAArg(VAListAddr, Ty, CGF) + : EmitAAPCSVAArg(VAListAddr, Ty, CGF); + } +}; + +class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { +public: + AArch64TargetCodeGenInfo(CodeGenTypes &CGT, AArch64ABIInfo::ABIKind Kind) + : TargetCodeGenInfo(new AArch64ABIInfo(CGT, Kind)) {} + + StringRef getARCRetainAutoreleasedReturnValueMarker() const { + return "mov\tfp, fp\t\t; marker for objc_retainAutoreleaseReturnValue"; + } + + int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { return 31; } + + virtual bool doesReturnSlotInterfereWithArgs() const { return false; } +}; +} + +static bool isHomogeneousAggregate(QualType Ty, const Type *&Base, + ASTContext &Context, + uint64_t *HAMembers = nullptr); + +ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, + unsigned &AllocatedVFP, + bool &IsHA, + unsigned &AllocatedGPR, + bool &IsSmallAggr, + bool IsNamedArg) const { + // Handle illegal vector types here. + if (isIllegalVectorType(Ty)) { + uint64_t Size = getContext().getTypeSize(Ty); + if (Size <= 32) { + llvm::Type *ResType = llvm::Type::getInt32Ty(getVMContext()); + AllocatedGPR++; + return ABIArgInfo::getDirect(ResType); + } + if (Size == 64) { + llvm::Type *ResType = + llvm::VectorType::get(llvm::Type::getInt32Ty(getVMContext()), 2); + AllocatedVFP++; + return ABIArgInfo::getDirect(ResType); + } + if (Size == 128) { + llvm::Type *ResType = + llvm::VectorType::get(llvm::Type::getInt32Ty(getVMContext()), 4); + AllocatedVFP++; + return ABIArgInfo::getDirect(ResType); + } + AllocatedGPR++; + return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + } + if (Ty->isVectorType()) + // Size of a legal vector should be either 64 or 128. + AllocatedVFP++; + if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { + if (BT->getKind() == BuiltinType::Half || + BT->getKind() == BuiltinType::Float || + BT->getKind() == BuiltinType::Double || + BT->getKind() == BuiltinType::LongDouble) + AllocatedVFP++; + } + + if (!isAggregateTypeForABI(Ty)) { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs<EnumType>()) + Ty = EnumTy->getDecl()->getIntegerType(); + + if (!Ty->isFloatingType() && !Ty->isVectorType()) { + unsigned Alignment = getContext().getTypeAlign(Ty); + if (!isDarwinPCS() && Alignment > 64) + AllocatedGPR = llvm::RoundUpToAlignment(AllocatedGPR, Alignment / 64); + + int RegsNeeded = getContext().getTypeSize(Ty) > 64 ? 2 : 1; + AllocatedGPR += RegsNeeded; + } + return (Ty->isPromotableIntegerType() && isDarwinPCS() + ? ABIArgInfo::getExtend() + : ABIArgInfo::getDirect()); + } + + // Structures with either a non-trivial destructor or a non-trivial + // copy constructor are always indirect. + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) { + AllocatedGPR++; + return ABIArgInfo::getIndirect(0, /*ByVal=*/RAA == + CGCXXABI::RAA_DirectInMemory); + } + + // Empty records are always ignored on Darwin, but actually passed in C++ mode + // elsewhere for GNU compatibility. + if (isEmptyRecord(getContext(), Ty, true)) { + if (!getContext().getLangOpts().CPlusPlus || isDarwinPCS()) + return ABIArgInfo::getIgnore(); + + ++AllocatedGPR; + return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext())); + } + + // Homogeneous Floating-point Aggregates (HFAs) need to be expanded. + const Type *Base = nullptr; + uint64_t Members = 0; + if (isHomogeneousAggregate(Ty, Base, getContext(), &Members)) { + IsHA = true; + if (!IsNamedArg && isDarwinPCS()) { + // With the Darwin ABI, variadic arguments are always passed on the stack + // and should not be expanded. Treat variadic HFAs as arrays of doubles. + uint64_t Size = getContext().getTypeSize(Ty); + llvm::Type *BaseTy = llvm::Type::getDoubleTy(getVMContext()); + return ABIArgInfo::getDirect(llvm::ArrayType::get(BaseTy, Size / 64)); + } + AllocatedVFP += Members; + return ABIArgInfo::getExpand(); + } + + // Aggregates <= 16 bytes are passed directly in registers or on the stack. + uint64_t Size = getContext().getTypeSize(Ty); + if (Size <= 128) { + unsigned Alignment = getContext().getTypeAlign(Ty); + if (!isDarwinPCS() && Alignment > 64) + AllocatedGPR = llvm::RoundUpToAlignment(AllocatedGPR, Alignment / 64); + + Size = 64 * ((Size + 63) / 64); // round up to multiple of 8 bytes + AllocatedGPR += Size / 64; + IsSmallAggr = true; + // We use a pair of i64 for 16-byte aggregate with 8-byte alignment. + // For aggregates with 16-byte alignment, we use i128. + if (Alignment < 128 && Size == 128) { + llvm::Type *BaseTy = llvm::Type::getInt64Ty(getVMContext()); + return ABIArgInfo::getDirect(llvm::ArrayType::get(BaseTy, Size / 64)); + } + return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size)); + } + + AllocatedGPR++; + return ABIArgInfo::getIndirect(0, /*ByVal=*/false); +} + +ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy) const { + if (RetTy->isVoidType()) + return ABIArgInfo::getIgnore(); + + // Large vector types should be returned via memory. + if (RetTy->isVectorType() && getContext().getTypeSize(RetTy) > 128) + return ABIArgInfo::getIndirect(0); + + if (!isAggregateTypeForABI(RetTy)) { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) + RetTy = EnumTy->getDecl()->getIntegerType(); + + return (RetTy->isPromotableIntegerType() && isDarwinPCS() + ? ABIArgInfo::getExtend() + : ABIArgInfo::getDirect()); + } + + if (isEmptyRecord(getContext(), RetTy, true)) + return ABIArgInfo::getIgnore(); + + const Type *Base = nullptr; + if (isHomogeneousAggregate(RetTy, Base, getContext())) + // Homogeneous Floating-point Aggregates (HFAs) are returned directly. + return ABIArgInfo::getDirect(); + + // Aggregates <= 16 bytes are returned directly in registers or on the stack. + uint64_t Size = getContext().getTypeSize(RetTy); + if (Size <= 128) { + Size = 64 * ((Size + 63) / 64); // round up to multiple of 8 bytes + return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size)); + } + + return ABIArgInfo::getIndirect(0); +} + +/// isIllegalVectorType - check whether the vector type is legal for AArch64. +bool AArch64ABIInfo::isIllegalVectorType(QualType Ty) const { + if (const VectorType *VT = Ty->getAs<VectorType>()) { + // Check whether VT is legal. + unsigned NumElements = VT->getNumElements(); + uint64_t Size = getContext().getTypeSize(VT); + // NumElements should be power of 2 between 1 and 16. + if ((NumElements & (NumElements - 1)) != 0 || NumElements > 16) + return true; + return Size != 64 && (Size != 128 || NumElements == 1); + } + return false; +} + +static llvm::Value *EmitAArch64VAArg(llvm::Value *VAListAddr, QualType Ty, + int AllocatedGPR, int AllocatedVFP, + bool IsIndirect, CodeGenFunction &CGF) { + // The AArch64 va_list type and handling is specified in the Procedure Call + // Standard, section B.4: + // + // struct { + // void *__stack; + // void *__gr_top; + // void *__vr_top; + // int __gr_offs; + // int __vr_offs; + // }; + + llvm::BasicBlock *MaybeRegBlock = CGF.createBasicBlock("vaarg.maybe_reg"); + llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg"); + llvm::BasicBlock *OnStackBlock = CGF.createBasicBlock("vaarg.on_stack"); + llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end"); + auto &Ctx = CGF.getContext(); + + llvm::Value *reg_offs_p = nullptr, *reg_offs = nullptr; + int reg_top_index; + int RegSize; + if (AllocatedGPR) { + assert(!AllocatedVFP && "Arguments never split between int & VFP regs"); + // 3 is the field number of __gr_offs + reg_offs_p = CGF.Builder.CreateStructGEP(VAListAddr, 3, "gr_offs_p"); + reg_offs = CGF.Builder.CreateLoad(reg_offs_p, "gr_offs"); + reg_top_index = 1; // field number for __gr_top + RegSize = 8 * AllocatedGPR; + } else { + assert(!AllocatedGPR && "Argument must go in VFP or int regs"); + // 4 is the field number of __vr_offs. + reg_offs_p = CGF.Builder.CreateStructGEP(VAListAddr, 4, "vr_offs_p"); + reg_offs = CGF.Builder.CreateLoad(reg_offs_p, "vr_offs"); + reg_top_index = 2; // field number for __vr_top + RegSize = 16 * AllocatedVFP; + } + + //======================================= + // Find out where argument was passed + //======================================= + + // If reg_offs >= 0 we're already using the stack for this type of + // argument. We don't want to keep updating reg_offs (in case it overflows, + // though anyone passing 2GB of arguments, each at most 16 bytes, deserves + // whatever they get). + llvm::Value *UsingStack = nullptr; + UsingStack = CGF.Builder.CreateICmpSGE( + reg_offs, llvm::ConstantInt::get(CGF.Int32Ty, 0)); + + CGF.Builder.CreateCondBr(UsingStack, OnStackBlock, MaybeRegBlock); + + // Otherwise, at least some kind of argument could go in these registers, the + // question is whether this particular type is too big. + CGF.EmitBlock(MaybeRegBlock); + + // Integer arguments may need to correct register alignment (for example a + // "struct { __int128 a; };" gets passed in x_2N, x_{2N+1}). In this case we + // align __gr_offs to calculate the potential address. + if (AllocatedGPR && !IsIndirect && Ctx.getTypeAlign(Ty) > 64) { + int Align = Ctx.getTypeAlign(Ty) / 8; + + reg_offs = CGF.Builder.CreateAdd( + reg_offs, llvm::ConstantInt::get(CGF.Int32Ty, Align - 1), + "align_regoffs"); + reg_offs = CGF.Builder.CreateAnd( + reg_offs, llvm::ConstantInt::get(CGF.Int32Ty, -Align), + "aligned_regoffs"); + } + + // Update the gr_offs/vr_offs pointer for next call to va_arg on this va_list. + llvm::Value *NewOffset = nullptr; + NewOffset = CGF.Builder.CreateAdd( + reg_offs, llvm::ConstantInt::get(CGF.Int32Ty, RegSize), "new_reg_offs"); + CGF.Builder.CreateStore(NewOffset, reg_offs_p); + + // Now we're in a position to decide whether this argument really was in + // registers or not. + llvm::Value *InRegs = nullptr; + InRegs = CGF.Builder.CreateICmpSLE( + NewOffset, llvm::ConstantInt::get(CGF.Int32Ty, 0), "inreg"); + + CGF.Builder.CreateCondBr(InRegs, InRegBlock, OnStackBlock); + + //======================================= + // Argument was in registers + //======================================= + + // Now we emit the code for if the argument was originally passed in + // registers. First start the appropriate block: + CGF.EmitBlock(InRegBlock); + + llvm::Value *reg_top_p = nullptr, *reg_top = nullptr; + reg_top_p = + CGF.Builder.CreateStructGEP(VAListAddr, reg_top_index, "reg_top_p"); + reg_top = CGF.Builder.CreateLoad(reg_top_p, "reg_top"); + llvm::Value *BaseAddr = CGF.Builder.CreateGEP(reg_top, reg_offs); + llvm::Value *RegAddr = nullptr; + llvm::Type *MemTy = llvm::PointerType::getUnqual(CGF.ConvertTypeForMem(Ty)); + + if (IsIndirect) { + // If it's been passed indirectly (actually a struct), whatever we find from + // stored registers or on the stack will actually be a struct **. + MemTy = llvm::PointerType::getUnqual(MemTy); + } + + const Type *Base = nullptr; + uint64_t NumMembers; + bool IsHFA = isHomogeneousAggregate(Ty, Base, Ctx, &NumMembers); + if (IsHFA && NumMembers > 1) { + // Homogeneous aggregates passed in registers will have their elements split + // and stored 16-bytes apart regardless of size (they're notionally in qN, + // qN+1, ...). We reload and store into a temporary local variable + // contiguously. + assert(!IsIndirect && "Homogeneous aggregates should be passed directly"); + llvm::Type *BaseTy = CGF.ConvertType(QualType(Base, 0)); + llvm::Type *HFATy = llvm::ArrayType::get(BaseTy, NumMembers); + llvm::Value *Tmp = CGF.CreateTempAlloca(HFATy); + int Offset = 0; + + if (CGF.CGM.getDataLayout().isBigEndian() && Ctx.getTypeSize(Base) < 128) + Offset = 16 - Ctx.getTypeSize(Base) / 8; + for (unsigned i = 0; i < NumMembers; ++i) { + llvm::Value *BaseOffset = + llvm::ConstantInt::get(CGF.Int32Ty, 16 * i + Offset); + llvm::Value *LoadAddr = CGF.Builder.CreateGEP(BaseAddr, BaseOffset); + LoadAddr = CGF.Builder.CreateBitCast( + LoadAddr, llvm::PointerType::getUnqual(BaseTy)); + llvm::Value *StoreAddr = CGF.Builder.CreateStructGEP(Tmp, i); + + llvm::Value *Elem = CGF.Builder.CreateLoad(LoadAddr); + CGF.Builder.CreateStore(Elem, StoreAddr); + } + + RegAddr = CGF.Builder.CreateBitCast(Tmp, MemTy); + } else { + // Otherwise the object is contiguous in memory + unsigned BeAlign = reg_top_index == 2 ? 16 : 8; + if (CGF.CGM.getDataLayout().isBigEndian() && + (IsHFA || !isAggregateTypeForABI(Ty)) && + Ctx.getTypeSize(Ty) < (BeAlign * 8)) { + int Offset = BeAlign - Ctx.getTypeSize(Ty) / 8; + BaseAddr = CGF.Builder.CreatePtrToInt(BaseAddr, CGF.Int64Ty); + + BaseAddr = CGF.Builder.CreateAdd( + BaseAddr, llvm::ConstantInt::get(CGF.Int64Ty, Offset), "align_be"); + + BaseAddr = CGF.Builder.CreateIntToPtr(BaseAddr, CGF.Int8PtrTy); + } + + RegAddr = CGF.Builder.CreateBitCast(BaseAddr, MemTy); + } + + CGF.EmitBranch(ContBlock); + + //======================================= + // Argument was on the stack + //======================================= + CGF.EmitBlock(OnStackBlock); + + llvm::Value *stack_p = nullptr, *OnStackAddr = nullptr; + stack_p = CGF.Builder.CreateStructGEP(VAListAddr, 0, "stack_p"); + OnStackAddr = CGF.Builder.CreateLoad(stack_p, "stack"); + + // Again, stack arguments may need realigmnent. In this case both integer and + // floating-point ones might be affected. + if (!IsIndirect && Ctx.getTypeAlign(Ty) > 64) { + int Align = Ctx.getTypeAlign(Ty) / 8; + + OnStackAddr = CGF.Builder.CreatePtrToInt(OnStackAddr, CGF.Int64Ty); + + OnStackAddr = CGF.Builder.CreateAdd( + OnStackAddr, llvm::ConstantInt::get(CGF.Int64Ty, Align - 1), + "align_stack"); + OnStackAddr = CGF.Builder.CreateAnd( + OnStackAddr, llvm::ConstantInt::get(CGF.Int64Ty, -Align), + "align_stack"); + + OnStackAddr = CGF.Builder.CreateIntToPtr(OnStackAddr, CGF.Int8PtrTy); + } + + uint64_t StackSize; + if (IsIndirect) + StackSize = 8; + else + StackSize = Ctx.getTypeSize(Ty) / 8; + + // All stack slots are 8 bytes + StackSize = llvm::RoundUpToAlignment(StackSize, 8); + + llvm::Value *StackSizeC = llvm::ConstantInt::get(CGF.Int32Ty, StackSize); + llvm::Value *NewStack = + CGF.Builder.CreateGEP(OnStackAddr, StackSizeC, "new_stack"); + + // Write the new value of __stack for the next call to va_arg + CGF.Builder.CreateStore(NewStack, stack_p); + + if (CGF.CGM.getDataLayout().isBigEndian() && !isAggregateTypeForABI(Ty) && + Ctx.getTypeSize(Ty) < 64) { + int Offset = 8 - Ctx.getTypeSize(Ty) / 8; + OnStackAddr = CGF.Builder.CreatePtrToInt(OnStackAddr, CGF.Int64Ty); + + OnStackAddr = CGF.Builder.CreateAdd( + OnStackAddr, llvm::ConstantInt::get(CGF.Int64Ty, Offset), "align_be"); + + OnStackAddr = CGF.Builder.CreateIntToPtr(OnStackAddr, CGF.Int8PtrTy); + } + + OnStackAddr = CGF.Builder.CreateBitCast(OnStackAddr, MemTy); + + CGF.EmitBranch(ContBlock); + + //======================================= + // Tidy up + //======================================= + CGF.EmitBlock(ContBlock); + + llvm::PHINode *ResAddr = CGF.Builder.CreatePHI(MemTy, 2, "vaarg.addr"); + ResAddr->addIncoming(RegAddr, InRegBlock); + ResAddr->addIncoming(OnStackAddr, OnStackBlock); + + if (IsIndirect) + return CGF.Builder.CreateLoad(ResAddr, "vaarg.addr"); + + return ResAddr; +} + +llvm::Value *AArch64ABIInfo::EmitAAPCSVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const { + + unsigned AllocatedGPR = 0, AllocatedVFP = 0; + bool IsHA = false, IsSmallAggr = false; + ABIArgInfo AI = classifyArgumentType(Ty, AllocatedVFP, IsHA, AllocatedGPR, + IsSmallAggr, false /*IsNamedArg*/); + + return EmitAArch64VAArg(VAListAddr, Ty, AllocatedGPR, AllocatedVFP, + AI.isIndirect(), CGF); +} + +llvm::Value *AArch64ABIInfo::EmitDarwinVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const { + // We do not support va_arg for aggregates or illegal vector types. + // Lower VAArg here for these cases and use the LLVM va_arg instruction for + // other cases. + if (!isAggregateTypeForABI(Ty) && !isIllegalVectorType(Ty)) + return nullptr; + + uint64_t Size = CGF.getContext().getTypeSize(Ty) / 8; + uint64_t Align = CGF.getContext().getTypeAlign(Ty) / 8; + + const Type *Base = nullptr; + bool isHA = isHomogeneousAggregate(Ty, Base, getContext()); + + bool isIndirect = false; + // Arguments bigger than 16 bytes which aren't homogeneous aggregates should + // be passed indirectly. + if (Size > 16 && !isHA) { + isIndirect = true; + Size = 8; + Align = 8; + } + + llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); + llvm::Type *BPP = llvm::PointerType::getUnqual(BP); + + CGBuilderTy &Builder = CGF.Builder; + llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap"); + llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); + + if (isEmptyRecord(getContext(), Ty, true)) { + // These are ignored for parameter passing purposes. + llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); + return Builder.CreateBitCast(Addr, PTy); + } + + const uint64_t MinABIAlign = 8; + if (Align > MinABIAlign) { + llvm::Value *Offset = llvm::ConstantInt::get(CGF.Int32Ty, Align - 1); + Addr = Builder.CreateGEP(Addr, Offset); + llvm::Value *AsInt = Builder.CreatePtrToInt(Addr, CGF.Int64Ty); + llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int64Ty, ~(Align - 1)); + llvm::Value *Aligned = Builder.CreateAnd(AsInt, Mask); + Addr = Builder.CreateIntToPtr(Aligned, BP, "ap.align"); + } + + uint64_t Offset = llvm::RoundUpToAlignment(Size, MinABIAlign); + llvm::Value *NextAddr = Builder.CreateGEP( + Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset), "ap.next"); + Builder.CreateStore(NextAddr, VAListAddrAsBPP); + + if (isIndirect) + Addr = Builder.CreateLoad(Builder.CreateBitCast(Addr, BPP)); + llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); + llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy); + + return AddrTyped; +} + +//===----------------------------------------------------------------------===// // ARM ABI Implementation //===----------------------------------------------------------------------===// @@ -3064,35 +4013,62 @@ public: private: ABIKind Kind; + mutable int VFPRegs[16]; + const unsigned NumVFPs; + const unsigned NumGPRs; + mutable unsigned AllocatedGPRs; + mutable unsigned AllocatedVFPs; public: - ARMABIInfo(CodeGenTypes &CGT, ABIKind _Kind) : ABIInfo(CGT), Kind(_Kind) { + ARMABIInfo(CodeGenTypes &CGT, ABIKind _Kind) : ABIInfo(CGT), Kind(_Kind), + NumVFPs(16), NumGPRs(4) { setRuntimeCC(); + resetAllocatedRegs(); } bool isEABI() const { - StringRef Env = getTarget().getTriple().getEnvironmentName(); - return (Env == "gnueabi" || Env == "eabi" || - Env == "android" || Env == "androideabi"); + switch (getTarget().getTriple().getEnvironment()) { + case llvm::Triple::Android: + case llvm::Triple::EABI: + case llvm::Triple::EABIHF: + case llvm::Triple::GNUEABI: + case llvm::Triple::GNUEABIHF: + return true; + default: + return false; + } + } + + bool isEABIHF() const { + switch (getTarget().getTriple().getEnvironment()) { + case llvm::Triple::EABIHF: + case llvm::Triple::GNUEABIHF: + return true; + default: + return false; + } } ABIKind getABIKind() const { return Kind; } private: - ABIArgInfo classifyReturnType(QualType RetTy) const; - ABIArgInfo classifyArgumentType(QualType RetTy, int *VFPRegs, - unsigned &AllocatedVFP, - bool &IsHA) const; + ABIArgInfo classifyReturnType(QualType RetTy, bool isVariadic) const; + ABIArgInfo classifyArgumentType(QualType RetTy, bool isVariadic, + bool &IsCPRC) const; bool isIllegalVectorType(QualType Ty) const; - virtual void computeInfo(CGFunctionInfo &FI) const; + void computeInfo(CGFunctionInfo &FI) const override; - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; llvm::CallingConv::ID getLLVMDefaultCC() const; llvm::CallingConv::ID getABIDefaultCC() const; void setRuntimeCC(); + + void markAllocatedGPRs(unsigned Alignment, unsigned NumRequired) const; + void markAllocatedVFPs(unsigned Alignment, unsigned NumRequired) const; + void resetAllocatedRegs(void) const; }; class ARMTargetCodeGenInfo : public TargetCodeGenInfo { @@ -3104,16 +4080,16 @@ public: return static_cast<const ARMABIInfo&>(TargetCodeGenInfo::getABIInfo()); } - int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { + int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { return 13; } - StringRef getARCRetainAutoreleasedReturnValueMarker() const { + StringRef getARCRetainAutoreleasedReturnValueMarker() const override { return "mov\tr7, r7\t\t@ marker for objc_retainAutoreleaseReturnValue"; } bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, - llvm::Value *Address) const { + llvm::Value *Address) const override { llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4); // 0-15 are the 16 integer registers. @@ -3121,13 +4097,13 @@ public: return false; } - unsigned getSizeOfUnwindException() const { + unsigned getSizeOfUnwindException() const override { if (getABIInfo().isEABI()) return 88; return TargetCodeGenInfo::getSizeOfUnwindException(); } void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, - CodeGen::CodeGenModule &CGM) const { + CodeGen::CodeGenModule &CGM) const override { const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); if (!FD) return; @@ -3176,24 +4152,43 @@ void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const { // allocated to the lowest-numbered sequence of such registers. // C.2.vfp If the argument is a VFP CPRC then any VFP registers that are // unallocated are marked as unavailable. - unsigned AllocatedVFP = 0; - int VFPRegs[16] = { 0 }; - FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); - it != ie; ++it) { - unsigned PreAllocation = AllocatedVFP; - bool IsHA = false; + resetAllocatedRegs(); + + if (getCXXABI().classifyReturnType(FI)) { + if (FI.getReturnInfo().isIndirect()) + markAllocatedGPRs(1, 1); + } else { + FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), FI.isVariadic()); + } + for (auto &I : FI.arguments()) { + unsigned PreAllocationVFPs = AllocatedVFPs; + unsigned PreAllocationGPRs = AllocatedGPRs; + bool IsCPRC = false; // 6.1.2.3 There is one VFP co-processor register class using registers // s0-s15 (d0-d7) for passing arguments. - const unsigned NumVFPs = 16; - it->info = classifyArgumentType(it->type, VFPRegs, AllocatedVFP, IsHA); - // If we do not have enough VFP registers for the HA, any VFP registers - // that are unallocated are marked as unavailable. To achieve this, we add - // padding of (NumVFPs - PreAllocation) floats. - if (IsHA && AllocatedVFP > NumVFPs && PreAllocation < NumVFPs) { + I.info = classifyArgumentType(I.type, FI.isVariadic(), IsCPRC); + + // If we have allocated some arguments onto the stack (due to running + // out of VFP registers), we cannot split an argument between GPRs and + // the stack. If this situation occurs, we add padding to prevent the + // GPRs from being used. In this situation, the current argument could + // only be allocated by rule C.8, so rule C.6 would mark these GPRs as + // unusable anyway. + // We do not have to do this if the argument is being passed ByVal, as the + // backend can handle that situation correctly. + const bool StackUsed = PreAllocationGPRs > NumGPRs || PreAllocationVFPs > NumVFPs; + const bool IsByVal = I.info.isIndirect() && I.info.getIndirectByVal(); + if (!IsCPRC && PreAllocationGPRs < NumGPRs && AllocatedGPRs > NumGPRs && + StackUsed && !IsByVal) { llvm::Type *PaddingTy = llvm::ArrayType::get( - llvm::Type::getFloatTy(getVMContext()), NumVFPs - PreAllocation); - it->info = ABIArgInfo::getExpandWithPadding(false, PaddingTy); + llvm::Type::getInt32Ty(getVMContext()), NumGPRs - PreAllocationGPRs); + if (I.info.canHaveCoerceToType()) { + I.info = ABIArgInfo::getDirect(I.info.getCoerceToType() /* type */, 0 /* offset */, + PaddingTy); + } else { + I.info = ABIArgInfo::getDirect(nullptr /* type */, 0 /* offset */, + PaddingTy); + } } } @@ -3209,7 +4204,7 @@ void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const { /// Return the default calling convention that LLVM will use. llvm::CallingConv::ID ARMABIInfo::getLLVMDefaultCC() const { // The default calling convention that LLVM will infer. - if (getTarget().getTriple().getEnvironmentName()=="gnueabihf") + if (isEABIHF()) return llvm::CallingConv::ARM_AAPCS_VFP; else if (isEABI()) return llvm::CallingConv::ARM_AAPCS; @@ -3243,8 +4238,7 @@ void ARMABIInfo::setRuntimeCC() { /// contained in the type is returned through it; this is used for the /// recursive calls that check aggregate component types. static bool isHomogeneousAggregate(QualType Ty, const Type *&Base, - ASTContext &Context, - uint64_t *HAMembers = 0) { + ASTContext &Context, uint64_t *HAMembers) { uint64_t Members = 0; if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) { if (!isHomogeneousAggregate(AT->getElementType(), Base, Context, &Members)) @@ -3256,9 +4250,7 @@ static bool isHomogeneousAggregate(QualType Ty, const Type *&Base, return false; Members = 0; - for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); - i != e; ++i) { - const FieldDecl *FD = *i; + for (const auto *FD : RD->fields()) { uint64_t FldMembers; if (!isHomogeneousAggregate(FD->getType(), Base, Context, &FldMembers)) return false; @@ -3293,10 +4285,29 @@ static bool isHomogeneousAggregate(QualType Ty, const Type *&Base, const Type *TyPtr = Ty.getTypePtr(); if (!Base) Base = TyPtr; - if (Base != TyPtr && - (!Base->isVectorType() || !TyPtr->isVectorType() || - Context.getTypeSize(Base) != Context.getTypeSize(TyPtr))) - return false; + + if (Base != TyPtr) { + // Homogeneous aggregates are defined as containing members with the + // same machine type. There are two cases in which two members have + // different TypePtrs but the same machine type: + + // 1) Vectors of the same length, regardless of the type and number + // of their members. + const bool SameLengthVectors = Base->isVectorType() && TyPtr->isVectorType() + && (Context.getTypeSize(Base) == Context.getTypeSize(TyPtr)); + + // 2) In the 32-bit AAPCS, `double' and `long double' have the same + // machine type. This is not the case for the 64-bit AAPCS. + const bool SameSizeDoubles = + ( ( Base->isSpecificBuiltinType(BuiltinType::Double) + && TyPtr->isSpecificBuiltinType(BuiltinType::LongDouble)) + || ( Base->isSpecificBuiltinType(BuiltinType::LongDouble) + && TyPtr->isSpecificBuiltinType(BuiltinType::Double))) + && (Context.getTypeSize(Base) == Context.getTypeSize(TyPtr)); + + if (!SameLengthVectors && !SameSizeDoubles) + return false; + } } // Homogeneous Aggregates can have at most 4 members of the base type. @@ -3308,12 +4319,15 @@ static bool isHomogeneousAggregate(QualType Ty, const Type *&Base, /// markAllocatedVFPs - update VFPRegs according to the alignment and /// number of VFP registers (unit is S register) requested. -static void markAllocatedVFPs(int *VFPRegs, unsigned &AllocatedVFP, - unsigned Alignment, - unsigned NumRequired) { +void ARMABIInfo::markAllocatedVFPs(unsigned Alignment, + unsigned NumRequired) const { // Early Exit. - if (AllocatedVFP >= 16) + if (AllocatedVFPs >= 16) { + // We use AllocatedVFP > 16 to signal that some CPRCs were allocated on + // the stack. + AllocatedVFPs = 17; return; + } // C.1.vfp If the argument is a VFP CPRC and there are sufficient consecutive // VFP registers of the appropriate type unallocated then the argument is // allocated to the lowest-numbered sequence of such registers. @@ -3327,7 +4341,7 @@ static void markAllocatedVFPs(int *VFPRegs, unsigned &AllocatedVFP, if (FoundSlot) { for (unsigned J = I, JEnd = I + NumRequired; J < JEnd; J++) VFPRegs[J] = 1; - AllocatedVFP += NumRequired; + AllocatedVFPs += NumRequired; return; } } @@ -3335,12 +4349,31 @@ static void markAllocatedVFPs(int *VFPRegs, unsigned &AllocatedVFP, // unallocated are marked as unavailable. for (unsigned I = 0; I < 16; I++) VFPRegs[I] = 1; - AllocatedVFP = 17; // We do not have enough VFP registers. + AllocatedVFPs = 17; // We do not have enough VFP registers. } -ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, int *VFPRegs, - unsigned &AllocatedVFP, - bool &IsHA) const { +/// Update AllocatedGPRs to record the number of general purpose registers +/// which have been allocated. It is valid for AllocatedGPRs to go above 4, +/// this represents arguments being stored on the stack. +void ARMABIInfo::markAllocatedGPRs(unsigned Alignment, + unsigned NumRequired) const { + assert((Alignment == 1 || Alignment == 2) && "Alignment must be 4 or 8 bytes"); + + if (Alignment == 2 && AllocatedGPRs & 0x1) + AllocatedGPRs += 1; + + AllocatedGPRs += NumRequired; +} + +void ARMABIInfo::resetAllocatedRegs(void) const { + AllocatedGPRs = 0; + AllocatedVFPs = 0; + for (unsigned i = 0; i < NumVFPs; ++i) + VFPRegs[i] = 0; +} + +ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic, + bool &IsCPRC) const { // We update number of allocated VFPs according to // 6.1.2.1 The following argument types are VFP CPRCs: // A single-precision floating-point type (including promoted @@ -3356,58 +4389,85 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, int *VFPRegs, if (Size <= 32) { llvm::Type *ResType = llvm::Type::getInt32Ty(getVMContext()); + markAllocatedGPRs(1, 1); return ABIArgInfo::getDirect(ResType); } if (Size == 64) { llvm::Type *ResType = llvm::VectorType::get( llvm::Type::getInt32Ty(getVMContext()), 2); - markAllocatedVFPs(VFPRegs, AllocatedVFP, 2, 2); + if (getABIKind() == ARMABIInfo::AAPCS || isVariadic){ + markAllocatedGPRs(2, 2); + } else { + markAllocatedVFPs(2, 2); + IsCPRC = true; + } return ABIArgInfo::getDirect(ResType); } if (Size == 128) { llvm::Type *ResType = llvm::VectorType::get( llvm::Type::getInt32Ty(getVMContext()), 4); - markAllocatedVFPs(VFPRegs, AllocatedVFP, 4, 4); + if (getABIKind() == ARMABIInfo::AAPCS || isVariadic) { + markAllocatedGPRs(2, 4); + } else { + markAllocatedVFPs(4, 4); + IsCPRC = true; + } return ABIArgInfo::getDirect(ResType); } + markAllocatedGPRs(1, 1); return ABIArgInfo::getIndirect(0, /*ByVal=*/false); } // Update VFPRegs for legal vector types. - if (const VectorType *VT = Ty->getAs<VectorType>()) { - uint64_t Size = getContext().getTypeSize(VT); - // Size of a legal vector should be power of 2 and above 64. - markAllocatedVFPs(VFPRegs, AllocatedVFP, Size >= 128 ? 4 : 2, Size / 32); + if (getABIKind() == ARMABIInfo::AAPCS_VFP && !isVariadic) { + if (const VectorType *VT = Ty->getAs<VectorType>()) { + uint64_t Size = getContext().getTypeSize(VT); + // Size of a legal vector should be power of 2 and above 64. + markAllocatedVFPs(Size >= 128 ? 4 : 2, Size / 32); + IsCPRC = true; + } } // Update VFPRegs for floating point types. - if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { - if (BT->getKind() == BuiltinType::Half || - BT->getKind() == BuiltinType::Float) - markAllocatedVFPs(VFPRegs, AllocatedVFP, 1, 1); - if (BT->getKind() == BuiltinType::Double || - BT->getKind() == BuiltinType::LongDouble) - markAllocatedVFPs(VFPRegs, AllocatedVFP, 2, 2); + if (getABIKind() == ARMABIInfo::AAPCS_VFP && !isVariadic) { + if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { + if (BT->getKind() == BuiltinType::Half || + BT->getKind() == BuiltinType::Float) { + markAllocatedVFPs(1, 1); + IsCPRC = true; + } + if (BT->getKind() == BuiltinType::Double || + BT->getKind() == BuiltinType::LongDouble) { + markAllocatedVFPs(2, 2); + IsCPRC = true; + } + } } if (!isAggregateTypeForABI(Ty)) { // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs<EnumType>()) + if (const EnumType *EnumTy = Ty->getAs<EnumType>()) { Ty = EnumTy->getDecl()->getIntegerType(); + } + unsigned Size = getContext().getTypeSize(Ty); + if (!IsCPRC) + markAllocatedGPRs(Size > 32 ? 2 : 1, (Size + 31) / 32); return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); } - if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) { + markAllocatedGPRs(1, 1); return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); + } // Ignore empty records. if (isEmptyRecord(getContext(), Ty, true)) return ABIArgInfo::getIgnore(); - if (getABIKind() == ARMABIInfo::AAPCS_VFP) { + if (getABIKind() == ARMABIInfo::AAPCS_VFP && !isVariadic) { // Homogeneous Aggregates need to be expanded when we can fit the aggregate // into VFP registers. - const Type *Base = 0; + const Type *Base = nullptr; uint64_t Members = 0; if (isHomogeneousAggregate(Ty, Base, getContext(), &Members)) { assert(Base && "Base class should be set for homogeneous aggregate"); @@ -3415,17 +4475,17 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, int *VFPRegs, if (Base->isVectorType()) { // ElementSize is in number of floats. unsigned ElementSize = getContext().getTypeSize(Base) == 64 ? 2 : 4; - markAllocatedVFPs(VFPRegs, AllocatedVFP, ElementSize, + markAllocatedVFPs(ElementSize, Members * ElementSize); } else if (Base->isSpecificBuiltinType(BuiltinType::Float)) - markAllocatedVFPs(VFPRegs, AllocatedVFP, 1, Members); + markAllocatedVFPs(1, Members); else { assert(Base->isSpecificBuiltinType(BuiltinType::Double) || Base->isSpecificBuiltinType(BuiltinType::LongDouble)); - markAllocatedVFPs(VFPRegs, AllocatedVFP, 2, Members * 2); + markAllocatedVFPs(2, Members * 2); } - IsHA = true; - return ABIArgInfo::getExpand(); + IsCPRC = true; + return ABIArgInfo::getDirect(); } } @@ -3439,7 +4499,12 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, int *VFPRegs, getABIKind() == ARMABIInfo::AAPCS) ABIAlign = std::min(std::max(TyAlign, (uint64_t)4), (uint64_t)8); if (getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(64)) { - return ABIArgInfo::getIndirect(0, /*ByVal=*/true, + // Update Allocated GPRs. Since this is only used when the size of the + // argument is greater than 64 bytes, this will always use up any available + // registers (of which there are 4). We also don't care about getting the + // alignment right, because general-purpose registers cannot be back-filled. + markAllocatedGPRs(1, 4); + return ABIArgInfo::getIndirect(TyAlign, /*ByVal=*/true, /*Realign=*/TyAlign > ABIAlign); } @@ -3451,9 +4516,11 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, int *VFPRegs, if (getContext().getTypeAlign(Ty) <= 32) { ElemTy = llvm::Type::getInt32Ty(getVMContext()); SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32; + markAllocatedGPRs(1, SizeRegs); } else { ElemTy = llvm::Type::getInt64Ty(getVMContext()); SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64; + markAllocatedGPRs(2, SizeRegs * 2); } llvm::Type *STy = @@ -3546,13 +4613,16 @@ static bool isIntegerLikeType(QualType Ty, ASTContext &Context, return true; } -ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const { +ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, + bool isVariadic) const { if (RetTy->isVoidType()) return ABIArgInfo::getIgnore(); // Large vector types should be returned via memory. - if (RetTy->isVectorType() && getContext().getTypeSize(RetTy) > 128) + if (RetTy->isVectorType() && getContext().getTypeSize(RetTy) > 128) { + markAllocatedGPRs(1, 1); return ABIArgInfo::getIndirect(0); + } if (!isAggregateTypeForABI(RetTy)) { // Treat an enum type as its underlying type. @@ -3563,11 +4633,6 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const { ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); } - // Structures with either a non-trivial destructor or a non-trivial - // copy constructor are always indirect. - if (isRecordReturnIndirect(RetTy, getCXXABI())) - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); - // Are we following APCS? if (getABIKind() == APCS) { if (isEmptyRecord(getContext(), RetTy, false)) @@ -3593,6 +4658,7 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const { } // Otherwise return in memory. + markAllocatedGPRs(1, 1); return ABIArgInfo::getIndirect(0); } @@ -3602,8 +4668,8 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const { return ABIArgInfo::getIgnore(); // Check for homogeneous aggregates with AAPCS-VFP. - if (getABIKind() == AAPCS_VFP) { - const Type *Base = 0; + if (getABIKind() == AAPCS_VFP && !isVariadic) { + const Type *Base = nullptr; if (isHomogeneousAggregate(RetTy, Base, getContext())) { assert(Base && "Base class should be set for homogeneous aggregate"); // Homogeneous Aggregates are returned directly. @@ -3615,6 +4681,10 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const { // are returned indirectly. uint64_t Size = getContext().getTypeSize(RetTy); if (Size <= 32) { + if (getDataLayout().isBigEndian()) + // Return in 32 bit integer integer type (as if loaded by LDR, AAPCS 5.4) + return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext())); + // Return in the smallest viable integer type. if (Size <= 8) return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext())); @@ -3623,6 +4693,7 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const { return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext())); } + markAllocatedGPRs(1, 1); return ABIArgInfo::getIndirect(0); } @@ -3723,9 +4794,9 @@ class NaClARMABIInfo : public ABIInfo { public: NaClARMABIInfo(CodeGen::CodeGenTypes &CGT, ARMABIInfo::ABIKind Kind) : ABIInfo(CGT), PInfo(CGT), NInfo(CGT, Kind) {} - virtual void computeInfo(CGFunctionInfo &FI) const; - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + void computeInfo(CGFunctionInfo &FI) const override; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; private: PNaClABIInfo PInfo; // Used for generating calls with pnaclcall callingconv. ARMABIInfo NInfo; // Used for everything else. @@ -3754,418 +4825,6 @@ llvm::Value *NaClARMABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, } //===----------------------------------------------------------------------===// -// AArch64 ABI Implementation -//===----------------------------------------------------------------------===// - -namespace { - -class AArch64ABIInfo : public ABIInfo { -public: - AArch64ABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {} - -private: - // The AArch64 PCS is explicit about return types and argument types being - // handled identically, so we don't need to draw a distinction between - // Argument and Return classification. - ABIArgInfo classifyGenericType(QualType Ty, int &FreeIntRegs, - int &FreeVFPRegs) const; - - ABIArgInfo tryUseRegs(QualType Ty, int &FreeRegs, int RegsNeeded, bool IsInt, - llvm::Type *DirectTy = 0) const; - - virtual void computeInfo(CGFunctionInfo &FI) const; - - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; -}; - -class AArch64TargetCodeGenInfo : public TargetCodeGenInfo { -public: - AArch64TargetCodeGenInfo(CodeGenTypes &CGT) - :TargetCodeGenInfo(new AArch64ABIInfo(CGT)) {} - - const AArch64ABIInfo &getABIInfo() const { - return static_cast<const AArch64ABIInfo&>(TargetCodeGenInfo::getABIInfo()); - } - - int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { - return 31; - } - - bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, - llvm::Value *Address) const { - // 0-31 are x0-x30 and sp: 8 bytes each - llvm::Value *Eight8 = llvm::ConstantInt::get(CGF.Int8Ty, 8); - AssignToArrayRange(CGF.Builder, Address, Eight8, 0, 31); - - // 64-95 are v0-v31: 16 bytes each - llvm::Value *Sixteen8 = llvm::ConstantInt::get(CGF.Int8Ty, 16); - AssignToArrayRange(CGF.Builder, Address, Sixteen8, 64, 95); - - return false; - } - -}; - -} - -void AArch64ABIInfo::computeInfo(CGFunctionInfo &FI) const { - int FreeIntRegs = 8, FreeVFPRegs = 8; - - FI.getReturnInfo() = classifyGenericType(FI.getReturnType(), - FreeIntRegs, FreeVFPRegs); - - FreeIntRegs = FreeVFPRegs = 8; - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); - it != ie; ++it) { - it->info = classifyGenericType(it->type, FreeIntRegs, FreeVFPRegs); - - } -} - -ABIArgInfo -AArch64ABIInfo::tryUseRegs(QualType Ty, int &FreeRegs, int RegsNeeded, - bool IsInt, llvm::Type *DirectTy) const { - if (FreeRegs >= RegsNeeded) { - FreeRegs -= RegsNeeded; - return ABIArgInfo::getDirect(DirectTy); - } - - llvm::Type *Padding = 0; - - // We need padding so that later arguments don't get filled in anyway. That - // wouldn't happen if only ByVal arguments followed in the same category, but - // a large structure will simply seem to be a pointer as far as LLVM is - // concerned. - if (FreeRegs > 0) { - if (IsInt) - Padding = llvm::Type::getInt64Ty(getVMContext()); - else - Padding = llvm::Type::getFloatTy(getVMContext()); - - // Either [N x i64] or [N x float]. - Padding = llvm::ArrayType::get(Padding, FreeRegs); - FreeRegs = 0; - } - - return ABIArgInfo::getIndirect(getContext().getTypeAlign(Ty) / 8, - /*IsByVal=*/ true, /*Realign=*/ false, - Padding); -} - - -ABIArgInfo AArch64ABIInfo::classifyGenericType(QualType Ty, - int &FreeIntRegs, - int &FreeVFPRegs) const { - // Can only occurs for return, but harmless otherwise. - if (Ty->isVoidType()) - return ABIArgInfo::getIgnore(); - - // Large vector types should be returned via memory. There's no such concept - // in the ABI, but they'd be over 16 bytes anyway so no matter how they're - // classified they'd go into memory (see B.3). - if (Ty->isVectorType() && getContext().getTypeSize(Ty) > 128) { - if (FreeIntRegs > 0) - --FreeIntRegs; - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); - } - - // All non-aggregate LLVM types have a concrete ABI representation so they can - // be passed directly. After this block we're guaranteed to be in a - // complicated case. - if (!isAggregateTypeForABI(Ty)) { - // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs<EnumType>()) - Ty = EnumTy->getDecl()->getIntegerType(); - - if (Ty->isFloatingType() || Ty->isVectorType()) - return tryUseRegs(Ty, FreeVFPRegs, /*RegsNeeded=*/ 1, /*IsInt=*/ false); - - assert(getContext().getTypeSize(Ty) <= 128 && - "unexpectedly large scalar type"); - - int RegsNeeded = getContext().getTypeSize(Ty) > 64 ? 2 : 1; - - // If the type may need padding registers to ensure "alignment", we must be - // careful when this is accounted for. Increasing the effective size covers - // all cases. - if (getContext().getTypeAlign(Ty) == 128) - RegsNeeded += FreeIntRegs % 2 != 0; - - return tryUseRegs(Ty, FreeIntRegs, RegsNeeded, /*IsInt=*/ true); - } - - if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) { - if (FreeIntRegs > 0 && RAA == CGCXXABI::RAA_Indirect) - --FreeIntRegs; - return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); - } - - if (isEmptyRecord(getContext(), Ty, true)) { - if (!getContext().getLangOpts().CPlusPlus) { - // Empty structs outside C++ mode are a GNU extension, so no ABI can - // possibly tell us what to do. It turns out (I believe) that GCC ignores - // the object for parameter-passsing purposes. - return ABIArgInfo::getIgnore(); - } - - // The combination of C++98 9p5 (sizeof(struct) != 0) and the pseudocode - // description of va_arg in the PCS require that an empty struct does - // actually occupy space for parameter-passing. I'm hoping for a - // clarification giving an explicit paragraph to point to in future. - return tryUseRegs(Ty, FreeIntRegs, /*RegsNeeded=*/ 1, /*IsInt=*/ true, - llvm::Type::getInt8Ty(getVMContext())); - } - - // Homogeneous vector aggregates get passed in registers or on the stack. - const Type *Base = 0; - uint64_t NumMembers = 0; - if (isHomogeneousAggregate(Ty, Base, getContext(), &NumMembers)) { - assert(Base && "Base class should be set for homogeneous aggregate"); - // Homogeneous aggregates are passed and returned directly. - return tryUseRegs(Ty, FreeVFPRegs, /*RegsNeeded=*/ NumMembers, - /*IsInt=*/ false); - } - - uint64_t Size = getContext().getTypeSize(Ty); - if (Size <= 128) { - // Small structs can use the same direct type whether they're in registers - // or on the stack. - llvm::Type *BaseTy; - unsigned NumBases; - int SizeInRegs = (Size + 63) / 64; - - if (getContext().getTypeAlign(Ty) == 128) { - BaseTy = llvm::Type::getIntNTy(getVMContext(), 128); - NumBases = 1; - - // If the type may need padding registers to ensure "alignment", we must - // be careful when this is accounted for. Increasing the effective size - // covers all cases. - SizeInRegs += FreeIntRegs % 2 != 0; - } else { - BaseTy = llvm::Type::getInt64Ty(getVMContext()); - NumBases = SizeInRegs; - } - llvm::Type *DirectTy = llvm::ArrayType::get(BaseTy, NumBases); - - return tryUseRegs(Ty, FreeIntRegs, /*RegsNeeded=*/ SizeInRegs, - /*IsInt=*/ true, DirectTy); - } - - // If the aggregate is > 16 bytes, it's passed and returned indirectly. In - // LLVM terms the return uses an "sret" pointer, but that's handled elsewhere. - --FreeIntRegs; - return ABIArgInfo::getIndirect(0, /* byVal = */ false); -} - -llvm::Value *AArch64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const { - // The AArch64 va_list type and handling is specified in the Procedure Call - // Standard, section B.4: - // - // struct { - // void *__stack; - // void *__gr_top; - // void *__vr_top; - // int __gr_offs; - // int __vr_offs; - // }; - - assert(!CGF.CGM.getDataLayout().isBigEndian() - && "va_arg not implemented for big-endian AArch64"); - - int FreeIntRegs = 8, FreeVFPRegs = 8; - Ty = CGF.getContext().getCanonicalType(Ty); - ABIArgInfo AI = classifyGenericType(Ty, FreeIntRegs, FreeVFPRegs); - - llvm::BasicBlock *MaybeRegBlock = CGF.createBasicBlock("vaarg.maybe_reg"); - llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg"); - llvm::BasicBlock *OnStackBlock = CGF.createBasicBlock("vaarg.on_stack"); - llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end"); - - llvm::Value *reg_offs_p = 0, *reg_offs = 0; - int reg_top_index; - int RegSize; - if (FreeIntRegs < 8) { - assert(FreeVFPRegs == 8 && "Arguments never split between int & VFP regs"); - // 3 is the field number of __gr_offs - reg_offs_p = CGF.Builder.CreateStructGEP(VAListAddr, 3, "gr_offs_p"); - reg_offs = CGF.Builder.CreateLoad(reg_offs_p, "gr_offs"); - reg_top_index = 1; // field number for __gr_top - RegSize = 8 * (8 - FreeIntRegs); - } else { - assert(FreeVFPRegs < 8 && "Argument must go in VFP or int regs"); - // 4 is the field number of __vr_offs. - reg_offs_p = CGF.Builder.CreateStructGEP(VAListAddr, 4, "vr_offs_p"); - reg_offs = CGF.Builder.CreateLoad(reg_offs_p, "vr_offs"); - reg_top_index = 2; // field number for __vr_top - RegSize = 16 * (8 - FreeVFPRegs); - } - - //======================================= - // Find out where argument was passed - //======================================= - - // If reg_offs >= 0 we're already using the stack for this type of - // argument. We don't want to keep updating reg_offs (in case it overflows, - // though anyone passing 2GB of arguments, each at most 16 bytes, deserves - // whatever they get). - llvm::Value *UsingStack = 0; - UsingStack = CGF.Builder.CreateICmpSGE(reg_offs, - llvm::ConstantInt::get(CGF.Int32Ty, 0)); - - CGF.Builder.CreateCondBr(UsingStack, OnStackBlock, MaybeRegBlock); - - // Otherwise, at least some kind of argument could go in these registers, the - // quesiton is whether this particular type is too big. - CGF.EmitBlock(MaybeRegBlock); - - // Integer arguments may need to correct register alignment (for example a - // "struct { __int128 a; };" gets passed in x_2N, x_{2N+1}). In this case we - // align __gr_offs to calculate the potential address. - if (FreeIntRegs < 8 && AI.isDirect() && getContext().getTypeAlign(Ty) > 64) { - int Align = getContext().getTypeAlign(Ty) / 8; - - reg_offs = CGF.Builder.CreateAdd(reg_offs, - llvm::ConstantInt::get(CGF.Int32Ty, Align - 1), - "align_regoffs"); - reg_offs = CGF.Builder.CreateAnd(reg_offs, - llvm::ConstantInt::get(CGF.Int32Ty, -Align), - "aligned_regoffs"); - } - - // Update the gr_offs/vr_offs pointer for next call to va_arg on this va_list. - llvm::Value *NewOffset = 0; - NewOffset = CGF.Builder.CreateAdd(reg_offs, - llvm::ConstantInt::get(CGF.Int32Ty, RegSize), - "new_reg_offs"); - CGF.Builder.CreateStore(NewOffset, reg_offs_p); - - // Now we're in a position to decide whether this argument really was in - // registers or not. - llvm::Value *InRegs = 0; - InRegs = CGF.Builder.CreateICmpSLE(NewOffset, - llvm::ConstantInt::get(CGF.Int32Ty, 0), - "inreg"); - - CGF.Builder.CreateCondBr(InRegs, InRegBlock, OnStackBlock); - - //======================================= - // Argument was in registers - //======================================= - - // Now we emit the code for if the argument was originally passed in - // registers. First start the appropriate block: - CGF.EmitBlock(InRegBlock); - - llvm::Value *reg_top_p = 0, *reg_top = 0; - reg_top_p = CGF.Builder.CreateStructGEP(VAListAddr, reg_top_index, "reg_top_p"); - reg_top = CGF.Builder.CreateLoad(reg_top_p, "reg_top"); - llvm::Value *BaseAddr = CGF.Builder.CreateGEP(reg_top, reg_offs); - llvm::Value *RegAddr = 0; - llvm::Type *MemTy = llvm::PointerType::getUnqual(CGF.ConvertTypeForMem(Ty)); - - if (!AI.isDirect()) { - // If it's been passed indirectly (actually a struct), whatever we find from - // stored registers or on the stack will actually be a struct **. - MemTy = llvm::PointerType::getUnqual(MemTy); - } - - const Type *Base = 0; - uint64_t NumMembers; - if (isHomogeneousAggregate(Ty, Base, getContext(), &NumMembers) - && NumMembers > 1) { - // Homogeneous aggregates passed in registers will have their elements split - // and stored 16-bytes apart regardless of size (they're notionally in qN, - // qN+1, ...). We reload and store into a temporary local variable - // contiguously. - assert(AI.isDirect() && "Homogeneous aggregates should be passed directly"); - llvm::Type *BaseTy = CGF.ConvertType(QualType(Base, 0)); - llvm::Type *HFATy = llvm::ArrayType::get(BaseTy, NumMembers); - llvm::Value *Tmp = CGF.CreateTempAlloca(HFATy); - - for (unsigned i = 0; i < NumMembers; ++i) { - llvm::Value *BaseOffset = llvm::ConstantInt::get(CGF.Int32Ty, 16 * i); - llvm::Value *LoadAddr = CGF.Builder.CreateGEP(BaseAddr, BaseOffset); - LoadAddr = CGF.Builder.CreateBitCast(LoadAddr, - llvm::PointerType::getUnqual(BaseTy)); - llvm::Value *StoreAddr = CGF.Builder.CreateStructGEP(Tmp, i); - - llvm::Value *Elem = CGF.Builder.CreateLoad(LoadAddr); - CGF.Builder.CreateStore(Elem, StoreAddr); - } - - RegAddr = CGF.Builder.CreateBitCast(Tmp, MemTy); - } else { - // Otherwise the object is contiguous in memory - RegAddr = CGF.Builder.CreateBitCast(BaseAddr, MemTy); - } - - CGF.EmitBranch(ContBlock); - - //======================================= - // Argument was on the stack - //======================================= - CGF.EmitBlock(OnStackBlock); - - llvm::Value *stack_p = 0, *OnStackAddr = 0; - stack_p = CGF.Builder.CreateStructGEP(VAListAddr, 0, "stack_p"); - OnStackAddr = CGF.Builder.CreateLoad(stack_p, "stack"); - - // Again, stack arguments may need realigmnent. In this case both integer and - // floating-point ones might be affected. - if (AI.isDirect() && getContext().getTypeAlign(Ty) > 64) { - int Align = getContext().getTypeAlign(Ty) / 8; - - OnStackAddr = CGF.Builder.CreatePtrToInt(OnStackAddr, CGF.Int64Ty); - - OnStackAddr = CGF.Builder.CreateAdd(OnStackAddr, - llvm::ConstantInt::get(CGF.Int64Ty, Align - 1), - "align_stack"); - OnStackAddr = CGF.Builder.CreateAnd(OnStackAddr, - llvm::ConstantInt::get(CGF.Int64Ty, -Align), - "align_stack"); - - OnStackAddr = CGF.Builder.CreateIntToPtr(OnStackAddr, CGF.Int8PtrTy); - } - - uint64_t StackSize; - if (AI.isDirect()) - StackSize = getContext().getTypeSize(Ty) / 8; - else - StackSize = 8; - - // All stack slots are 8 bytes - StackSize = llvm::RoundUpToAlignment(StackSize, 8); - - llvm::Value *StackSizeC = llvm::ConstantInt::get(CGF.Int32Ty, StackSize); - llvm::Value *NewStack = CGF.Builder.CreateGEP(OnStackAddr, StackSizeC, - "new_stack"); - - // Write the new value of __stack for the next call to va_arg - CGF.Builder.CreateStore(NewStack, stack_p); - - OnStackAddr = CGF.Builder.CreateBitCast(OnStackAddr, MemTy); - - CGF.EmitBranch(ContBlock); - - //======================================= - // Tidy up - //======================================= - CGF.EmitBlock(ContBlock); - - llvm::PHINode *ResAddr = CGF.Builder.CreatePHI(MemTy, 2, "vaarg.addr"); - ResAddr->addIncoming(RegAddr, InRegBlock); - ResAddr->addIncoming(OnStackAddr, OnStackBlock); - - if (AI.isDirect()) - return ResAddr; - - return CGF.Builder.CreateLoad(ResAddr, "vaarg.addr"); -} - -//===----------------------------------------------------------------------===// // NVPTX ABI Implementation //===----------------------------------------------------------------------===// @@ -4178,20 +4837,22 @@ public: ABIArgInfo classifyReturnType(QualType RetTy) const; ABIArgInfo classifyArgumentType(QualType Ty) const; - virtual void computeInfo(CGFunctionInfo &FI) const; - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CFG) const; + void computeInfo(CGFunctionInfo &FI) const override; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CFG) const override; }; class NVPTXTargetCodeGenInfo : public TargetCodeGenInfo { public: NVPTXTargetCodeGenInfo(CodeGenTypes &CGT) : TargetCodeGenInfo(new NVPTXABIInfo(CGT)) {} - - virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, - CodeGen::CodeGenModule &M) const; + + void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) const override; private: - static void addKernelMetadata(llvm::Function *F); + // Adds a NamedMDNode with F, Name, and Operand as operands, and adds the + // resulting MDNode to the nvvm.annotations MDNode. + static void addNVVMMetadata(llvm::Function *F, StringRef Name, int Operand); }; ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const { @@ -4220,10 +4881,10 @@ ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const { } void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const { - FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); - it != ie; ++it) - it->info = classifyArgumentType(it->type); + if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + for (auto &I : FI.arguments()) + I.info = classifyArgumentType(I.type); // Always honor user-specified calling convention. if (FI.getCallingConvention() != llvm::CallingConv::C) @@ -4251,7 +4912,8 @@ SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, // By default, all functions are device functions if (FD->hasAttr<OpenCLKernelAttr>()) { // OpenCL __kernel functions get kernel metadata - addKernelMetadata(F); + // Create !{<func-ref>, metadata !"kernel", i32 1} node + addNVVMMetadata(F, "kernel", 1); // And kernel functions are not subject to inlining F->addFnAttr(llvm::Attribute::NoInline); } @@ -4262,28 +4924,41 @@ SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, // CUDA __global__ functions get a kernel metadata entry. Since // __global__ functions cannot be called from the device, we do not // need to set the noinline attribute. - if (FD->getAttr<CUDAGlobalAttr>()) - addKernelMetadata(F); + if (FD->hasAttr<CUDAGlobalAttr>()) { + // Create !{<func-ref>, metadata !"kernel", i32 1} node + addNVVMMetadata(F, "kernel", 1); + } + if (FD->hasAttr<CUDALaunchBoundsAttr>()) { + // Create !{<func-ref>, metadata !"maxntidx", i32 <val>} node + addNVVMMetadata(F, "maxntidx", + FD->getAttr<CUDALaunchBoundsAttr>()->getMaxThreads()); + // min blocks is a default argument for CUDALaunchBoundsAttr, so getting a + // zero value from getMinBlocks either means it was not specified in + // __launch_bounds__ or the user specified a 0 value. In both cases, we + // don't have to add a PTX directive. + int MinCTASM = FD->getAttr<CUDALaunchBoundsAttr>()->getMinBlocks(); + if (MinCTASM > 0) { + // Create !{<func-ref>, metadata !"minctasm", i32 <val>} node + addNVVMMetadata(F, "minctasm", MinCTASM); + } + } } } -void NVPTXTargetCodeGenInfo::addKernelMetadata(llvm::Function *F) { +void NVPTXTargetCodeGenInfo::addNVVMMetadata(llvm::Function *F, StringRef Name, + int Operand) { llvm::Module *M = F->getParent(); llvm::LLVMContext &Ctx = M->getContext(); // Get "nvvm.annotations" metadata node llvm::NamedMDNode *MD = M->getOrInsertNamedMetadata("nvvm.annotations"); - // Create !{<func-ref>, metadata !"kernel", i32 1} node - llvm::SmallVector<llvm::Value *, 3> MDVals; - MDVals.push_back(F); - MDVals.push_back(llvm::MDString::get(Ctx, "kernel")); - MDVals.push_back(llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), 1)); - + llvm::Value *MDVals[] = { + F, llvm::MDString::get(Ctx, Name), + llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), Operand)}; // Append metadata to nvvm.annotations MD->addOperand(llvm::MDNode::get(Ctx, MDVals)); } - } //===----------------------------------------------------------------------===// @@ -4303,15 +4978,15 @@ public: ABIArgInfo classifyReturnType(QualType RetTy) const; ABIArgInfo classifyArgumentType(QualType ArgTy) const; - virtual void computeInfo(CGFunctionInfo &FI) const { - FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); - it != ie; ++it) - it->info = classifyArgumentType(it->type); + void computeInfo(CGFunctionInfo &FI) const override { + if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + for (auto &I : FI.arguments()) + I.info = classifyArgumentType(I.type); } - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; }; class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { @@ -4363,9 +5038,8 @@ bool SystemZABIInfo::isFPArgumentType(QualType Ty) const { // If this is a C++ record, check the bases first. if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) - for (CXXRecordDecl::base_class_const_iterator I = CXXRD->bases_begin(), - E = CXXRD->bases_end(); I != E; ++I) { - QualType Base = I->getType(); + for (const auto &I : CXXRD->bases()) { + QualType Base = I.getType(); // Empty bases don't affect things either way. if (isEmptyRecord(getContext(), Base, true)) @@ -4379,10 +5053,7 @@ bool SystemZABIInfo::isFPArgumentType(QualType Ty) const { } // Check the fields. - for (RecordDecl::field_iterator I = RD->field_begin(), - E = RD->field_end(); I != E; ++I) { - const FieldDecl *FD = *I; - + for (const auto *FD : RD->fields()) { // Empty bitfields don't affect things either way. // Unlike isSingleElementStruct(), empty structure and array fields // do count. So do anonymous bitfields that aren't zero-sized. @@ -4455,7 +5126,7 @@ llvm::Value *SystemZABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, llvm::Type *IndexTy = RegCount->getType(); llvm::Value *MaxRegsV = llvm::ConstantInt::get(IndexTy, MaxRegs); llvm::Value *InRegs = CGF.Builder.CreateICmpULT(RegCount, MaxRegsV, - "fits_in_regs"); + "fits_in_regs"); llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg"); llvm::BasicBlock *InMemBlock = CGF.createBasicBlock("vaarg.in_mem"); @@ -4521,37 +5192,6 @@ llvm::Value *SystemZABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, return ResAddr; } -bool X86_32TargetCodeGenInfo::isStructReturnInRegABI( - const llvm::Triple &Triple, const CodeGenOptions &Opts) { - assert(Triple.getArch() == llvm::Triple::x86); - - switch (Opts.getStructReturnConvention()) { - case CodeGenOptions::SRCK_Default: - break; - case CodeGenOptions::SRCK_OnStack: // -fpcc-struct-return - return false; - case CodeGenOptions::SRCK_InRegs: // -freg-struct-return - return true; - } - - if (Triple.isOSDarwin()) - return true; - - switch (Triple.getOS()) { - case llvm::Triple::Cygwin: - case llvm::Triple::MinGW32: - case llvm::Triple::AuroraUX: - case llvm::Triple::DragonFly: - case llvm::Triple::FreeBSD: - case llvm::Triple::OpenBSD: - case llvm::Triple::Bitrig: - case llvm::Triple::Win32: - return true; - default: - return false; - } -} - ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const { if (RetTy->isVoidType()) return ABIArgInfo::getIgnore(); @@ -4600,7 +5240,7 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const { if (isCompoundType(Ty)) return ABIArgInfo::getIndirect(0, /*ByVal=*/false); - return ABIArgInfo::getDirect(0); + return ABIArgInfo::getDirect(nullptr); } //===----------------------------------------------------------------------===// @@ -4614,7 +5254,7 @@ public: MSP430TargetCodeGenInfo(CodeGenTypes &CGT) : TargetCodeGenInfo(new DefaultABIInfo(CGT)) {} void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, - CodeGen::CodeGenModule &M) const; + CodeGen::CodeGenModule &M) const override; }; } @@ -4635,9 +5275,8 @@ void MSP430TargetCodeGenInfo::SetTargetAttributes(const Decl *D, // Step 3: Emit ISR vector alias. unsigned Num = attr->getNumber() / 2; - new llvm::GlobalAlias(GV->getType(), llvm::Function::ExternalLinkage, - "__isr_" + Twine(Num), - GV, &M.getModule()); + llvm::GlobalAlias::create(llvm::Function::ExternalLinkage, + "__isr_" + Twine(Num), F); } } } @@ -4663,9 +5302,9 @@ public: ABIArgInfo classifyReturnType(QualType RetTy) const; ABIArgInfo classifyArgumentType(QualType RetTy, uint64_t &Offset) const; - virtual void computeInfo(CGFunctionInfo &FI) const; - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + void computeInfo(CGFunctionInfo &FI) const override; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; }; class MIPSTargetCodeGenInfo : public TargetCodeGenInfo { @@ -4675,12 +5314,12 @@ public: : TargetCodeGenInfo(new MipsABIInfo(CGT, IsO32)), SizeOfUnwindException(IsO32 ? 24 : 32) {} - int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const { + int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override { return 29; } void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, - CodeGen::CodeGenModule &CGM) const { + CodeGen::CodeGenModule &CGM) const override { const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); if (!FD) return; llvm::Function *Fn = cast<llvm::Function>(GV); @@ -4693,9 +5332,9 @@ public: } bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, - llvm::Value *Address) const; + llvm::Value *Address) const override; - unsigned getSizeOfUnwindException() const { + unsigned getSizeOfUnwindException() const override { return SizeOfUnwindException; } }; @@ -4778,7 +5417,7 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const { llvm::Type *MipsABIInfo::getPaddingType(uint64_t OrigOffset, uint64_t Offset) const { if (OrigOffset + MinABIStackAlignInBytes > Offset) - return 0; + return nullptr; return llvm::IntegerType::get(getVMContext(), (Offset - OrigOffset) * 8); } @@ -4819,7 +5458,7 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const { return ABIArgInfo::getExtend(); return ABIArgInfo::getDirect( - 0, 0, IsO32 ? 0 : getPaddingType(OrigOffset, CurrOffset)); + nullptr, 0, IsO32 ? nullptr : getPaddingType(OrigOffset, CurrOffset)); } llvm::Type* @@ -4871,9 +5510,6 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const { return ABIArgInfo::getIgnore(); if (isAggregateTypeForABI(RetTy) || RetTy->isVectorType()) { - if (isRecordReturnIndirect(RetTy, getCXXABI())) - return ABIArgInfo::getIndirect(0); - if (Size <= 128) { if (RetTy->isAnyComplexType()) return ABIArgInfo::getDirect(); @@ -4899,14 +5535,14 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const { void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const { ABIArgInfo &RetInfo = FI.getReturnInfo(); - RetInfo = classifyReturnType(FI.getReturnType()); + if (!getCXXABI().classifyReturnType(FI)) + RetInfo = classifyReturnType(FI.getReturnType()); // Check if a pointer to an aggregate is passed as a hidden argument. uint64_t Offset = RetInfo.isIndirect() ? MinABIStackAlignInBytes : 0; - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); - it != ie; ++it) - it->info = classifyArgumentType(it->type, Offset); + for (auto &I : FI.arguments()) + I.info = classifyArgumentType(I.type, Offset); } llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, @@ -4987,8 +5623,8 @@ public: TCETargetCodeGenInfo(CodeGenTypes &CGT) : DefaultTargetCodeGenInfo(CGT) {} - virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, - CodeGen::CodeGenModule &M) const; + void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) const override; }; void TCETargetCodeGenInfo::SetTargetAttributes(const Decl *D, @@ -5003,9 +5639,8 @@ void TCETargetCodeGenInfo::SetTargetAttributes(const Decl *D, if (FD->hasAttr<OpenCLKernelAttr>()) { // OpenCL C Kernel functions are not subject to inlining F->addFnAttr(llvm::Attribute::NoInline); - - if (FD->hasAttr<ReqdWorkGroupSizeAttr>()) { - + const ReqdWorkGroupSizeAttr *Attr = FD->getAttr<ReqdWorkGroupSizeAttr>(); + if (Attr) { // Convert the reqd_work_group_size() attributes to metadata. llvm::LLVMContext &Context = F->getContext(); llvm::NamedMDNode *OpenCLMetadata = @@ -5015,14 +5650,11 @@ void TCETargetCodeGenInfo::SetTargetAttributes(const Decl *D, Operands.push_back(F); Operands.push_back(llvm::Constant::getIntegerValue(M.Int32Ty, - llvm::APInt(32, - FD->getAttr<ReqdWorkGroupSizeAttr>()->getXDim()))); + llvm::APInt(32, Attr->getXDim()))); Operands.push_back(llvm::Constant::getIntegerValue(M.Int32Ty, - llvm::APInt(32, - FD->getAttr<ReqdWorkGroupSizeAttr>()->getYDim()))); + llvm::APInt(32, Attr->getYDim()))); Operands.push_back(llvm::Constant::getIntegerValue(M.Int32Ty, - llvm::APInt(32, - FD->getAttr<ReqdWorkGroupSizeAttr>()->getZDim()))); + llvm::APInt(32, Attr->getZDim()))); // Add a boolean constant operand for "required" (true) or "hint" (false) // for implementing the work_group_size_hint attr later. Currently @@ -5053,10 +5685,10 @@ private: ABIArgInfo classifyReturnType(QualType RetTy) const; ABIArgInfo classifyArgumentType(QualType RetTy) const; - virtual void computeInfo(CGFunctionInfo &FI) const; + void computeInfo(CGFunctionInfo &FI) const override; - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; }; class HexagonTargetCodeGenInfo : public TargetCodeGenInfo { @@ -5064,7 +5696,7 @@ public: HexagonTargetCodeGenInfo(CodeGenTypes &CGT) :TargetCodeGenInfo(new HexagonABIInfo(CGT)) {} - int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { + int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { return 29; } }; @@ -5072,10 +5704,10 @@ public: } void HexagonABIInfo::computeInfo(CGFunctionInfo &FI) const { - FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); - it != ie; ++it) - it->info = classifyArgumentType(it->type); + if (!getCXXABI().classifyReturnType(FI)) + FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + for (auto &I : FI.arguments()) + I.info = classifyArgumentType(I.type); } ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty) const { @@ -5126,11 +5758,6 @@ ABIArgInfo HexagonABIInfo::classifyReturnType(QualType RetTy) const { ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); } - // Structures with either a non-trivial destructor or a non-trivial - // copy constructor are always indirect. - if (isRecordReturnIndirect(RetTy, getCXXABI())) - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); - if (isEmptyRecord(getContext(), RetTy, true)) return ABIArgInfo::getIgnore(); @@ -5208,9 +5835,9 @@ public: private: ABIArgInfo classifyType(QualType RetTy, unsigned SizeLimit) const; - virtual void computeInfo(CGFunctionInfo &FI) const; - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + void computeInfo(CGFunctionInfo &FI) const override; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; // Coercion type builder for structs passed in registers. The coercion type // serves two purposes: @@ -5390,6 +6017,7 @@ llvm::Value *SparcV9ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, switch (AI.getKind()) { case ABIArgInfo::Expand: + case ABIArgInfo::InAlloca: llvm_unreachable("Unsupported ABI kind for va_arg"); case ABIArgInfo::Extend: @@ -5425,9 +6053,8 @@ llvm::Value *SparcV9ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, void SparcV9ABIInfo::computeInfo(CGFunctionInfo &FI) const { FI.getReturnInfo() = classifyType(FI.getReturnType(), 32 * 8); - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); - it != ie; ++it) - it->info = classifyType(it->type, 16 * 8); + for (auto &I : FI.arguments()) + I.info = classifyType(I.type, 16 * 8); } namespace { @@ -5436,12 +6063,12 @@ public: SparcV9TargetCodeGenInfo(CodeGenTypes &CGT) : TargetCodeGenInfo(new SparcV9ABIInfo(CGT)) {} - int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { + int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override { return 14; } bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, - llvm::Value *Address) const; + llvm::Value *Address) const override; }; } // end anonymous namespace @@ -5481,21 +6108,119 @@ SparcV9TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, //===----------------------------------------------------------------------===// -// Xcore ABI Implementation +// XCore ABI Implementation //===----------------------------------------------------------------------===// + namespace { + +/// A SmallStringEnc instance is used to build up the TypeString by passing +/// it by reference between functions that append to it. +typedef llvm::SmallString<128> SmallStringEnc; + +/// TypeStringCache caches the meta encodings of Types. +/// +/// The reason for caching TypeStrings is two fold: +/// 1. To cache a type's encoding for later uses; +/// 2. As a means to break recursive member type inclusion. +/// +/// A cache Entry can have a Status of: +/// NonRecursive: The type encoding is not recursive; +/// Recursive: The type encoding is recursive; +/// Incomplete: An incomplete TypeString; +/// IncompleteUsed: An incomplete TypeString that has been used in a +/// Recursive type encoding. +/// +/// A NonRecursive entry will have all of its sub-members expanded as fully +/// as possible. Whilst it may contain types which are recursive, the type +/// itself is not recursive and thus its encoding may be safely used whenever +/// the type is encountered. +/// +/// A Recursive entry will have all of its sub-members expanded as fully as +/// possible. The type itself is recursive and it may contain other types which +/// are recursive. The Recursive encoding must not be used during the expansion +/// of a recursive type's recursive branch. For simplicity the code uses +/// IncompleteCount to reject all usage of Recursive encodings for member types. +/// +/// An Incomplete entry is always a RecordType and only encodes its +/// identifier e.g. "s(S){}". Incomplete 'StubEnc' entries are ephemeral and +/// are placed into the cache during type expansion as a means to identify and +/// handle recursive inclusion of types as sub-members. If there is recursion +/// the entry becomes IncompleteUsed. +/// +/// During the expansion of a RecordType's members: +/// +/// If the cache contains a NonRecursive encoding for the member type, the +/// cached encoding is used; +/// +/// If the cache contains a Recursive encoding for the member type, the +/// cached encoding is 'Swapped' out, as it may be incorrect, and... +/// +/// If the member is a RecordType, an Incomplete encoding is placed into the +/// cache to break potential recursive inclusion of itself as a sub-member; +/// +/// Once a member RecordType has been expanded, its temporary incomplete +/// entry is removed from the cache. If a Recursive encoding was swapped out +/// it is swapped back in; +/// +/// If an incomplete entry is used to expand a sub-member, the incomplete +/// entry is marked as IncompleteUsed. The cache keeps count of how many +/// IncompleteUsed entries it currently contains in IncompleteUsedCount; +/// +/// If a member's encoding is found to be a NonRecursive or Recursive viz: +/// IncompleteUsedCount==0, the member's encoding is added to the cache. +/// Else the member is part of a recursive type and thus the recursion has +/// been exited too soon for the encoding to be correct for the member. +/// +class TypeStringCache { + enum Status {NonRecursive, Recursive, Incomplete, IncompleteUsed}; + struct Entry { + std::string Str; // The encoded TypeString for the type. + enum Status State; // Information about the encoding in 'Str'. + std::string Swapped; // A temporary place holder for a Recursive encoding + // during the expansion of RecordType's members. + }; + std::map<const IdentifierInfo *, struct Entry> Map; + unsigned IncompleteCount; // Number of Incomplete entries in the Map. + unsigned IncompleteUsedCount; // Number of IncompleteUsed entries in the Map. +public: + TypeStringCache() : IncompleteCount(0), IncompleteUsedCount(0) {}; + void addIncomplete(const IdentifierInfo *ID, std::string StubEnc); + bool removeIncomplete(const IdentifierInfo *ID); + void addIfComplete(const IdentifierInfo *ID, StringRef Str, + bool IsRecursive); + StringRef lookupStr(const IdentifierInfo *ID); +}; + +/// TypeString encodings for enum & union fields must be order. +/// FieldEncoding is a helper for this ordering process. +class FieldEncoding { + bool HasName; + std::string Enc; +public: + FieldEncoding(bool b, SmallStringEnc &e) : HasName(b), Enc(e.c_str()) {}; + StringRef str() {return Enc.c_str();}; + bool operator<(const FieldEncoding &rhs) const { + if (HasName != rhs.HasName) return HasName; + return Enc < rhs.Enc; + } +}; + class XCoreABIInfo : public DefaultABIInfo { public: XCoreABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {} - virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const; + llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const override; }; -class XcoreTargetCodeGenInfo : public TargetCodeGenInfo { +class XCoreTargetCodeGenInfo : public TargetCodeGenInfo { + mutable TypeStringCache TSC; public: - XcoreTargetCodeGenInfo(CodeGenTypes &CGT) + XCoreTargetCodeGenInfo(CodeGenTypes &CGT) :TargetCodeGenInfo(new XCoreABIInfo(CGT)) {} + void emitTargetMD(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &M) const override; }; + } // End anonymous namespace. llvm::Value *XCoreABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, @@ -5517,6 +6242,7 @@ llvm::Value *XCoreABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, uint64_t ArgSize = 0; switch (AI.getKind()) { case ABIArgInfo::Expand: + case ABIArgInfo::InAlloca: llvm_unreachable("Unsupported ABI kind for va_arg"); case ABIArgInfo::Ignore: Val = llvm::UndefValue::get(ArgPtrTy); @@ -5546,6 +6272,461 @@ llvm::Value *XCoreABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, return Val; } +/// During the expansion of a RecordType, an incomplete TypeString is placed +/// into the cache as a means to identify and break recursion. +/// If there is a Recursive encoding in the cache, it is swapped out and will +/// be reinserted by removeIncomplete(). +/// All other types of encoding should have been used rather than arriving here. +void TypeStringCache::addIncomplete(const IdentifierInfo *ID, + std::string StubEnc) { + if (!ID) + return; + Entry &E = Map[ID]; + assert( (E.Str.empty() || E.State == Recursive) && + "Incorrectly use of addIncomplete"); + assert(!StubEnc.empty() && "Passing an empty string to addIncomplete()"); + E.Swapped.swap(E.Str); // swap out the Recursive + E.Str.swap(StubEnc); + E.State = Incomplete; + ++IncompleteCount; +} + +/// Once the RecordType has been expanded, the temporary incomplete TypeString +/// must be removed from the cache. +/// If a Recursive was swapped out by addIncomplete(), it will be replaced. +/// Returns true if the RecordType was defined recursively. +bool TypeStringCache::removeIncomplete(const IdentifierInfo *ID) { + if (!ID) + return false; + auto I = Map.find(ID); + assert(I != Map.end() && "Entry not present"); + Entry &E = I->second; + assert( (E.State == Incomplete || + E.State == IncompleteUsed) && + "Entry must be an incomplete type"); + bool IsRecursive = false; + if (E.State == IncompleteUsed) { + // We made use of our Incomplete encoding, thus we are recursive. + IsRecursive = true; + --IncompleteUsedCount; + } + if (E.Swapped.empty()) + Map.erase(I); + else { + // Swap the Recursive back. + E.Swapped.swap(E.Str); + E.Swapped.clear(); + E.State = Recursive; + } + --IncompleteCount; + return IsRecursive; +} + +/// Add the encoded TypeString to the cache only if it is NonRecursive or +/// Recursive (viz: all sub-members were expanded as fully as possible). +void TypeStringCache::addIfComplete(const IdentifierInfo *ID, StringRef Str, + bool IsRecursive) { + if (!ID || IncompleteUsedCount) + return; // No key or it is is an incomplete sub-type so don't add. + Entry &E = Map[ID]; + if (IsRecursive && !E.Str.empty()) { + assert(E.State==Recursive && E.Str.size() == Str.size() && + "This is not the same Recursive entry"); + // The parent container was not recursive after all, so we could have used + // this Recursive sub-member entry after all, but we assumed the worse when + // we started viz: IncompleteCount!=0. + return; + } + assert(E.Str.empty() && "Entry already present"); + E.Str = Str.str(); + E.State = IsRecursive? Recursive : NonRecursive; +} + +/// Return a cached TypeString encoding for the ID. If there isn't one, or we +/// are recursively expanding a type (IncompleteCount != 0) and the cached +/// encoding is Recursive, return an empty StringRef. +StringRef TypeStringCache::lookupStr(const IdentifierInfo *ID) { + if (!ID) + return StringRef(); // We have no key. + auto I = Map.find(ID); + if (I == Map.end()) + return StringRef(); // We have no encoding. + Entry &E = I->second; + if (E.State == Recursive && IncompleteCount) + return StringRef(); // We don't use Recursive encodings for member types. + + if (E.State == Incomplete) { + // The incomplete type is being used to break out of recursion. + E.State = IncompleteUsed; + ++IncompleteUsedCount; + } + return E.Str.c_str(); +} + +/// The XCore ABI includes a type information section that communicates symbol +/// type information to the linker. The linker uses this information to verify +/// safety/correctness of things such as array bound and pointers et al. +/// The ABI only requires C (and XC) language modules to emit TypeStrings. +/// This type information (TypeString) is emitted into meta data for all global +/// symbols: definitions, declarations, functions & variables. +/// +/// The TypeString carries type, qualifier, name, size & value details. +/// Please see 'Tools Development Guide' section 2.16.2 for format details: +/// <https://www.xmos.com/download/public/Tools-Development-Guide%28X9114A%29.pdf> +/// The output is tested by test/CodeGen/xcore-stringtype.c. +/// +static bool getTypeString(SmallStringEnc &Enc, const Decl *D, + CodeGen::CodeGenModule &CGM, TypeStringCache &TSC); + +/// XCore uses emitTargetMD to emit TypeString metadata for global symbols. +void XCoreTargetCodeGenInfo::emitTargetMD(const Decl *D, llvm::GlobalValue *GV, + CodeGen::CodeGenModule &CGM) const { + SmallStringEnc Enc; + if (getTypeString(Enc, D, CGM, TSC)) { + llvm::LLVMContext &Ctx = CGM.getModule().getContext(); + llvm::SmallVector<llvm::Value *, 2> MDVals; + MDVals.push_back(GV); + MDVals.push_back(llvm::MDString::get(Ctx, Enc.str())); + llvm::NamedMDNode *MD = + CGM.getModule().getOrInsertNamedMetadata("xcore.typestrings"); + MD->addOperand(llvm::MDNode::get(Ctx, MDVals)); + } +} + +static bool appendType(SmallStringEnc &Enc, QualType QType, + const CodeGen::CodeGenModule &CGM, + TypeStringCache &TSC); + +/// Helper function for appendRecordType(). +/// Builds a SmallVector containing the encoded field types in declaration order. +static bool extractFieldType(SmallVectorImpl<FieldEncoding> &FE, + const RecordDecl *RD, + const CodeGen::CodeGenModule &CGM, + TypeStringCache &TSC) { + for (RecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); + I != E; ++I) { + SmallStringEnc Enc; + Enc += "m("; + Enc += I->getName(); + Enc += "){"; + if (I->isBitField()) { + Enc += "b("; + llvm::raw_svector_ostream OS(Enc); + OS.resync(); + OS << I->getBitWidthValue(CGM.getContext()); + OS.flush(); + Enc += ':'; + } + if (!appendType(Enc, I->getType(), CGM, TSC)) + return false; + if (I->isBitField()) + Enc += ')'; + Enc += '}'; + FE.push_back(FieldEncoding(!I->getName().empty(), Enc)); + } + return true; +} + +/// Appends structure and union types to Enc and adds encoding to cache. +/// Recursively calls appendType (via extractFieldType) for each field. +/// Union types have their fields ordered according to the ABI. +static bool appendRecordType(SmallStringEnc &Enc, const RecordType *RT, + const CodeGen::CodeGenModule &CGM, + TypeStringCache &TSC, const IdentifierInfo *ID) { + // Append the cached TypeString if we have one. + StringRef TypeString = TSC.lookupStr(ID); + if (!TypeString.empty()) { + Enc += TypeString; + return true; + } + + // Start to emit an incomplete TypeString. + size_t Start = Enc.size(); + Enc += (RT->isUnionType()? 'u' : 's'); + Enc += '('; + if (ID) + Enc += ID->getName(); + Enc += "){"; + + // We collect all encoded fields and order as necessary. + bool IsRecursive = false; + const RecordDecl *RD = RT->getDecl()->getDefinition(); + if (RD && !RD->field_empty()) { + // An incomplete TypeString stub is placed in the cache for this RecordType + // so that recursive calls to this RecordType will use it whilst building a + // complete TypeString for this RecordType. + SmallVector<FieldEncoding, 16> FE; + std::string StubEnc(Enc.substr(Start).str()); + StubEnc += '}'; // StubEnc now holds a valid incomplete TypeString. + TSC.addIncomplete(ID, std::move(StubEnc)); + if (!extractFieldType(FE, RD, CGM, TSC)) { + (void) TSC.removeIncomplete(ID); + return false; + } + IsRecursive = TSC.removeIncomplete(ID); + // The ABI requires unions to be sorted but not structures. + // See FieldEncoding::operator< for sort algorithm. + if (RT->isUnionType()) + std::sort(FE.begin(), FE.end()); + // We can now complete the TypeString. + unsigned E = FE.size(); + for (unsigned I = 0; I != E; ++I) { + if (I) + Enc += ','; + Enc += FE[I].str(); + } + } + Enc += '}'; + TSC.addIfComplete(ID, Enc.substr(Start), IsRecursive); + return true; +} + +/// Appends enum types to Enc and adds the encoding to the cache. +static bool appendEnumType(SmallStringEnc &Enc, const EnumType *ET, + TypeStringCache &TSC, + const IdentifierInfo *ID) { + // Append the cached TypeString if we have one. + StringRef TypeString = TSC.lookupStr(ID); + if (!TypeString.empty()) { + Enc += TypeString; + return true; + } + + size_t Start = Enc.size(); + Enc += "e("; + if (ID) + Enc += ID->getName(); + Enc += "){"; + + // We collect all encoded enumerations and order them alphanumerically. + if (const EnumDecl *ED = ET->getDecl()->getDefinition()) { + SmallVector<FieldEncoding, 16> FE; + for (auto I = ED->enumerator_begin(), E = ED->enumerator_end(); I != E; + ++I) { + SmallStringEnc EnumEnc; + EnumEnc += "m("; + EnumEnc += I->getName(); + EnumEnc += "){"; + I->getInitVal().toString(EnumEnc); + EnumEnc += '}'; + FE.push_back(FieldEncoding(!I->getName().empty(), EnumEnc)); + } + std::sort(FE.begin(), FE.end()); + unsigned E = FE.size(); + for (unsigned I = 0; I != E; ++I) { + if (I) + Enc += ','; + Enc += FE[I].str(); + } + } + Enc += '}'; + TSC.addIfComplete(ID, Enc.substr(Start), false); + return true; +} + +/// Appends type's qualifier to Enc. +/// This is done prior to appending the type's encoding. +static void appendQualifier(SmallStringEnc &Enc, QualType QT) { + // Qualifiers are emitted in alphabetical order. + static const char *Table[] = {"","c:","r:","cr:","v:","cv:","rv:","crv:"}; + int Lookup = 0; + if (QT.isConstQualified()) + Lookup += 1<<0; + if (QT.isRestrictQualified()) + Lookup += 1<<1; + if (QT.isVolatileQualified()) + Lookup += 1<<2; + Enc += Table[Lookup]; +} + +/// Appends built-in types to Enc. +static bool appendBuiltinType(SmallStringEnc &Enc, const BuiltinType *BT) { + const char *EncType; + switch (BT->getKind()) { + case BuiltinType::Void: + EncType = "0"; + break; + case BuiltinType::Bool: + EncType = "b"; + break; + case BuiltinType::Char_U: + EncType = "uc"; + break; + case BuiltinType::UChar: + EncType = "uc"; + break; + case BuiltinType::SChar: + EncType = "sc"; + break; + case BuiltinType::UShort: + EncType = "us"; + break; + case BuiltinType::Short: + EncType = "ss"; + break; + case BuiltinType::UInt: + EncType = "ui"; + break; + case BuiltinType::Int: + EncType = "si"; + break; + case BuiltinType::ULong: + EncType = "ul"; + break; + case BuiltinType::Long: + EncType = "sl"; + break; + case BuiltinType::ULongLong: + EncType = "ull"; + break; + case BuiltinType::LongLong: + EncType = "sll"; + break; + case BuiltinType::Float: + EncType = "ft"; + break; + case BuiltinType::Double: + EncType = "d"; + break; + case BuiltinType::LongDouble: + EncType = "ld"; + break; + default: + return false; + } + Enc += EncType; + return true; +} + +/// Appends a pointer encoding to Enc before calling appendType for the pointee. +static bool appendPointerType(SmallStringEnc &Enc, const PointerType *PT, + const CodeGen::CodeGenModule &CGM, + TypeStringCache &TSC) { + Enc += "p("; + if (!appendType(Enc, PT->getPointeeType(), CGM, TSC)) + return false; + Enc += ')'; + return true; +} + +/// Appends array encoding to Enc before calling appendType for the element. +static bool appendArrayType(SmallStringEnc &Enc, QualType QT, + const ArrayType *AT, + const CodeGen::CodeGenModule &CGM, + TypeStringCache &TSC, StringRef NoSizeEnc) { + if (AT->getSizeModifier() != ArrayType::Normal) + return false; + Enc += "a("; + if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT)) + CAT->getSize().toStringUnsigned(Enc); + else + Enc += NoSizeEnc; // Global arrays use "*", otherwise it is "". + Enc += ':'; + // The Qualifiers should be attached to the type rather than the array. + appendQualifier(Enc, QT); + if (!appendType(Enc, AT->getElementType(), CGM, TSC)) + return false; + Enc += ')'; + return true; +} + +/// Appends a function encoding to Enc, calling appendType for the return type +/// and the arguments. +static bool appendFunctionType(SmallStringEnc &Enc, const FunctionType *FT, + const CodeGen::CodeGenModule &CGM, + TypeStringCache &TSC) { + Enc += "f{"; + if (!appendType(Enc, FT->getReturnType(), CGM, TSC)) + return false; + Enc += "}("; + if (const FunctionProtoType *FPT = FT->getAs<FunctionProtoType>()) { + // N.B. we are only interested in the adjusted param types. + auto I = FPT->param_type_begin(); + auto E = FPT->param_type_end(); + if (I != E) { + do { + if (!appendType(Enc, *I, CGM, TSC)) + return false; + ++I; + if (I != E) + Enc += ','; + } while (I != E); + if (FPT->isVariadic()) + Enc += ",va"; + } else { + if (FPT->isVariadic()) + Enc += "va"; + else + Enc += '0'; + } + } + Enc += ')'; + return true; +} + +/// Handles the type's qualifier before dispatching a call to handle specific +/// type encodings. +static bool appendType(SmallStringEnc &Enc, QualType QType, + const CodeGen::CodeGenModule &CGM, + TypeStringCache &TSC) { + + QualType QT = QType.getCanonicalType(); + + if (const ArrayType *AT = QT->getAsArrayTypeUnsafe()) + // The Qualifiers should be attached to the type rather than the array. + // Thus we don't call appendQualifier() here. + return appendArrayType(Enc, QT, AT, CGM, TSC, ""); + + appendQualifier(Enc, QT); + + if (const BuiltinType *BT = QT->getAs<BuiltinType>()) + return appendBuiltinType(Enc, BT); + + if (const PointerType *PT = QT->getAs<PointerType>()) + return appendPointerType(Enc, PT, CGM, TSC); + + if (const EnumType *ET = QT->getAs<EnumType>()) + return appendEnumType(Enc, ET, TSC, QT.getBaseTypeIdentifier()); + + if (const RecordType *RT = QT->getAsStructureType()) + return appendRecordType(Enc, RT, CGM, TSC, QT.getBaseTypeIdentifier()); + + if (const RecordType *RT = QT->getAsUnionType()) + return appendRecordType(Enc, RT, CGM, TSC, QT.getBaseTypeIdentifier()); + + if (const FunctionType *FT = QT->getAs<FunctionType>()) + return appendFunctionType(Enc, FT, CGM, TSC); + + return false; +} + +static bool getTypeString(SmallStringEnc &Enc, const Decl *D, + CodeGen::CodeGenModule &CGM, TypeStringCache &TSC) { + if (!D) + return false; + + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + if (FD->getLanguageLinkage() != CLanguageLinkage) + return false; + return appendType(Enc, FD->getType(), CGM, TSC); + } + + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { + if (VD->getLanguageLinkage() != CLanguageLinkage) + return false; + QualType QT = VD->getType().getCanonicalType(); + if (const ArrayType *AT = QT->getAsArrayTypeUnsafe()) { + // Global ArrayTypes are given a size of '*' if the size is unknown. + // The Qualifiers should be attached to the type rather than the array. + // Thus we don't call appendQualifier() here. + return appendArrayType(Enc, QT, AT, CGM, TSC, "*"); + } + return appendType(Enc, QT, CGM, TSC); + } + return false; +} + + //===----------------------------------------------------------------------===// // Driver code //===----------------------------------------------------------------------===// @@ -5570,13 +6751,23 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, false)); case llvm::Triple::aarch64: - return *(TheTargetCodeGenInfo = new AArch64TargetCodeGenInfo(Types)); + case llvm::Triple::aarch64_be: + case llvm::Triple::arm64: + case llvm::Triple::arm64_be: { + AArch64ABIInfo::ABIKind Kind = AArch64ABIInfo::AAPCS; + if (getTarget().getABI() == "darwinpcs") + Kind = AArch64ABIInfo::DarwinPCS; + + return *(TheTargetCodeGenInfo = new AArch64TargetCodeGenInfo(Types, Kind)); + } case llvm::Triple::arm: + case llvm::Triple::armeb: case llvm::Triple::thumb: + case llvm::Triple::thumbeb: { ARMABIInfo::ABIKind Kind = ARMABIInfo::AAPCS; - if (strcmp(getTarget().getABI(), "apcs-gnu") == 0) + if (getTarget().getABI() == "apcs-gnu") Kind = ARMABIInfo::APCS; else if (CodeGenOpts.FloatABI == "hard" || (CodeGenOpts.FloatABI != "soft" && @@ -5596,13 +6787,20 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::ppc: return *(TheTargetCodeGenInfo = new PPC32TargetCodeGenInfo(Types)); case llvm::Triple::ppc64: - if (Triple.isOSBinFormatELF()) - return *(TheTargetCodeGenInfo = new PPC64_SVR4_TargetCodeGenInfo(Types)); - else + if (Triple.isOSBinFormatELF()) { + // FIXME: Should be switchable via command-line option. + PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv1; + return *(TheTargetCodeGenInfo = + new PPC64_SVR4_TargetCodeGenInfo(Types, Kind)); + } else return *(TheTargetCodeGenInfo = new PPC64TargetCodeGenInfo(Types)); - case llvm::Triple::ppc64le: + case llvm::Triple::ppc64le: { assert(Triple.isOSBinFormatELF() && "PPC64 LE non-ELF not supported!"); - return *(TheTargetCodeGenInfo = new PPC64_SVR4_TargetCodeGenInfo(Types)); + // FIXME: Should be switchable via command-line option. + PPC64_SVR4_ABIInfo::ABIKind Kind = PPC64_SVR4_ABIInfo::ELFv2; + return *(TheTargetCodeGenInfo = + new PPC64_SVR4_TargetCodeGenInfo(Types, Kind)); + } case llvm::Triple::nvptx: case llvm::Triple::nvptx64: @@ -5621,7 +6819,7 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { bool IsDarwinVectorABI = Triple.isOSDarwin(); bool IsSmallStructInRegABI = X86_32TargetCodeGenInfo::isStructReturnInRegABI(Triple, CodeGenOpts); - bool IsWin32FloatStructABI = (Triple.getOS() == llvm::Triple::Win32); + bool IsWin32FloatStructABI = Triple.isWindowsMSVCEnvironment(); if (Triple.getOS() == llvm::Triple::Win32) { return *(TheTargetCodeGenInfo = @@ -5639,12 +6837,10 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { } case llvm::Triple::x86_64: { - bool HasAVX = strcmp(getTarget().getABI(), "avx") == 0; + bool HasAVX = getTarget().getABI() == "avx"; switch (Triple.getOS()) { case llvm::Triple::Win32: - case llvm::Triple::MinGW32: - case llvm::Triple::Cygwin: return *(TheTargetCodeGenInfo = new WinX86_64TargetCodeGenInfo(Types)); case llvm::Triple::NaCl: return *(TheTargetCodeGenInfo = new NaClX86_64TargetCodeGenInfo(Types, @@ -5659,7 +6855,6 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::sparcv9: return *(TheTargetCodeGenInfo = new SparcV9TargetCodeGenInfo(Types)); case llvm::Triple::xcore: - return *(TheTargetCodeGenInfo = new XcoreTargetCodeGenInfo(Types)); - + return *(TheTargetCodeGenInfo = new XCoreTargetCodeGenInfo(Types)); } } |