diff options
Diffstat (limited to 'lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 624 |
1 files changed, 450 insertions, 174 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 612e72bdd7..f9689affa0 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -14,6 +14,7 @@ #include "TargetInfo.h" #include "ABIInfo.h" +#include "CGCXXABI.h" #include "CodeGenFunction.h" #include "clang/AST/RecordLayout.h" #include "clang/Frontend/CodeGenOptions.h" @@ -43,6 +44,37 @@ static bool isAggregateTypeForABI(QualType T) { ABIInfo::~ABIInfo() {} +static bool isRecordReturnIndirect(const RecordType *RT, CodeGen::CodeGenTypes &CGT) { + const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); + if (!RD) + return false; + return CGT.CGM.getCXXABI().isReturnTypeIndirect(RD); +} + + +static bool isRecordReturnIndirect(QualType T, CodeGen::CodeGenTypes &CGT) { + const RecordType *RT = T->getAs<RecordType>(); + if (!RT) + return false; + return isRecordReturnIndirect(RT, CGT); +} + +static CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, + CodeGen::CodeGenTypes &CGT) { + const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); + if (!RD) + return CGCXXABI::RAA_Default; + return CGT.CGM.getCXXABI().getRecordArgABI(RD); +} + +static CGCXXABI::RecordArgABI getRecordArgABI(QualType T, + CodeGen::CodeGenTypes &CGT) { + const RecordType *RT = T->getAs<RecordType>(); + if (!RT) + return CGCXXABI::RAA_Default; + return getRecordArgABI(RT, CGT); +} + ASTContext &ABIInfo::getContext() const { return CGT.getContext(); } @@ -55,6 +87,9 @@ const llvm::DataLayout &ABIInfo::getDataLayout() const { return CGT.getDataLayout(); } +const TargetInfo &ABIInfo::getTarget() const { + return CGT.getTarget(); +} void ABIArgInfo::dump() const { raw_ostream &OS = llvm::errs(); @@ -167,27 +202,6 @@ static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays) { return true; } -/// hasNonTrivialDestructorOrCopyConstructor - Determine if a type has either -/// a non-trivial destructor or a non-trivial copy constructor. -static bool hasNonTrivialDestructorOrCopyConstructor(const RecordType *RT) { - const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); - if (!RD) - return false; - - return !RD->hasTrivialDestructor() || RD->hasNonTrivialCopyConstructor(); -} - -/// isRecordWithNonTrivialDestructorOrCopyConstructor - Determine if a type is -/// a record type with either a non-trivial destructor or a non-trivial copy -/// constructor. -static bool isRecordWithNonTrivialDestructorOrCopyConstructor(QualType T) { - const RecordType *RT = T->getAs<RecordType>(); - if (!RT) - return false; - - return hasNonTrivialDestructorOrCopyConstructor(RT); -} - /// isSingleElementStruct - Determine if a structure is a "single /// element struct", i.e. it has exactly one non-empty field or /// exactly one field which is itself a single element @@ -367,7 +381,7 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { if (isAggregateTypeForABI(Ty)) { // Records with non trivial destructors/constructors should not be passed // by value. - if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) + if (isRecordReturnIndirect(Ty, CGT)) return ABIArgInfo::getIndirect(0, /*ByVal=*/false); return ABIArgInfo::getIndirect(0); @@ -398,6 +412,9 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const { //===----------------------------------------------------------------------===// // le32/PNaCl bitcode ABI Implementation +// +// This is a simplified version of the x86_32 ABI. Arguments and return values +// are always passed on the stack. //===----------------------------------------------------------------------===// class PNaClABIInfo : public ABIInfo { @@ -405,7 +422,7 @@ class PNaClABIInfo : public ABIInfo { PNaClABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {} ABIArgInfo classifyReturnType(QualType RetTy) const; - ABIArgInfo classifyArgumentType(QualType RetTy, unsigned &FreeRegs) const; + ABIArgInfo classifyArgumentType(QualType RetTy) const; virtual void computeInfo(CGFunctionInfo &FI) const; virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, @@ -425,11 +442,9 @@ class PNaClTargetCodeGenInfo : public TargetCodeGenInfo { void PNaClABIInfo::computeInfo(CGFunctionInfo &FI) const { FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); - unsigned FreeRegs = FI.getHasRegParm() ? FI.getRegParm() : 0; - for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); it != ie; ++it) - it->info = classifyArgumentType(it->type, FreeRegs); + it->info = classifyArgumentType(it->type); } llvm::Value *PNaClABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, @@ -437,42 +452,29 @@ llvm::Value *PNaClABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, return 0; } -ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty, - unsigned &FreeRegs) const { +/// \brief Classify argument of given type \p Ty. +ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty) const { if (isAggregateTypeForABI(Ty)) { - // Records with non trivial destructors/constructors should not be passed - // by value. - FreeRegs = 0; - if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); - + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) + return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); return ABIArgInfo::getIndirect(0); - } - - // Treat an enum type as its underlying type. - if (const EnumType *EnumTy = Ty->getAs<EnumType>()) + } else if (const EnumType *EnumTy = Ty->getAs<EnumType>()) { + // Treat an enum type as its underlying type. Ty = EnumTy->getDecl()->getIntegerType(); + } else if (Ty->isFloatingType()) { + // Floating-point types don't go inreg. + return ABIArgInfo::getDirect(); + } - ABIArgInfo BaseInfo = (Ty->isPromotableIntegerType() ? + return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); - - // Regparm regs hold 32 bits. - unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32; - if (SizeInRegs == 0) return BaseInfo; - if (SizeInRegs > FreeRegs) { - FreeRegs = 0; - return BaseInfo; - } - FreeRegs -= SizeInRegs; - return BaseInfo.isDirect() ? - ABIArgInfo::getDirectInReg(BaseInfo.getCoerceToType()) : - ABIArgInfo::getExtendInReg(BaseInfo.getCoerceToType()); } ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const { if (RetTy->isVoidType()) return ABIArgInfo::getIgnore(); + // In the PNaCl ABI we always return records/structures on the stack. if (isAggregateTypeForABI(RetTy)) return ABIArgInfo::getIndirect(0); @@ -484,11 +486,9 @@ ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const { ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); } -/// UseX86_MMXType - Return true if this is an MMX type that should use the -/// special x86_mmx type. -bool UseX86_MMXType(llvm::Type *IRType) { - // If the type is an MMX type <2 x i32>, <4 x i16>, or <8 x i8>, use the - // special x86_mmx type. +/// IsX86_MMXType - Return true if this is an MMX type. +bool IsX86_MMXType(llvm::Type *IRType) { + // Return true if the type is an MMX type <2 x i32>, <4 x i16>, or <8 x i8>. return IRType->isVectorTy() && IRType->getPrimitiveSizeInBits() == 64 && cast<llvm::VectorType>(IRType)->getElementType()->isIntegerTy() && IRType->getScalarSizeInBits() != 64; @@ -517,8 +517,7 @@ class X86_32ABIInfo : public ABIInfo { bool IsDarwinVectorABI; bool IsSmallStructInRegABI; - bool IsMMXDisabled; - bool IsWin32FloatStructABI; + bool IsWin32StructABI; unsigned DefaultNumRegisterParameters; static bool isRegisterSize(unsigned Size) { @@ -550,26 +549,24 @@ public: virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const; - X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool m, bool w, + X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool w, unsigned r) : ABIInfo(CGT), IsDarwinVectorABI(d), IsSmallStructInRegABI(p), - IsMMXDisabled(m), IsWin32FloatStructABI(w), - DefaultNumRegisterParameters(r) {} + IsWin32StructABI(w), DefaultNumRegisterParameters(r) {} }; class X86_32TargetCodeGenInfo : public TargetCodeGenInfo { public: X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, - bool d, bool p, bool m, bool w, unsigned r) - :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, m, w, r)) {} + bool d, bool p, bool w, unsigned r) + :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, w, r)) {} void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const; int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const { // Darwin uses different dwarf register numbers for EH. - if (CGM.isTargetDarwin()) return 5; - + if (CGM.getTarget().getTriple().isOSDarwin()) return 5; return 4; } @@ -681,9 +678,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, if (isAggregateTypeForABI(RetTy)) { if (const RecordType *RT = RetTy->getAs<RecordType>()) { - // Structures with either a non-trivial destructor or a non-trivial - // copy constructor are always indirect. - if (hasNonTrivialDestructorOrCopyConstructor(RT)) + if (isRecordReturnIndirect(RT, CGT)) return ABIArgInfo::getIndirect(0, /*ByVal=*/false); // Structures with flexible arrays are always indirect. @@ -707,7 +702,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, // We apply a similar transformation for pointer types to improve the // quality of the generated IR. if (const Type *SeltTy = isSingleElementStruct(RetTy, getContext())) - if ((!IsWin32FloatStructABI && SeltTy->isRealFloatingType()) + if ((!IsWin32StructABI && SeltTy->isRealFloatingType()) || SeltTy->hasPointerRepresentation()) return ABIArgInfo::getDirect(CGT.ConvertType(QualType(SeltTy, 0))); @@ -864,13 +859,14 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, bool IsFastCall) const { // FIXME: Set alignment on indirect arguments. if (isAggregateTypeForABI(Ty)) { - // Structures with flexible arrays are always indirect. if (const RecordType *RT = Ty->getAs<RecordType>()) { - // Structures with either a non-trivial destructor or a non-trivial - // copy constructor are always indirect. - if (hasNonTrivialDestructorOrCopyConstructor(RT)) - return getIndirectResult(Ty, false, FreeRegs); + if (IsWin32StructABI) + return getIndirectResult(Ty, true, FreeRegs); + + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, CGT)) + return getIndirectResult(Ty, RAA == CGCXXABI::RAA_DirectInMemory, FreeRegs); + // Structures with flexible arrays are always indirect. if (RT->getDecl()->hasFlexibleArrayMember()) return getIndirectResult(Ty, true, FreeRegs); } @@ -914,15 +910,8 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, Size)); } - llvm::Type *IRType = CGT.ConvertType(Ty); - if (UseX86_MMXType(IRType)) { - if (IsMMXDisabled) - return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), - 64)); - ABIArgInfo AAI = ABIArgInfo::getDirect(IRType); - AAI.setCoerceToType(llvm::Type::getX86_MMXTy(getVMContext())); - return AAI; - } + if (IsX86_MMXType(CGT.ConvertType(Ty))) + return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), 64)); return ABIArgInfo::getDirect(); } @@ -1044,7 +1033,7 @@ bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable( // 8 is %eip. AssignToArrayRange(Builder, Address, Four8, 0, 8); - if (CGF.CGM.isTargetDarwin()) { + if (CGF.CGM.getTarget().getTriple().isOSDarwin()) { // 12-16 are st(0..4). Not sure why we stop at 4. // These have size 16, which is sizeof(long double) on // platforms with 8-byte alignment for that type. @@ -1169,7 +1158,7 @@ class X86_64ABIInfo : public ABIInfo { /// required strict binary compatibility with older versions of GCC /// may need to exempt themselves. bool honorsRevision0_98() const { - return !getContext().getTargetInfo().getTriple().isOSDarwin(); + return !getTarget().getTriple().isOSDarwin(); } bool HasAVX; @@ -1204,7 +1193,7 @@ public: /// WinX86_64ABIInfo - The Windows X86_64 ABI information. class WinX86_64ABIInfo : public ABIInfo { - ABIArgInfo classify(QualType Ty) const; + ABIArgInfo classify(QualType Ty, bool IsReturnType) const; public: WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {} @@ -1393,8 +1382,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Current = Integer; } else if ((k == BuiltinType::Float || k == BuiltinType::Double) || (k == BuiltinType::LongDouble && - getContext().getTargetInfo().getTriple().getOS() == - llvm::Triple::NaCl)) { + getTarget().getTriple().getOS() == llvm::Triple::NaCl)) { Current = SSE; } else if (k == BuiltinType::LongDouble) { Lo = X87; @@ -1482,8 +1470,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Current = SSE; else if (ET == getContext().DoubleTy || (ET == getContext().LongDoubleTy && - getContext().getTargetInfo().getTriple().getOS() == - llvm::Triple::NaCl)) + getTarget().getTriple().getOS() == llvm::Triple::NaCl)) Lo = Hi = SSE; else if (ET == getContext().LongDoubleTy) Current = ComplexX87; @@ -1552,7 +1539,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, // AMD64-ABI 3.2.3p2: Rule 2. If a C++ object has either a non-trivial // copy constructor or a non-trivial destructor, it is passed by invisible // reference. - if (hasNonTrivialDestructorOrCopyConstructor(RT)) + if (getRecordArgABI(RT, CGT)) return; const RecordDecl *RD = RT->getDecl(); @@ -1702,8 +1689,8 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty, ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); } - if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) + return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); // Compute the byval alignment. We specify the alignment of the byval in all // cases so that the mid-level optimizer knows the alignment of the byval. @@ -2191,7 +2178,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType( // COMPLEX_X87, it is passed in memory. case X87: case ComplexX87: - if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) + if (getRecordArgABI(Ty, CGT) == CGCXXABI::RAA_Indirect) ++neededInt; return getIndirectResult(Ty, freeIntRegs); @@ -2522,7 +2509,7 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, return ResAddr; } -ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty) const { +ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, bool IsReturnType) const { if (Ty->isVoidType()) return ABIArgInfo::getIgnore(); @@ -2533,14 +2520,19 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty) const { uint64_t Size = getContext().getTypeSize(Ty); if (const RecordType *RT = Ty->getAs<RecordType>()) { - if (hasNonTrivialDestructorOrCopyConstructor(RT) || - RT->getDecl()->hasFlexibleArrayMember()) + if (IsReturnType) { + if (isRecordReturnIndirect(RT, CGT)) + return ABIArgInfo::getIndirect(0, false); + } else { + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, CGT)) + return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); + } + + if (RT->getDecl()->hasFlexibleArrayMember()) return ABIArgInfo::getIndirect(0, /*ByVal=*/false); // FIXME: mingw-w64-gcc emits 128-bit struct as i128 - if (Size == 128 && - getContext().getTargetInfo().getTriple().getOS() - == llvm::Triple::MinGW32) + if (Size == 128 && getTarget().getTriple().getOS() == llvm::Triple::MinGW32) return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size)); @@ -2563,11 +2555,11 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty) const { void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { QualType RetTy = FI.getReturnType(); - FI.getReturnInfo() = classify(RetTy); + 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); + it->info = classify(it->type, false); } llvm::Value *WinX86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, @@ -2794,10 +2786,8 @@ PPC64_SVR4_ABIInfo::classifyArgumentType(QualType Ty) const { return ABIArgInfo::getDirect(); if (isAggregateTypeForABI(Ty)) { - // Records with non trivial destructors/constructors should not be passed - // by value. - if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) + return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); return ABIArgInfo::getIndirect(0); } @@ -2970,8 +2960,7 @@ public: } bool isEABI() const { - StringRef Env = - getContext().getTargetInfo().getTriple().getEnvironmentName(); + StringRef Env = getTarget().getTriple().getEnvironmentName(); return (Env == "gnueabi" || Env == "eabi" || Env == "android" || Env == "androideabi"); } @@ -3070,7 +3059,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 (getContext().getTargetInfo().getTriple().getEnvironmentName()=="gnueabihf") + if (getTarget().getTriple().getEnvironmentName()=="gnueabihf") return llvm::CallingConv::ARM_AAPCS_VFP; else if (isEABI()) return llvm::CallingConv::ARM_AAPCS; @@ -3262,10 +3251,8 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, int *VFPRegs, if (isEmptyRecord(getContext(), Ty, true)) return ABIArgInfo::getIgnore(); - // Structures with either a non-trivial destructor or a non-trivial - // copy constructor are always indirect. - if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) + return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); if (getABIKind() == ARMABIInfo::AAPCS_VFP) { // Homogeneous Aggregates need to be expanded when we can fit the aggregate @@ -3428,7 +3415,7 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const { // Structures with either a non-trivial destructor or a non-trivial // copy constructor are always indirect. - if (isRecordWithNonTrivialDestructorOrCopyConstructor(RetTy)) + if (isRecordReturnIndirect(RetTy, CGT)) return ABIArgInfo::getIndirect(0, /*ByVal=*/false); // Are we following APCS? @@ -3752,12 +3739,10 @@ ABIArgInfo AArch64ABIInfo::classifyGenericType(QualType Ty, return tryUseRegs(Ty, FreeIntRegs, RegsNeeded, /*IsInt=*/ true); } - // Structures with either a non-trivial destructor or a non-trivial - // copy constructor are always indirect. - if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) { - if (FreeIntRegs > 0) + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) { + if (FreeIntRegs > 0 && RAA == CGCXXABI::RAA_Indirect) --FreeIntRegs; - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); } if (isEmptyRecord(getContext(), Ty, true)) { @@ -4032,7 +4017,7 @@ namespace { class NVPTXABIInfo : public ABIInfo { public: - NVPTXABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) { setRuntimeCC(); } + NVPTXABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {} ABIArgInfo classifyReturnType(QualType RetTy) const; ABIArgInfo classifyArgumentType(QualType Ty) const; @@ -4040,8 +4025,6 @@ public: virtual void computeInfo(CGFunctionInfo &FI) const; virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CFG) const; -private: - void setRuntimeCC(); }; class NVPTXTargetCodeGenInfo : public TargetCodeGenInfo { @@ -4051,6 +4034,8 @@ public: virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const; +private: + static void addKernelMetadata(llvm::Function *F); }; ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const { @@ -4081,25 +4066,6 @@ void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const { FI.setEffectiveCallingConvention(getRuntimeCC()); } -void NVPTXABIInfo::setRuntimeCC() { - // Calling convention as default by an ABI. - // We're still using the PTX_Kernel/PTX_Device calling conventions here, - // but we should switch to NVVM metadata later on. - const LangOptions &LangOpts = getContext().getLangOpts(); - if (LangOpts.OpenCL || LangOpts.CUDA) { - // If we are in OpenCL or CUDA mode, then default to device functions - RuntimeCC = llvm::CallingConv::PTX_Device; - } else { - // If we are in standard C/C++ mode, use the triple to decide on the default - StringRef Env = - getContext().getTargetInfo().getTriple().getEnvironmentName(); - if (Env == "device") - RuntimeCC = llvm::CallingConv::PTX_Device; - else - RuntimeCC = llvm::CallingConv::PTX_Kernel; - } -} - llvm::Value *NVPTXABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CFG) const { llvm_unreachable("NVPTX does not support varargs"); @@ -4115,11 +4081,11 @@ SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, // Perform special handling in OpenCL mode if (M.getLangOpts().OpenCL) { - // Use OpenCL function attributes to set proper calling conventions + // Use OpenCL function attributes to check for kernel functions // By default, all functions are device functions if (FD->hasAttr<OpenCLKernelAttr>()) { - // OpenCL __kernel functions get a kernel calling convention - F->setCallingConv(llvm::CallingConv::PTX_Kernel); + // OpenCL __kernel functions get kernel metadata + addKernelMetadata(F); // And kernel functions are not subject to inlining F->addFnAttr(llvm::Attribute::NoInline); } @@ -4127,14 +4093,318 @@ SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, // Perform special handling in CUDA mode. if (M.getLangOpts().CUDA) { - // CUDA __global__ functions get a kernel calling convention. Since + // 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>()) - F->setCallingConv(llvm::CallingConv::PTX_Kernel); + addKernelMetadata(F); } } +void NVPTXTargetCodeGenInfo::addKernelMetadata(llvm::Function *F) { + 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)); + + // Append metadata to nvvm.annotations + MD->addOperand(llvm::MDNode::get(Ctx, MDVals)); +} + +} + +//===----------------------------------------------------------------------===// +// SystemZ ABI Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class SystemZABIInfo : public ABIInfo { +public: + SystemZABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {} + + bool isPromotableIntegerType(QualType Ty) const; + bool isCompoundType(QualType Ty) const; + bool isFPArgumentType(QualType Ty) const; + + 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); + } + + virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const; +}; + +class SystemZTargetCodeGenInfo : public TargetCodeGenInfo { +public: + SystemZTargetCodeGenInfo(CodeGenTypes &CGT) + : TargetCodeGenInfo(new SystemZABIInfo(CGT)) {} +}; + +} + +bool SystemZABIInfo::isPromotableIntegerType(QualType Ty) const { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs<EnumType>()) + Ty = EnumTy->getDecl()->getIntegerType(); + + // Promotable integer types are required to be promoted by the ABI. + if (Ty->isPromotableIntegerType()) + return true; + + // 32-bit values must also be promoted. + if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) + switch (BT->getKind()) { + case BuiltinType::Int: + case BuiltinType::UInt: + return true; + default: + return false; + } + return false; +} + +bool SystemZABIInfo::isCompoundType(QualType Ty) const { + return Ty->isAnyComplexType() || isAggregateTypeForABI(Ty); +} + +bool SystemZABIInfo::isFPArgumentType(QualType Ty) const { + if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) + switch (BT->getKind()) { + case BuiltinType::Float: + case BuiltinType::Double: + return true; + default: + return false; + } + + if (const RecordType *RT = Ty->getAsStructureType()) { + const RecordDecl *RD = RT->getDecl(); + bool Found = false; + + // 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(); + + // Empty bases don't affect things either way. + if (isEmptyRecord(getContext(), Base, true)) + continue; + + if (Found) + return false; + Found = isFPArgumentType(Base); + if (!Found) + return false; + } + + // Check the fields. + for (RecordDecl::field_iterator I = RD->field_begin(), + E = RD->field_end(); I != E; ++I) { + const FieldDecl *FD = *I; + + // 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. + if (FD->isBitField() && FD->getBitWidthValue(getContext()) == 0) + return true; + + // Unlike isSingleElementStruct(), arrays do not count. + // Nested isFPArgumentType structures still do though. + if (Found) + return false; + Found = isFPArgumentType(FD->getType()); + if (!Found) + return false; + } + + // Unlike isSingleElementStruct(), trailing padding is allowed. + // An 8-byte aligned struct s { float f; } is passed as a double. + return Found; + } + + return false; +} + +llvm::Value *SystemZABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const { + // Assume that va_list type is correct; should be pointer to LLVM type: + // struct { + // i64 __gpr; + // i64 __fpr; + // i8 *__overflow_arg_area; + // i8 *__reg_save_area; + // }; + + // Every argument occupies 8 bytes and is passed by preference in either + // GPRs or FPRs. + Ty = CGF.getContext().getCanonicalType(Ty); + ABIArgInfo AI = classifyArgumentType(Ty); + bool InFPRs = isFPArgumentType(Ty); + + llvm::Type *APTy = llvm::PointerType::getUnqual(CGF.ConvertTypeForMem(Ty)); + bool IsIndirect = AI.isIndirect(); + unsigned UnpaddedBitSize; + if (IsIndirect) { + APTy = llvm::PointerType::getUnqual(APTy); + UnpaddedBitSize = 64; + } else + UnpaddedBitSize = getContext().getTypeSize(Ty); + unsigned PaddedBitSize = 64; + assert((UnpaddedBitSize <= PaddedBitSize) && "Invalid argument size."); + + unsigned PaddedSize = PaddedBitSize / 8; + unsigned Padding = (PaddedBitSize - UnpaddedBitSize) / 8; + + unsigned MaxRegs, RegCountField, RegSaveIndex, RegPadding; + if (InFPRs) { + MaxRegs = 4; // Maximum of 4 FPR arguments + RegCountField = 1; // __fpr + RegSaveIndex = 16; // save offset for f0 + RegPadding = 0; // floats are passed in the high bits of an FPR + } else { + MaxRegs = 5; // Maximum of 5 GPR arguments + RegCountField = 0; // __gpr + RegSaveIndex = 2; // save offset for r2 + RegPadding = Padding; // values are passed in the low bits of a GPR + } + + llvm::Value *RegCountPtr = + CGF.Builder.CreateStructGEP(VAListAddr, RegCountField, "reg_count_ptr"); + llvm::Value *RegCount = CGF.Builder.CreateLoad(RegCountPtr, "reg_count"); + llvm::Type *IndexTy = RegCount->getType(); + llvm::Value *MaxRegsV = llvm::ConstantInt::get(IndexTy, MaxRegs); + llvm::Value *InRegs = CGF.Builder.CreateICmpULT(RegCount, MaxRegsV, + "fits_in_regs"); + + llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg"); + llvm::BasicBlock *InMemBlock = CGF.createBasicBlock("vaarg.in_mem"); + llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end"); + CGF.Builder.CreateCondBr(InRegs, InRegBlock, InMemBlock); + + // Emit code to load the value if it was passed in registers. + CGF.EmitBlock(InRegBlock); + + // Work out the address of an argument register. + llvm::Value *PaddedSizeV = llvm::ConstantInt::get(IndexTy, PaddedSize); + llvm::Value *ScaledRegCount = + CGF.Builder.CreateMul(RegCount, PaddedSizeV, "scaled_reg_count"); + llvm::Value *RegBase = + llvm::ConstantInt::get(IndexTy, RegSaveIndex * PaddedSize + RegPadding); + llvm::Value *RegOffset = + CGF.Builder.CreateAdd(ScaledRegCount, RegBase, "reg_offset"); + llvm::Value *RegSaveAreaPtr = + CGF.Builder.CreateStructGEP(VAListAddr, 3, "reg_save_area_ptr"); + llvm::Value *RegSaveArea = + CGF.Builder.CreateLoad(RegSaveAreaPtr, "reg_save_area"); + llvm::Value *RawRegAddr = + CGF.Builder.CreateGEP(RegSaveArea, RegOffset, "raw_reg_addr"); + llvm::Value *RegAddr = + CGF.Builder.CreateBitCast(RawRegAddr, APTy, "reg_addr"); + + // Update the register count + llvm::Value *One = llvm::ConstantInt::get(IndexTy, 1); + llvm::Value *NewRegCount = + CGF.Builder.CreateAdd(RegCount, One, "reg_count"); + CGF.Builder.CreateStore(NewRegCount, RegCountPtr); + CGF.EmitBranch(ContBlock); + + // Emit code to load the value if it was passed in memory. + CGF.EmitBlock(InMemBlock); + + // Work out the address of a stack argument. + llvm::Value *OverflowArgAreaPtr = + CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr"); + llvm::Value *OverflowArgArea = + CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area"); + llvm::Value *PaddingV = llvm::ConstantInt::get(IndexTy, Padding); + llvm::Value *RawMemAddr = + CGF.Builder.CreateGEP(OverflowArgArea, PaddingV, "raw_mem_addr"); + llvm::Value *MemAddr = + CGF.Builder.CreateBitCast(RawMemAddr, APTy, "mem_addr"); + + // Update overflow_arg_area_ptr pointer + llvm::Value *NewOverflowArgArea = + CGF.Builder.CreateGEP(OverflowArgArea, PaddedSizeV, "overflow_arg_area"); + CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr); + CGF.EmitBranch(ContBlock); + + // Return the appropriate result. + CGF.EmitBlock(ContBlock); + llvm::PHINode *ResAddr = CGF.Builder.CreatePHI(APTy, 2, "va_arg.addr"); + ResAddr->addIncoming(RegAddr, InRegBlock); + ResAddr->addIncoming(MemAddr, InMemBlock); + + if (IsIndirect) + return CGF.Builder.CreateLoad(ResAddr, "indirect_arg"); + + return ResAddr; +} + + +ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const { + if (RetTy->isVoidType()) + return ABIArgInfo::getIgnore(); + if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64) + return ABIArgInfo::getIndirect(0); + return (isPromotableIntegerType(RetTy) ? + ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); +} + +ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const { + // Handle the generic C++ ABI. + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) + return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); + + // Integers and enums are extended to full register width. + if (isPromotableIntegerType(Ty)) + return ABIArgInfo::getExtend(); + + // Values that are not 1, 2, 4 or 8 bytes in size are passed indirectly. + uint64_t Size = getContext().getTypeSize(Ty); + if (Size != 8 && Size != 16 && Size != 32 && Size != 64) + return ABIArgInfo::getIndirect(0); + + // Handle small structures. + if (const RecordType *RT = Ty->getAs<RecordType>()) { + // Structures with flexible arrays have variable length, so really + // fail the size test above. + const RecordDecl *RD = RT->getDecl(); + if (RD->hasFlexibleArrayMember()) + return ABIArgInfo::getIndirect(0); + + // The structure is passed as an unextended integer, a float, or a double. + llvm::Type *PassTy; + if (isFPArgumentType(Ty)) { + assert(Size == 32 || Size == 64); + if (Size == 32) + PassTy = llvm::Type::getFloatTy(getVMContext()); + else + PassTy = llvm::Type::getDoubleTy(getVMContext()); + } else + PassTy = llvm::IntegerType::get(getVMContext(), Size); + return ABIArgInfo::getDirect(PassTy); + } + + // Non-structure compounds are passed indirectly. + if (isCompoundType(Ty)) + return ABIArgInfo::getIndirect(0); + + return ABIArgInfo::getDirect(0); } //===----------------------------------------------------------------------===// @@ -4325,11 +4595,17 @@ public: void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const { - // - // can fill this in when new attribute work in llvm is done. - // attributes mips16 and nomips16 need to be handled here. - // + const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); + if (!FD) return; + llvm::Function *Fn = cast<llvm::Function>(GV); + if (FD->hasAttr<Mips16Attr>()) { + Fn->addFnAttr("mips16"); + } + else if (FD->hasAttr<NoMips16Attr>()) { + Fn->addFnAttr("nomips16"); + } } + bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const; @@ -4438,11 +4714,9 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const { if (TySize == 0) return ABIArgInfo::getIgnore(); - // Records with non trivial destructors/constructors should not be passed - // by value. - if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) { + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) { Offset = OrigOffset + MinABIStackAlignInBytes; - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); } // If we have reached here, aggregates are passed directly by coercing to @@ -4512,6 +4786,9 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const { return ABIArgInfo::getIgnore(); if (isAggregateTypeForABI(RetTy) || RetTy->isVectorType()) { + if (isRecordReturnIndirect(RetTy, CGT)) + return ABIArgInfo::getIndirect(0); + if (Size <= 128) { if (RetTy->isAnyComplexType()) return ABIArgInfo::getDirect(); @@ -4520,7 +4797,7 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const { if (IsO32 && RetTy->isVectorType() && !RetTy->hasFloatingRepresentation()) return ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size)); - if (!IsO32 && !isRecordWithNonTrivialDestructorOrCopyConstructor(RetTy)) + if (!IsO32) return ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size)); } @@ -4558,7 +4835,7 @@ llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, int64_t TypeAlign = getContext().getTypeAlign(Ty) / 8; llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); llvm::Value *AddrTyped; - unsigned PtrWidth = getContext().getTargetInfo().getPointerWidth(0); + unsigned PtrWidth = getTarget().getPointerWidth(0); llvm::IntegerType *IntTy = (PtrWidth == 32) ? CGF.Int32Ty : CGF.Int64Ty; if (TypeAlign > MinABIStackAlignInBytes) { @@ -4730,10 +5007,8 @@ ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty) const { if (isEmptyRecord(getContext(), Ty, true)) return ABIArgInfo::getIgnore(); - // Structures with either a non-trivial destructor or a non-trivial - // copy constructor are always indirect. - if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) - return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, CGT)) + return ABIArgInfo::getIndirect(0, RAA == CGCXXABI::RAA_DirectInMemory); uint64_t Size = getContext().getTypeSize(Ty); if (Size > 64) @@ -4768,7 +5043,7 @@ ABIArgInfo HexagonABIInfo::classifyReturnType(QualType RetTy) const { // Structures with either a non-trivial destructor or a non-trivial // copy constructor are always indirect. - if (isRecordWithNonTrivialDestructorOrCopyConstructor(RetTy)) + if (isRecordReturnIndirect(RetTy, CGT)) return ABIArgInfo::getIndirect(0, /*ByVal=*/false); if (isEmptyRecord(getContext(), RetTy, true)) @@ -4819,7 +5094,7 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { if (TheTargetCodeGenInfo) return *TheTargetCodeGenInfo; - const llvm::Triple &Triple = getContext().getTargetInfo().getTriple(); + const llvm::Triple &Triple = getTarget().getTriple(); switch (Triple.getArch()) { default: return *(TheTargetCodeGenInfo = new DefaultTargetCodeGenInfo(Types)); @@ -4841,10 +5116,11 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::thumb: { ARMABIInfo::ABIKind Kind = ARMABIInfo::AAPCS; - if (strcmp(getContext().getTargetInfo().getABI(), "apcs-gnu") == 0) + if (strcmp(getTarget().getABI(), "apcs-gnu") == 0) Kind = ARMABIInfo::APCS; else if (CodeGenOpts.FloatABI == "hard" || - (CodeGenOpts.FloatABI != "soft" && Triple.getEnvironment()==llvm::Triple::GNUEABIHF)) + (CodeGenOpts.FloatABI != "soft" && + Triple.getEnvironment() == llvm::Triple::GNUEABIHF)) Kind = ARMABIInfo::AAPCS_VFP; switch (Triple.getOS()) { @@ -4875,15 +5151,16 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::msp430: return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo(Types)); + case llvm::Triple::systemz: + return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo(Types)); + case llvm::Triple::tce: return *(TheTargetCodeGenInfo = new TCETargetCodeGenInfo(Types)); case llvm::Triple::x86: { - bool DisableMMX = strcmp(getContext().getTargetInfo().getABI(), "no-mmx") == 0; - if (Triple.isOSDarwin()) return *(TheTargetCodeGenInfo = - new X86_32TargetCodeGenInfo(Types, true, true, DisableMMX, false, + new X86_32TargetCodeGenInfo(Types, true, true, false, CodeGenOpts.NumRegisterParameters)); switch (Triple.getOS()) { @@ -4895,25 +5172,23 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::OpenBSD: case llvm::Triple::Bitrig: return *(TheTargetCodeGenInfo = - new X86_32TargetCodeGenInfo(Types, false, true, DisableMMX, - false, + new X86_32TargetCodeGenInfo(Types, false, true, false, CodeGenOpts.NumRegisterParameters)); case llvm::Triple::Win32: return *(TheTargetCodeGenInfo = - new X86_32TargetCodeGenInfo(Types, false, true, DisableMMX, true, + new X86_32TargetCodeGenInfo(Types, false, true, true, CodeGenOpts.NumRegisterParameters)); default: return *(TheTargetCodeGenInfo = - new X86_32TargetCodeGenInfo(Types, false, false, DisableMMX, - false, + new X86_32TargetCodeGenInfo(Types, false, false, false, CodeGenOpts.NumRegisterParameters)); } } case llvm::Triple::x86_64: { - bool HasAVX = strcmp(getContext().getTargetInfo().getABI(), "avx") == 0; + bool HasAVX = strcmp(getTarget().getABI(), "avx") == 0; switch (Triple.getOS()) { case llvm::Triple::Win32: @@ -4921,7 +5196,8 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::Cygwin: return *(TheTargetCodeGenInfo = new WinX86_64TargetCodeGenInfo(Types)); case llvm::Triple::NaCl: - return *(TheTargetCodeGenInfo = new NaClX86_64TargetCodeGenInfo(Types, HasAVX)); + return *(TheTargetCodeGenInfo = new NaClX86_64TargetCodeGenInfo(Types, + HasAVX)); default: return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo(Types, HasAVX)); |