diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp | 882 |
1 files changed, 605 insertions, 277 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp index e1dc8f7..3ed1778 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp @@ -98,7 +98,8 @@ unsigned TargetCodeGenInfo::getSizeOfUnwindException() const { return 32; } -bool TargetCodeGenInfo::isNoProtoCallVariadic(CallingConv CC) const { +bool TargetCodeGenInfo::isNoProtoCallVariadic(const CallArgList &args, + const FunctionNoProtoType *fnType) const { // The following conventions are known to require this to be false: // x86_stdcall // MIPS @@ -117,10 +118,14 @@ static bool isEmptyField(ASTContext &Context, const FieldDecl *FD, QualType FT = FD->getType(); - // Constant arrays of empty records count as empty, strip them off. + // Constant arrays of empty records count as empty, strip them off. + // Constant arrays of zero length always count as empty. if (AllowArrays) - while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) + while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) { + if (AT->getSize() == 0) + return true; FT = AT->getElementType(); + } const RecordType *RT = FT->getAs<RecordType>(); if (!RT) @@ -252,6 +257,11 @@ static const Type *isSingleElementStruct(QualType T, ASTContext &Context) { } } + // 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 Found; } @@ -287,6 +297,8 @@ static bool canExpandIndirectArgument(QualType Ty, ASTContext &Context) { if (!RD->isStruct() || isa<CXXRecordDecl>(RD)) return false; + uint64_t Size = 0; + for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); i != e; ++i) { const FieldDecl *FD = *i; @@ -299,8 +311,14 @@ static bool canExpandIndirectArgument(QualType Ty, ASTContext &Context) { // counts as "basic" is more complicated than what we were doing previously. if (FD->isBitField()) return false; + + Size += Context.getTypeSize(FD->getType()); } + // Make sure there are not any holes in the struct. + if (Size != Context.getTypeSize(Ty)) + return false; + return true; } @@ -339,8 +357,14 @@ llvm::Value *DefaultABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, } ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const { - if (isAggregateTypeForABI(Ty)) + if (isAggregateTypeForABI(Ty)) { + // Records with non trivial destructors/constructors should not be passed + // by value. + if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) + return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + return ABIArgInfo::getIndirect(0); + } // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs<EnumType>()) @@ -365,8 +389,8 @@ ABIArgInfo DefaultABIInfo::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. +/// 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. @@ -394,12 +418,14 @@ class X86_32ABIInfo : public ABIInfo { bool IsDarwinVectorABI; bool IsSmallStructInRegABI; bool IsMMXDisabled; + bool IsWin32FloatStructABI; static bool isRegisterSize(unsigned Size) { return (Size == 8 || Size == 16 || Size == 32 || Size == 64); } - static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context); + static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context, + unsigned callingConvention); /// getIndirectResult - Give a source type \arg Ty, return a suitable result /// such that the argument will be passed in memory. @@ -410,11 +436,13 @@ class X86_32ABIInfo : public ABIInfo { public: - ABIArgInfo classifyReturnType(QualType RetTy) const; + ABIArgInfo classifyReturnType(QualType RetTy, + unsigned callingConvention) const; ABIArgInfo classifyArgumentType(QualType RetTy) const; virtual void computeInfo(CGFunctionInfo &FI) const { - FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), + FI.getCallingConvention()); for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); it != ie; ++it) it->info = classifyArgumentType(it->type); @@ -423,15 +451,16 @@ public: virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const; - X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool m) + X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool m, bool w) : ABIInfo(CGT), IsDarwinVectorABI(d), IsSmallStructInRegABI(p), - IsMMXDisabled(m) {} + IsMMXDisabled(m), IsWin32FloatStructABI(w) {} }; class X86_32TargetCodeGenInfo : public TargetCodeGenInfo { public: - X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool m) - :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, m)) {} + X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, + bool d, bool p, bool m, bool w) + :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, m, w)) {} void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const; @@ -459,7 +488,8 @@ 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) { + ASTContext &Context, + unsigned callingConvention) { uint64_t Size = Context.getTypeSize(Ty); // Type must be register sized. @@ -484,7 +514,8 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty, // Arrays are treated like records. if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) - return shouldReturnTypeInRegister(AT->getElementType(), Context); + return shouldReturnTypeInRegister(AT->getElementType(), Context, + callingConvention); // Otherwise, it must be a record type. const RecordType *RT = Ty->getAs<RecordType>(); @@ -492,6 +523,13 @@ 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(), @@ -503,14 +541,15 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty, continue; // Check fields recursively. - if (!shouldReturnTypeInRegister(FD->getType(), Context)) + if (!shouldReturnTypeInRegister(FD->getType(), Context, + callingConvention)) return false; } - return true; } -ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy) const { +ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, + unsigned callingConvention) const { if (RetTy->isVoidType()) return ABIArgInfo::getIgnore(); @@ -555,51 +594,24 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy) const { if (!IsSmallStructInRegABI && !RetTy->isAnyComplexType()) return ABIArgInfo::getIndirect(0); - // Classify "single element" structs as their element type. - if (const Type *SeltTy = isSingleElementStruct(RetTy, getContext())) { - if (const BuiltinType *BT = SeltTy->getAs<BuiltinType>()) { - if (BT->isIntegerType()) { - // We need to use the size of the structure, padding - // bit-fields can adjust that to be larger than the single - // element type. - uint64_t Size = getContext().getTypeSize(RetTy); - return ABIArgInfo::getDirect( - llvm::IntegerType::get(getVMContext(), (unsigned)Size)); - } - - if (BT->getKind() == BuiltinType::Float) { - assert(getContext().getTypeSize(RetTy) == - getContext().getTypeSize(SeltTy) && - "Unexpect single element structure size!"); - return ABIArgInfo::getDirect(llvm::Type::getFloatTy(getVMContext())); - } - - if (BT->getKind() == BuiltinType::Double) { - assert(getContext().getTypeSize(RetTy) == - getContext().getTypeSize(SeltTy) && - "Unexpect single element structure size!"); - return ABIArgInfo::getDirect(llvm::Type::getDoubleTy(getVMContext())); - } - } else if (SeltTy->isPointerType()) { - // FIXME: It would be really nice if this could come out as the proper - // pointer type. - llvm::Type *PtrTy = llvm::Type::getInt8PtrTy(getVMContext()); - return ABIArgInfo::getDirect(PtrTy); - } else if (SeltTy->isVectorType()) { - // 64- and 128-bit vectors are never returned in a - // register when inside a structure. - uint64_t Size = getContext().getTypeSize(RetTy); - if (Size == 64 || Size == 128) - return ABIArgInfo::getIndirect(0); - - return classifyReturnType(QualType(SeltTy, 0)); - } - } - // Small structures which are register sized are generally returned // in a register. - if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext())) { + if (X86_32ABIInfo::shouldReturnTypeInRegister(RetTy, getContext(), + callingConvention)) { uint64_t Size = getContext().getTypeSize(RetTy); + + // As a special-case, if the struct is a "single-element" struct, and + // the field is of type "float" or "double", return it in a + // floating-point register. (MSVC does not apply this special case.) + // 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()) + || SeltTy->hasPointerRepresentation()) + return ABIArgInfo::getDirect(CGT.ConvertType(QualType(SeltTy, 0))); + + // FIXME: We should be able to narrow this integer in cases with dead + // padding. return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),Size)); } @@ -631,7 +643,7 @@ static bool isRecordWithSSEVectorType(ASTContext &Context, QualType Ty) { i != e; ++i) { QualType FT = i->getType(); - if (FT->getAs<VectorType>() && Context.getTypeSize(Ty) == 128) + if (FT->getAs<VectorType>() && Context.getTypeSize(FT) == 128) return true; if (isRecordWithSSEVectorType(Context, FT)) @@ -655,7 +667,7 @@ unsigned X86_32ABIInfo::getTypeStackAlignInBytes(QualType Ty, } // Otherwise, if the type contains an SSE vector type, the alignment is 16. - if (isRecordWithSSEVectorType(getContext(), Ty)) + if (Align >= 16 && isRecordWithSSEVectorType(getContext(), Ty)) return 16; return MinABIStackAlignInBytes; @@ -694,8 +706,8 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty) const { return getIndirectResult(Ty); } - // Ignore empty structs. - if (Ty->isStructureType() && getContext().getTypeSize(Ty) == 0) + // Ignore empty structs/unions. + if (isEmptyRecord(getContext(), Ty, true)) return ABIArgInfo::getIgnore(); // Expand small (<= 128-bit) record types when we know that the stack layout @@ -743,19 +755,36 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty) const { llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const { - llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); - llvm::Type *BPP = llvm::PointerType::getUnqual(BP); + llvm::Type *BPP = CGF.Int8PtrPtrTy; CGBuilderTy &Builder = CGF.Builder; llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap"); llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); + + // Compute if the address needs to be aligned + unsigned Align = CGF.getContext().getTypeAlignInChars(Ty).getQuantity(); + Align = getTypeStackAlignInBytes(Ty, Align); + Align = std::max(Align, 4U); + if (Align > 4) { + // addr = (addr + align - 1) & -align; + llvm::Value *Offset = + llvm::ConstantInt::get(CGF.Int32Ty, Align - 1); + Addr = CGF.Builder.CreateGEP(Addr, Offset); + llvm::Value *AsInt = CGF.Builder.CreatePtrToInt(Addr, + CGF.Int32Ty); + llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty, -Align); + Addr = CGF.Builder.CreateIntToPtr(CGF.Builder.CreateAnd(AsInt, Mask), + Addr->getType(), + "ap.cur.aligned"); + } + llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy); uint64_t Offset = - llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, 4); + llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, Align); llvm::Value *NextAddr = Builder.CreateGEP(Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset), "ap.next"); @@ -782,10 +811,8 @@ bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable( CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const { CodeGen::CGBuilderTy &Builder = CGF.Builder; - llvm::LLVMContext &Context = CGF.getLLVMContext(); - llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); - llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4); + llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4); // 0-7 are the eight integer registers; the order is different // on Darwin (for EH), but the range is the same. @@ -796,7 +823,7 @@ bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable( // 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. - llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16); + llvm::Value *Sixteen8 = llvm::ConstantInt::get(CGF.Int8Ty, 16); AssignToArrayRange(Builder, Address, Sixteen8, 12, 16); } else { @@ -807,7 +834,7 @@ bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable( // 11-16 are st(0..5). Not sure why we stop at 5. // These have size 12, which is sizeof(long double) on // platforms with 4-byte alignment for that type. - llvm::Value *Twelve8 = llvm::ConstantInt::get(i8, 12); + llvm::Value *Twelve8 = llvm::ConstantInt::get(CGF.Int8Ty, 12); AssignToArrayRange(Builder, Address, Twelve8, 11, 16); } @@ -897,14 +924,20 @@ class X86_64ABIInfo : public ABIInfo { /// getIndirectResult - Give a source type \arg Ty, return a suitable result /// such that the argument will be passed in memory. - ABIArgInfo getIndirectResult(QualType Ty) const; + /// + /// \param freeIntRegs - The number of free integer registers remaining + /// available. + ABIArgInfo getIndirectResult(QualType Ty, unsigned freeIntRegs) const; ABIArgInfo classifyReturnType(QualType RetTy) const; ABIArgInfo classifyArgumentType(QualType Ty, + unsigned freeIntRegs, unsigned &neededInt, unsigned &neededSSE) const; + bool IsIllegalVectorType(QualType Ty) const; + /// The 0.98 ABI revision clarified a lot of ambiguities, /// unfortunately in ways that were not always consistent with /// certain previous compilers. In particular, platforms which @@ -914,8 +947,23 @@ class X86_64ABIInfo : public ABIInfo { return !getContext().getTargetInfo().getTriple().isOSDarwin(); } + bool HasAVX; + public: - X86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {} + X86_64ABIInfo(CodeGen::CodeGenTypes &CGT, bool hasavx) : + ABIInfo(CGT), HasAVX(hasavx) {} + + bool isPassedUsingAVXType(QualType type) const { + unsigned neededInt, neededSSE; + // The freeIntRegs argument doesn't matter here. + ABIArgInfo info = classifyArgumentType(type, 0, neededInt, neededSSE); + if (info.isDirect()) { + llvm::Type *ty = info.getCoerceToType(); + if (llvm::VectorType *vectorTy = dyn_cast_or_null<llvm::VectorType>(ty)) + return (vectorTy->getBitWidth() > 128); + } + return false; + } virtual void computeInfo(CGFunctionInfo &FI) const; @@ -939,8 +987,12 @@ public: class X86_64TargetCodeGenInfo : public TargetCodeGenInfo { public: - X86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT) - : TargetCodeGenInfo(new X86_64ABIInfo(CGT)) {} + X86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool HasAVX) + : TargetCodeGenInfo(new X86_64ABIInfo(CGT, HasAVX)) {} + + const X86_64ABIInfo &getABIInfo() const { + return static_cast<const X86_64ABIInfo&>(TargetCodeGenInfo::getABIInfo()); + } int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const { return 7; @@ -948,16 +1000,11 @@ public: bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const { - CodeGen::CGBuilderTy &Builder = CGF.Builder; - llvm::LLVMContext &Context = CGF.getLLVMContext(); - - llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); - llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8); + llvm::Value *Eight8 = llvm::ConstantInt::get(CGF.Int8Ty, 8); // 0-15 are the 16 integer registers. // 16 is %rip. - AssignToArrayRange(Builder, Address, Eight8, 0, 16); - + AssignToArrayRange(CGF.Builder, Address, Eight8, 0, 16); return false; } @@ -967,13 +1014,29 @@ public: return X86AdjustInlineAsmType(CGF, Constraint, Ty); } - bool isNoProtoCallVariadic(CallingConv CC) const { + bool isNoProtoCallVariadic(const CallArgList &args, + const FunctionNoProtoType *fnType) const { // 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. - if (CC == CC_Default || CC == CC_C) return true; + // function, so we override the default behavior. However, don't do + // that when AVX types are involved: the ABI explicitly states it is + // undefined, and it doesn't work in practice because of how the ABI + // defines varargs anyway. + if (fnType->getCallConv() == CC_Default || fnType->getCallConv() == CC_C) { + bool HasAVXType = false; + for (CallArgList::const_iterator + it = args.begin(), ie = args.end(); it != ie; ++it) { + if (getABIInfo().isPassedUsingAVXType(it->Ty)) { + HasAVXType = true; + break; + } + } + + if (!HasAVXType) + return true; + } - return TargetCodeGenInfo::isNoProtoCallVariadic(CC); + return TargetCodeGenInfo::isNoProtoCallVariadic(args, fnType); } }; @@ -989,16 +1052,11 @@ public: bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const { - CodeGen::CGBuilderTy &Builder = CGF.Builder; - llvm::LLVMContext &Context = CGF.getLLVMContext(); - - llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); - llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8); + llvm::Value *Eight8 = llvm::ConstantInt::get(CGF.Int8Ty, 8); // 0-15 are the 16 integer registers. // 16 is %rip. - AssignToArrayRange(Builder, Address, Eight8, 0, 16); - + AssignToArrayRange(CGF.Builder, Address, Eight8, 0, 16); return false; } }; @@ -1164,7 +1222,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, // split. if (OffsetBase && OffsetBase != 64) Hi = Lo; - } else if (Size == 128 || Size == 256) { + } else if (Size == 128 || (HasAVX && Size == 256)) { // Arguments of 256-bits are split into four eightbyte chunks. The // least significant one belongs to class SSE and all the others to class // SSEUP. The original Lo and Hi design considers that types can't be @@ -1377,10 +1435,28 @@ ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const { return ABIArgInfo::getIndirect(0); } -ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty) const { +bool X86_64ABIInfo::IsIllegalVectorType(QualType Ty) const { + if (const VectorType *VecTy = Ty->getAs<VectorType>()) { + uint64_t Size = getContext().getTypeSize(VecTy); + unsigned LargestVector = HasAVX ? 256 : 128; + if (Size <= 64 || Size > LargestVector) + return true; + } + + return false; +} + +ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty, + unsigned freeIntRegs) const { // If this is a scalar LLVM value then assume LLVM will pass it in the right // place naturally. - if (!isAggregateTypeForABI(Ty)) { + // + // This assumption is optimistic, as there could be free registers available + // when we need to pass this argument in memory, and LLVM could try to pass + // the argument in the free register. This does not seem to happen currently, + // but this code would be much safer if we could mark the argument with + // 'onstack'. See PR12193. + if (!isAggregateTypeForABI(Ty) && !IsIllegalVectorType(Ty)) { // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs<EnumType>()) Ty = EnumTy->getDecl()->getIntegerType(); @@ -1395,6 +1471,38 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty) const { // 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. unsigned Align = std::max(getContext().getTypeAlign(Ty) / 8, 8U); + + // Attempt to avoid passing indirect results using byval when possible. This + // is important for good codegen. + // + // We do this by coercing the value into a scalar type which the backend can + // handle naturally (i.e., without using byval). + // + // For simplicity, we currently only do this when we have exhausted all of the + // free integer registers. Doing this when there are free integer registers + // would require more care, as we would have to ensure that the coerced value + // did not claim the unused register. That would require either reording the + // arguments to the function (so that any subsequent inreg values came first), + // or only doing this optimization when there were no following arguments that + // might be inreg. + // + // We currently expect it to be rare (particularly in well written code) for + // arguments to be passed on the stack when there are still free integer + // registers available (this would typically imply large structs being passed + // by value), so this seems like a fair tradeoff for now. + // + // We can revisit this if the backend grows support for 'onstack' parameter + // attributes. See PR12193. + if (freeIntRegs == 0) { + uint64_t Size = getContext().getTypeSize(Ty); + + // If this type fits in an eightbyte, coerce it into the matching integral + // type, which will end up on the stack (with alignment 8). + if (Align == 8 && Size <= 64) + return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), + Size)); + } + return ABIArgInfo::getIndirect(Align); } @@ -1416,7 +1524,7 @@ llvm::Type *X86_64ABIInfo::GetByteVectorType(QualType Ty) const { if (llvm::VectorType *VT = dyn_cast<llvm::VectorType>(IRType)){ llvm::Type *EltTy = VT->getElementType(); unsigned BitWidth = VT->getBitWidth(); - if ((BitWidth == 128 || BitWidth == 256) && + if ((BitWidth >= 128 && BitWidth <= 256) && (EltTy->isFloatTy() || EltTy->isDoubleTy() || EltTy->isIntegerTy(8) || EltTy->isIntegerTy(16) || EltTy->isIntegerTy(32) || EltTy->isIntegerTy(64) || @@ -1810,8 +1918,10 @@ classifyReturnType(QualType RetTy) const { return ABIArgInfo::getDirect(ResType); } -ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt, - unsigned &neededSSE) const { +ABIArgInfo X86_64ABIInfo::classifyArgumentType( + QualType Ty, unsigned freeIntRegs, unsigned &neededInt, unsigned &neededSSE) + const +{ X86_64ABIInfo::Class Lo, Hi; classify(Ty, 0, Lo, Hi); @@ -1843,7 +1953,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt, case ComplexX87: if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) ++neededInt; - return getIndirectResult(Ty); + return getIndirectResult(Ty, freeIntRegs); case SSEUp: case X87Up: @@ -1951,7 +2061,8 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); it != ie; ++it) { unsigned neededInt, neededSSE; - it->info = classifyArgumentType(it->type, neededInt, neededSSE); + it->info = classifyArgumentType(it->type, freeIntRegs, neededInt, + neededSSE); // AMD64-ABI 3.2.3p3: If there are no registers available for any // eightbyte of an argument, the whole argument is passed on the @@ -1961,7 +2072,7 @@ void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { freeIntRegs -= neededInt; freeSSERegs -= neededSSE; } else { - it->info = getIndirectResult(it->type); + it->info = getIndirectResult(it->type, freeIntRegs); } } } @@ -1976,19 +2087,17 @@ static llvm::Value *EmitVAArgFromMemory(llvm::Value *VAListAddr, // AMD64-ABI 3.5.7p5: Step 7. Align l->overflow_arg_area upwards to a 16 // byte boundary if alignment needed by type exceeds 8 byte boundary. + // It isn't stated explicitly in the standard, but in practice we use + // alignment greater than 16 where necessary. uint64_t Align = CGF.getContext().getTypeAlign(Ty) / 8; if (Align > 8) { - // Note that we follow the ABI & gcc here, even though the type - // could in theory have an alignment greater than 16. This case - // shouldn't ever matter in practice. - - // overflow_arg_area = (overflow_arg_area + 15) & ~15; + // overflow_arg_area = (overflow_arg_area + align - 1) & -align; llvm::Value *Offset = - llvm::ConstantInt::get(CGF.Int32Ty, 15); + llvm::ConstantInt::get(CGF.Int64Ty, Align - 1); overflow_arg_area = CGF.Builder.CreateGEP(overflow_arg_area, Offset); llvm::Value *AsInt = CGF.Builder.CreatePtrToInt(overflow_arg_area, CGF.Int64Ty); - llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int64Ty, ~15LL); + llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int64Ty, -(uint64_t)Align); overflow_arg_area = CGF.Builder.CreateIntToPtr(CGF.Builder.CreateAnd(AsInt, Mask), overflow_arg_area->getType(), @@ -2019,8 +2128,6 @@ static llvm::Value *EmitVAArgFromMemory(llvm::Value *VAListAddr, llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const { - llvm::LLVMContext &VMContext = CGF.getLLVMContext(); - // Assume that va_list type is correct; should be pointer to LLVM type: // struct { // i32 gp_offset; @@ -2031,7 +2138,7 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, unsigned neededInt, neededSSE; Ty = CGF.getContext().getCanonicalType(Ty); - ABIArgInfo AI = classifyArgumentType(Ty, neededInt, neededSSE); + ABIArgInfo AI = classifyArgumentType(Ty, 0, neededInt, neededSSE); // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed // in the registers. If not go to step 7. @@ -2129,7 +2236,7 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, // area, we need to collect the two eightbytes together. llvm::Value *RegAddrLo = CGF.Builder.CreateGEP(RegAddr, fp_offset); llvm::Value *RegAddrHi = CGF.Builder.CreateConstGEP1_32(RegAddrLo, 16); - llvm::Type *DoubleTy = llvm::Type::getDoubleTy(VMContext); + llvm::Type *DoubleTy = CGF.DoubleTy; llvm::Type *DblPtrTy = llvm::PointerType::getUnqual(DoubleTy); llvm::StructType *ST = llvm::StructType::get(DoubleTy, @@ -2192,7 +2299,8 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty) const { // FIXME: mingw-w64-gcc emits 128-bit struct as i128 if (Size == 128 && - getContext().getTargetInfo().getTriple().getOS() == llvm::Triple::MinGW32) + getContext().getTargetInfo().getTriple().getOS() + == llvm::Triple::MinGW32) return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Size)); @@ -2224,8 +2332,7 @@ void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { llvm::Value *WinX86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const { - llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); - llvm::Type *BPP = llvm::PointerType::getUnqual(BP); + llvm::Type *BPP = CGF.Int8PtrPtrTy; CGBuilderTy &Builder = CGF.Builder; llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, @@ -2270,9 +2377,8 @@ PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, // against gcc output. AFAIK all ABIs use the same encoding. CodeGen::CGBuilderTy &Builder = CGF.Builder; - llvm::LLVMContext &Context = CGF.getLLVMContext(); - llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); + llvm::IntegerType *i8 = CGF.Int8Ty; llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4); llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8); llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16); @@ -2327,8 +2433,9 @@ public: ARMABIInfo(CodeGenTypes &CGT, ABIKind _Kind) : ABIInfo(CGT), Kind(_Kind) {} bool isEABI() const { - StringRef Env = getContext().getTargetInfo().getTriple().getEnvironmentName(); - return (Env == "gnueabi" || Env == "eabi"); + StringRef Env = + getContext().getTargetInfo().getTriple().getEnvironmentName(); + return (Env == "gnueabi" || Env == "eabi" || Env == "androideabi"); } private: @@ -2362,15 +2469,10 @@ public: bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, llvm::Value *Address) const { - CodeGen::CGBuilderTy &Builder = CGF.Builder; - llvm::LLVMContext &Context = CGF.getLLVMContext(); - - llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); - llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4); + llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4); // 0-15 are the 16 integer registers. - AssignToArrayRange(Builder, Address, Four8, 0, 15); - + AssignToArrayRange(CGF.Builder, Address, Four8, 0, 15); return false; } @@ -2671,6 +2773,14 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const { if (isEmptyRecord(getContext(), RetTy, true)) return ABIArgInfo::getIgnore(); + // Check for homogeneous aggregates with AAPCS-VFP. + if (getABIKind() == AAPCS_VFP) { + const Type *Base = 0; + if (isHomogeneousAggregate(RetTy, Base, getContext())) + // Homogeneous Aggregates are returned directly. + return ABIArgInfo::getDirect(); + } + // Aggregates <= 4 bytes are returned in r0; other aggregates // are returned indirectly. uint64_t Size = getContext().getTypeSize(RetTy); @@ -2688,12 +2798,11 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const { llvm::Value *ARMABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const { - llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); - llvm::Type *BPP = llvm::PointerType::getUnqual(BP); + llvm::Type *BP = CGF.Int8PtrTy; + llvm::Type *BPP = CGF.Int8PtrPtrTy; CGBuilderTy &Builder = CGF.Builder; - llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, - "ap"); + llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap"); llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); // Handle address alignment for type alignment > 32 bits uint64_t TyAlign = CGF.getContext().getTypeAlign(Ty) / 8; @@ -2773,7 +2882,7 @@ void PTXABIInfo::computeInfo(CGFunctionInfo &FI) const { // Calling convention as default by an ABI. llvm::CallingConv::ID DefaultCC; - const LangOptions &LangOpts = getContext().getLangOptions(); + const LangOptions &LangOpts = getContext().getLangOpts(); if (LangOpts.OpenCL || LangOpts.CUDA) { // If we are in OpenCL or CUDA mode, then default to device functions DefaultCC = llvm::CallingConv::PTX_Device; @@ -2793,7 +2902,6 @@ void PTXABIInfo::computeInfo(CGFunctionInfo &FI) const { llvm::Value *PTXABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CFG) const { llvm_unreachable("PTX does not support varargs"); - return 0; } void PTXTargetCodeGenInfo::SetTargetAttributes(const Decl *D, @@ -2805,7 +2913,7 @@ void PTXTargetCodeGenInfo::SetTargetAttributes(const Decl *D, llvm::Function *F = cast<llvm::Function>(GV); // Perform special handling in OpenCL mode - if (M.getLangOptions().OpenCL) { + if (M.getLangOpts().OpenCL) { // Use OpenCL function attributes to set proper calling conventions // By default, all functions are device functions if (FD->hasAttr<OpenCLKernelAttr>()) { @@ -2817,7 +2925,7 @@ void PTXTargetCodeGenInfo::SetTargetAttributes(const Decl *D, } // Perform special handling in CUDA mode. - if (M.getLangOptions().CUDA) { + if (M.getLangOpts().CUDA) { // CUDA __global__ functions get a kernel calling convention. Since // __global__ functions cannot be called from the device, we do not // need to set the noinline attribute. @@ -2829,85 +2937,6 @@ void PTXTargetCodeGenInfo::SetTargetAttributes(const Decl *D, } //===----------------------------------------------------------------------===// -// SystemZ ABI Implementation -//===----------------------------------------------------------------------===// - -namespace { - -class SystemZABIInfo : public ABIInfo { -public: - SystemZABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {} - - bool isPromotableIntegerType(QualType Ty) const; - - 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); - } - - 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 { - // SystemZ ABI requires all 8, 16 and 32 bit quantities to be extended. - if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) - switch (BT->getKind()) { - case BuiltinType::Bool: - case BuiltinType::Char_S: - case BuiltinType::Char_U: - case BuiltinType::SChar: - case BuiltinType::UChar: - case BuiltinType::Short: - case BuiltinType::UShort: - case BuiltinType::Int: - case BuiltinType::UInt: - return true; - default: - return false; - } - return false; -} - -llvm::Value *SystemZABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, - CodeGenFunction &CGF) const { - // FIXME: Implement - return 0; -} - - -ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const { - if (RetTy->isVoidType()) - return ABIArgInfo::getIgnore(); - if (isAggregateTypeForABI(RetTy)) - return ABIArgInfo::getIndirect(0); - - return (isPromotableIntegerType(RetTy) ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); -} - -ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const { - if (isAggregateTypeForABI(Ty)) - return ABIArgInfo::getIndirect(0); - - return (isPromotableIntegerType(Ty) ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); -} - -//===----------------------------------------------------------------------===// // MBlaze ABI Implementation //===----------------------------------------------------------------------===// @@ -3063,24 +3092,28 @@ void MSP430TargetCodeGenInfo::SetTargetAttributes(const Decl *D, namespace { class MipsABIInfo : public ABIInfo { - static const unsigned MinABIStackAlignInBytes = 4; + bool IsO32; + unsigned MinABIStackAlignInBytes; + llvm::Type* HandleAggregates(QualType Ty) const; + llvm::Type* returnAggregateInRegs(QualType RetTy, uint64_t Size) const; + llvm::Type* getPaddingType(uint64_t Align, uint64_t Offset) const; public: - MipsABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {} + MipsABIInfo(CodeGenTypes &CGT, bool _IsO32) : + ABIInfo(CGT), IsO32(_IsO32), MinABIStackAlignInBytes(IsO32 ? 4 : 8) {} ABIArgInfo classifyReturnType(QualType RetTy) const; - ABIArgInfo classifyArgumentType(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; }; -const unsigned MipsABIInfo::MinABIStackAlignInBytes; - class MIPSTargetCodeGenInfo : public TargetCodeGenInfo { unsigned SizeOfUnwindException; public: - MIPSTargetCodeGenInfo(CodeGenTypes &CGT, unsigned SZ) - : TargetCodeGenInfo(new MipsABIInfo(CGT)), SizeOfUnwindException(SZ) {} + MIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32) + : TargetCodeGenInfo(new MipsABIInfo(CGT, IsO32)), + SizeOfUnwindException(IsO32 ? 24 : 32) {} int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const { return 29; @@ -3095,35 +3128,184 @@ public: }; } -ABIArgInfo MipsABIInfo::classifyArgumentType(QualType Ty) const { +// In N32/64, an aligned double precision floating point field is passed in +// a register. +llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty) const { + if (IsO32) + return 0; + + if (Ty->isComplexType()) + return CGT.ConvertType(Ty); + + const RecordType *RT = Ty->getAs<RecordType>(); + + // Unions are passed in integer registers. + if (!RT || !RT->isStructureOrClassType()) + return 0; + + const RecordDecl *RD = RT->getDecl(); + const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); + uint64_t StructSize = getContext().getTypeSize(Ty); + assert(!(StructSize % 8) && "Size of structure must be multiple of 8."); + + uint64_t LastOffset = 0; + unsigned idx = 0; + llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64); + SmallVector<llvm::Type*, 8> ArgList; + + // Iterate over fields in the struct/class and check if there are any aligned + // double fields. + for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); + i != e; ++i, ++idx) { + const QualType Ty = (*i)->getType(); + const BuiltinType *BT = Ty->getAs<BuiltinType>(); + + if (!BT || BT->getKind() != BuiltinType::Double) + continue; + + uint64_t Offset = Layout.getFieldOffset(idx); + if (Offset % 64) // Ignore doubles that are not aligned. + continue; + + // Add ((Offset - LastOffset) / 64) args of type i64. + for (unsigned j = (Offset - LastOffset) / 64; j > 0; --j) + ArgList.push_back(I64); + + // Add double type. + ArgList.push_back(llvm::Type::getDoubleTy(getVMContext())); + LastOffset = Offset + 64; + } + + // This struct/class doesn't have an aligned double field. + if (!LastOffset) + return 0; + + // Add ((StructSize - LastOffset) / 64) args of type i64. + for (unsigned N = (StructSize - LastOffset) / 64; N; --N) + ArgList.push_back(I64); + + // If the size of the remainder is not zero, add one more integer type to + // ArgList. + unsigned R = (StructSize - LastOffset) % 64; + if (R) + ArgList.push_back(llvm::IntegerType::get(getVMContext(), R)); + + return llvm::StructType::get(getVMContext(), ArgList); +} + +llvm::Type *MipsABIInfo::getPaddingType(uint64_t Align, uint64_t Offset) const { + // Padding is inserted only for N32/64. + if (IsO32) + return 0; + + assert(Align <= 16 && "Alignment larger than 16 not handled."); + return (Align == 16 && Offset & 0xf) ? + llvm::IntegerType::get(getVMContext(), 64) : 0; +} + +ABIArgInfo +MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const { + uint64_t OrigOffset = Offset; + uint64_t TySize = + llvm::RoundUpToAlignment(getContext().getTypeSize(Ty), 64) / 8; + uint64_t Align = getContext().getTypeAlign(Ty) / 8; + Offset = llvm::RoundUpToAlignment(Offset, std::max(Align, (uint64_t)8)); + Offset += TySize; + if (isAggregateTypeForABI(Ty)) { // Ignore empty aggregates. - if (getContext().getTypeSize(Ty) == 0) + if (TySize == 0) return ABIArgInfo::getIgnore(); // Records with non trivial destructors/constructors should not be passed // by value. - if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) + if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty)) { + Offset = OrigOffset + 8; return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + } - return ABIArgInfo::getIndirect(0); + // If we have reached here, aggregates are passed either indirectly via a + // byval pointer or directly by coercing to another structure type. In the + // latter case, padding is inserted if the offset of the aggregate is + // unaligned. + llvm::Type *ResType = HandleAggregates(Ty); + + if (!ResType) + return ABIArgInfo::getIndirect(0); + + return ABIArgInfo::getDirect(ResType, 0, getPaddingType(Align, OrigOffset)); } // Treat an enum type as its underlying type. if (const EnumType *EnumTy = Ty->getAs<EnumType>()) Ty = EnumTy->getDecl()->getIntegerType(); - return (Ty->isPromotableIntegerType() ? - ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + if (Ty->isPromotableIntegerType()) + return ABIArgInfo::getExtend(); + + return ABIArgInfo::getDirect(0, 0, getPaddingType(Align, OrigOffset)); +} + +llvm::Type* +MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const { + const RecordType *RT = RetTy->getAs<RecordType>(); + SmallVector<llvm::Type*, 2> RTList; + + if (RT && RT->isStructureOrClassType()) { + const RecordDecl *RD = RT->getDecl(); + const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); + unsigned FieldCnt = Layout.getFieldCount(); + + // N32/64 returns struct/classes in floating point registers if the + // following conditions are met: + // 1. The size of the struct/class is no larger than 128-bit. + // 2. The struct/class has one or two fields all of which are floating + // point types. + // 3. The offset of the first field is zero (this follows what gcc does). + // + // Any other composite results are returned in integer registers. + // + if (FieldCnt && (FieldCnt <= 2) && !Layout.getFieldOffset(0)) { + RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end(); + for (; b != e; ++b) { + const BuiltinType *BT = (*b)->getType()->getAs<BuiltinType>(); + + if (!BT || !BT->isFloatingPoint()) + break; + + RTList.push_back(CGT.ConvertType((*b)->getType())); + } + + if (b == e) + return llvm::StructType::get(getVMContext(), RTList, + RD->hasAttr<PackedAttr>()); + + RTList.clear(); + } + } + + RTList.push_back(llvm::IntegerType::get(getVMContext(), + std::min(Size, (uint64_t)64))); + if (Size > 64) + RTList.push_back(llvm::IntegerType::get(getVMContext(), Size - 64)); + + return llvm::StructType::get(getVMContext(), RTList); } ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const { - if (RetTy->isVoidType()) + uint64_t Size = getContext().getTypeSize(RetTy); + + if (RetTy->isVoidType() || Size == 0) return ABIArgInfo::getIgnore(); if (isAggregateTypeForABI(RetTy)) { - if (RetTy->isAnyComplexType()) - return ABIArgInfo::getDirect(); + if (Size <= 128) { + if (RetTy->isAnyComplexType()) + return ABIArgInfo::getDirect(); + + if (!IsO32 && !isRecordWithNonTrivialDestructorOrCopyConstructor(RetTy)) + return ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size)); + } return ABIArgInfo::getIndirect(0); } @@ -3137,29 +3319,36 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const { } void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const { - FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); + ABIArgInfo &RetInfo = FI.getReturnInfo(); + RetInfo = classifyReturnType(FI.getReturnType()); + + // Check if a pointer to an aggregate is passed as a hidden argument. + uint64_t Offset = RetInfo.isIndirect() ? 8 : 0; + for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); it != ie; ++it) - it->info = classifyArgumentType(it->type); + it->info = classifyArgumentType(it->type, Offset); } llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const { - llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); - llvm::Type *BPP = llvm::PointerType::getUnqual(BP); + llvm::Type *BP = CGF.Int8PtrTy; + llvm::Type *BPP = CGF.Int8PtrPtrTy; CGBuilderTy &Builder = CGF.Builder; llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap"); llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); - unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8; + 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); + llvm::IntegerType *IntTy = (PtrWidth == 32) ? CGF.Int32Ty : CGF.Int64Ty; if (TypeAlign > MinABIStackAlignInBytes) { - llvm::Value *AddrAsInt32 = CGF.Builder.CreatePtrToInt(Addr, CGF.Int32Ty); - llvm::Value *Inc = llvm::ConstantInt::get(CGF.Int32Ty, TypeAlign - 1); - llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty, -TypeAlign); - llvm::Value *Add = CGF.Builder.CreateAdd(AddrAsInt32, Inc); + llvm::Value *AddrAsInt = CGF.Builder.CreatePtrToInt(Addr, IntTy); + llvm::Value *Inc = llvm::ConstantInt::get(IntTy, TypeAlign - 1); + llvm::Value *Mask = llvm::ConstantInt::get(IntTy, -TypeAlign); + llvm::Value *Add = CGF.Builder.CreateAdd(AddrAsInt, Inc); llvm::Value *And = CGF.Builder.CreateAnd(Add, Mask); AddrTyped = CGF.Builder.CreateIntToPtr(And, PTy); } @@ -3167,11 +3356,11 @@ llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, AddrTyped = Builder.CreateBitCast(Addr, PTy); llvm::Value *AlignedAddr = Builder.CreateBitCast(AddrTyped, BP); - TypeAlign = std::max(TypeAlign, MinABIStackAlignInBytes); + TypeAlign = std::max((unsigned)TypeAlign, MinABIStackAlignInBytes); uint64_t Offset = llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, TypeAlign); llvm::Value *NextAddr = - Builder.CreateGEP(AlignedAddr, llvm::ConstantInt::get(CGF.Int32Ty, Offset), + Builder.CreateGEP(AlignedAddr, llvm::ConstantInt::get(IntTy, Offset), "ap.next"); Builder.CreateStore(NextAddr, VAListAddrAsBPP); @@ -3184,19 +3373,15 @@ MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, // This information comes from gcc's implementation, which seems to // as canonical as it gets. - CodeGen::CGBuilderTy &Builder = CGF.Builder; - llvm::LLVMContext &Context = CGF.getLLVMContext(); - // Everything on MIPS is 4 bytes. Double-precision FP registers // are aliased to pairs of single-precision FP registers. - llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); - llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4); + llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4); // 0-31 are the general purpose registers, $0 - $31. // 32-63 are the floating-point registers, $f0 - $f31. // 64 and 65 are the multiply/divide registers, $hi and $lo. // 66 is the (notional, I think) register for signal-handler return. - AssignToArrayRange(Builder, Address, Four8, 0, 65); + AssignToArrayRange(CGF.Builder, Address, Four8, 0, 65); // 67-74 are the floating-point status registers, $fcc0 - $fcc7. // They are one bit wide and ignored here. @@ -3206,8 +3391,7 @@ MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, // 112-143 are the coprocessor 2 registers, $c2r0 - $c2r31. // 144-175 are the coprocessor 3 registers, $c3r0 - $c3r31. // 176-181 are the DSP accumulator registers. - AssignToArrayRange(Builder, Address, Four8, 80, 181); - + AssignToArrayRange(CGF.Builder, Address, Four8, 80, 181); return false; } @@ -3236,7 +3420,7 @@ void TCETargetCodeGenInfo::SetTargetAttributes(const Decl *D, llvm::Function *F = cast<llvm::Function>(GV); - if (M.getLangOptions().OpenCL) { + if (M.getLangOpts().OpenCL) { if (FD->hasAttr<OpenCLKernelAttr>()) { // OpenCL C Kernel functions are not subject to inlining F->addFnAttr(llvm::Attribute::NoInline); @@ -3251,27 +3435,20 @@ void TCETargetCodeGenInfo::SetTargetAttributes(const Decl *D, SmallVector<llvm::Value*, 5> Operands; Operands.push_back(F); - Operands.push_back(llvm::Constant::getIntegerValue( - llvm::Type::getInt32Ty(Context), - llvm::APInt( - 32, - FD->getAttr<ReqdWorkGroupSizeAttr>()->getXDim()))); - Operands.push_back(llvm::Constant::getIntegerValue( - llvm::Type::getInt32Ty(Context), - llvm::APInt( - 32, + Operands.push_back(llvm::Constant::getIntegerValue(M.Int32Ty, + llvm::APInt(32, + FD->getAttr<ReqdWorkGroupSizeAttr>()->getXDim()))); + Operands.push_back(llvm::Constant::getIntegerValue(M.Int32Ty, + llvm::APInt(32, FD->getAttr<ReqdWorkGroupSizeAttr>()->getYDim()))); - Operands.push_back(llvm::Constant::getIntegerValue( - llvm::Type::getInt32Ty(Context), - llvm::APInt( - 32, + Operands.push_back(llvm::Constant::getIntegerValue(M.Int32Ty, + llvm::APInt(32, FD->getAttr<ReqdWorkGroupSizeAttr>()->getZDim()))); // Add a boolean constant operand for "required" (true) or "hint" (false) // for implementing the work_group_size_hint attr later. Currently // always true as the hint is not yet implemented. - Operands.push_back(llvm::ConstantInt::getTrue(llvm::Type::getInt1Ty(Context))); - + Operands.push_back(llvm::ConstantInt::getTrue(Context)); OpenCLMetadata->addOperand(llvm::MDNode::get(Context, Operands)); } } @@ -3280,6 +3457,147 @@ void TCETargetCodeGenInfo::SetTargetAttributes(const Decl *D, } +//===----------------------------------------------------------------------===// +// Hexagon ABI Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class HexagonABIInfo : public ABIInfo { + + +public: + HexagonABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {} + +private: + + 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; +}; + +class HexagonTargetCodeGenInfo : public TargetCodeGenInfo { +public: + HexagonTargetCodeGenInfo(CodeGenTypes &CGT) + :TargetCodeGenInfo(new HexagonABIInfo(CGT)) {} + + int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const { + return 29; + } +}; + +} + +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); +} + +ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty) const { + if (!isAggregateTypeForABI(Ty)) { + // Treat an enum type as its underlying type. + if (const EnumType *EnumTy = Ty->getAs<EnumType>()) + Ty = EnumTy->getDecl()->getIntegerType(); + + return (Ty->isPromotableIntegerType() ? + ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + } + + // Ignore empty records. + 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); + + uint64_t Size = getContext().getTypeSize(Ty); + if (Size > 64) + return ABIArgInfo::getIndirect(0, /*ByVal=*/true); + // Pass in the smallest viable integer type. + else if (Size > 32) + return ABIArgInfo::getDirect(llvm::Type::getInt64Ty(getVMContext())); + else if (Size > 16) + return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext())); + else if (Size > 8) + return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext())); + else + return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext())); +} + +ABIArgInfo HexagonABIInfo::classifyReturnType(QualType RetTy) const { + if (RetTy->isVoidType()) + return ABIArgInfo::getIgnore(); + + // Large vector types should be returned via memory. + if (RetTy->isVectorType() && getContext().getTypeSize(RetTy) > 64) + 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() ? + ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); + } + + // Structures with either a non-trivial destructor or a non-trivial + // copy constructor are always indirect. + if (isRecordWithNonTrivialDestructorOrCopyConstructor(RetTy)) + return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + + if (isEmptyRecord(getContext(), RetTy, true)) + return ABIArgInfo::getIgnore(); + + // Aggregates <= 8 bytes are returned in r0; other aggregates + // are returned indirectly. + uint64_t Size = getContext().getTypeSize(RetTy); + if (Size <= 64) { + // Return in the smallest viable integer type. + if (Size <= 8) + return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext())); + if (Size <= 16) + return ABIArgInfo::getDirect(llvm::Type::getInt16Ty(getVMContext())); + if (Size <= 32) + return ABIArgInfo::getDirect(llvm::Type::getInt32Ty(getVMContext())); + return ABIArgInfo::getDirect(llvm::Type::getInt64Ty(getVMContext())); + } + + return ABIArgInfo::getIndirect(0, /*ByVal=*/true); +} + +llvm::Value *HexagonABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, + CodeGenFunction &CGF) const { + // FIXME: Need to handle alignment + llvm::Type *BPP = CGF.Int8PtrPtrTy; + + CGBuilderTy &Builder = CGF.Builder; + llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, + "ap"); + llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); + llvm::Type *PTy = + llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); + llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy); + + uint64_t Offset = + llvm::RoundUpToAlignment(CGF.getContext().getTypeSize(Ty) / 8, 4); + llvm::Value *NextAddr = + Builder.CreateGEP(Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset), + "ap.next"); + Builder.CreateStore(NextAddr, VAListAddrAsBPP); + + return AddrTyped; +} + + const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { if (TheTargetCodeGenInfo) return *TheTargetCodeGenInfo; @@ -3291,11 +3609,11 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::mips: case llvm::Triple::mipsel: - return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, 24)); + return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, true)); case llvm::Triple::mips64: case llvm::Triple::mips64el: - return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, 32)); + return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, false)); case llvm::Triple::arm: case llvm::Triple::thumb: @@ -3317,9 +3635,6 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::ptx64: return *(TheTargetCodeGenInfo = new PTXTargetCodeGenInfo(Types)); - case llvm::Triple::systemz: - return *(TheTargetCodeGenInfo = new SystemZTargetCodeGenInfo(Types)); - case llvm::Triple::mblaze: return *(TheTargetCodeGenInfo = new MBlazeTargetCodeGenInfo(Types)); @@ -3334,7 +3649,8 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { if (Triple.isOSDarwin()) return *(TheTargetCodeGenInfo = - new X86_32TargetCodeGenInfo(Types, true, true, DisableMMX)); + new X86_32TargetCodeGenInfo( + Types, true, true, DisableMMX, false)); switch (Triple.getOS()) { case llvm::Triple::Cygwin: @@ -3343,24 +3659,36 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() { case llvm::Triple::DragonFly: case llvm::Triple::FreeBSD: case llvm::Triple::OpenBSD: - case llvm::Triple::NetBSD: return *(TheTargetCodeGenInfo = - new X86_32TargetCodeGenInfo(Types, false, true, DisableMMX)); + new X86_32TargetCodeGenInfo( + Types, false, true, DisableMMX, false)); + + case llvm::Triple::Win32: + return *(TheTargetCodeGenInfo = + new X86_32TargetCodeGenInfo( + Types, false, true, DisableMMX, true)); default: return *(TheTargetCodeGenInfo = - new X86_32TargetCodeGenInfo(Types, false, false, DisableMMX)); + new X86_32TargetCodeGenInfo( + Types, false, false, DisableMMX, false)); } } - case llvm::Triple::x86_64: + case llvm::Triple::x86_64: { + bool HasAVX = strcmp(getContext().getTargetInfo().getABI(), "avx") == 0; + switch (Triple.getOS()) { case llvm::Triple::Win32: case llvm::Triple::MinGW32: case llvm::Triple::Cygwin: return *(TheTargetCodeGenInfo = new WinX86_64TargetCodeGenInfo(Types)); default: - return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo(Types)); + return *(TheTargetCodeGenInfo = new X86_64TargetCodeGenInfo(Types, + HasAVX)); } } + case llvm::Triple::hexagon: + return *(TheTargetCodeGenInfo = new HexagonTargetCodeGenInfo(Types)); + } } |