diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp')
| -rw-r--r-- | contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp | 420 | 
1 files changed, 347 insertions, 73 deletions
diff --git a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp index df2c1bd98cca..e1dc8f7ffdbd 100644 --- a/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp +++ b/contrib/llvm/tools/clang/lib/CodeGen/TargetInfo.cpp @@ -57,12 +57,12 @@ const llvm::TargetData &ABIInfo::getTargetData() const {  void ABIArgInfo::dump() const { -  llvm::raw_ostream &OS = llvm::errs(); +  raw_ostream &OS = llvm::errs();    OS << "(ABIArgInfo Kind=";    switch (TheKind) {    case Direct:      OS << "Direct Type="; -    if (const llvm::Type *Ty = getCoerceToType()) +    if (llvm::Type *Ty = getCoerceToType())        Ty->print(OS);      else        OS << "null"; @@ -87,6 +87,25 @@ void ABIArgInfo::dump() const {  TargetCodeGenInfo::~TargetCodeGenInfo() { delete Info; } +// If someone can figure out a general rule for this, that would be great. +// It's probably just doomed to be platform-dependent, though. +unsigned TargetCodeGenInfo::getSizeOfUnwindException() const { +  // Verified for: +  //   x86-64     FreeBSD, Linux, Darwin +  //   x86-32     FreeBSD, Linux, Darwin +  //   PowerPC    Linux, Darwin +  //   ARM        Darwin (*not* EABI) +  return 32; +} + +bool TargetCodeGenInfo::isNoProtoCallVariadic(CallingConv CC) const { +  // The following conventions are known to require this to be false: +  //   x86_stdcall +  //   MIPS +  // For everything else, we just prefer false unless we opt out. +  return false; +} +  static bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays);  /// isEmptyField - Return true iff a the field is "empty", that is it @@ -348,7 +367,7 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {  /// UseX86_MMXType - Return true if this is an MMX type that should use the special  /// x86_mmx type. -bool UseX86_MMXType(const llvm::Type *IRType) { +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.    return IRType->isVectorTy() && IRType->getPrimitiveSizeInBits() == 64 && @@ -357,7 +376,7 @@ bool UseX86_MMXType(const llvm::Type *IRType) {  }  static llvm::Type* X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF, -                                          llvm::StringRef Constraint, +                                          StringRef Constraint,                                            llvm::Type* Ty) {    if ((Constraint == "y" || Constraint == "&y") && Ty->isVectorTy())      return llvm::Type::getX86_MMXTy(CGF.getLLVMContext()); @@ -428,7 +447,7 @@ public:                                 llvm::Value *Address) const;    llvm::Type* adjustInlineAsmType(CodeGen::CodeGenFunction &CGF, -                                  llvm::StringRef Constraint, +                                  StringRef Constraint,                                    llvm::Type* Ty) const {      return X86AdjustInlineAsmType(CGF, Constraint, Ty);    } @@ -724,8 +743,8 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty) const {  llvm::Value *X86_32ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,                                        CodeGenFunction &CGF) const { -  const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); -  const llvm::Type *BPP = llvm::PointerType::getUnqual(BP); +  llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); +  llvm::Type *BPP = llvm::PointerType::getUnqual(BP);    CGBuilderTy &Builder = CGF.Builder;    llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, @@ -765,7 +784,7 @@ bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable(    CodeGen::CGBuilderTy &Builder = CGF.Builder;    llvm::LLVMContext &Context = CGF.getLLVMContext(); -  const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); +  llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);    llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);    // 0-7 are the eight integer registers;  the order is different @@ -892,7 +911,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().Target.getTriple().isOSDarwin(); +    return !getContext().getTargetInfo().getTriple().isOSDarwin();    }  public: @@ -932,7 +951,7 @@ public:      CodeGen::CGBuilderTy &Builder = CGF.Builder;      llvm::LLVMContext &Context = CGF.getLLVMContext(); -    const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); +    llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);      llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);      // 0-15 are the 16 integer registers. @@ -943,11 +962,20 @@ public:    }    llvm::Type* adjustInlineAsmType(CodeGen::CodeGenFunction &CGF, -                                  llvm::StringRef Constraint, +                                  StringRef Constraint,                                    llvm::Type* Ty) const {      return X86AdjustInlineAsmType(CGF, Constraint, Ty);    } +  bool isNoProtoCallVariadic(CallingConv CC) 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; + +    return TargetCodeGenInfo::isNoProtoCallVariadic(CC); +  } +  };  class WinX86_64TargetCodeGenInfo : public TargetCodeGenInfo { @@ -964,7 +992,7 @@ public:      CodeGen::CGBuilderTy &Builder = CGF.Builder;      llvm::LLVMContext &Context = CGF.getLLVMContext(); -    const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); +    llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);      llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);      // 0-15 are the 16 integer registers. @@ -1309,8 +1337,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase,            continue;          uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx); -        uint64_t Size = -          i->getBitWidth()->EvaluateAsInt(getContext()).getZExtValue(); +        uint64_t Size = i->getBitWidthValue(getContext());          uint64_t EB_Lo = Offset / 64;          uint64_t EB_Hi = (Offset + Size - 1) / 64; @@ -1489,14 +1516,14 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit,  /// float member at the specified offset.  For example, {int,{float}} has a  /// float at offset 4.  It is conservatively correct for this routine to return  /// false. -static bool ContainsFloatAtOffset(const llvm::Type *IRType, unsigned IROffset, +static bool ContainsFloatAtOffset(llvm::Type *IRType, unsigned IROffset,                                    const llvm::TargetData &TD) {    // Base case if we find a float.    if (IROffset == 0 && IRType->isFloatTy())      return true;    // If this is a struct, recurse into the field at the specified offset. -  if (const llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType)) { +  if (llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType)) {      const llvm::StructLayout *SL = TD.getStructLayout(STy);      unsigned Elt = SL->getElementContainingOffset(IROffset);      IROffset -= SL->getElementOffset(Elt); @@ -1504,8 +1531,8 @@ static bool ContainsFloatAtOffset(const llvm::Type *IRType, unsigned IROffset,    }    // If this is an array, recurse into the field at the specified offset. -  if (const llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(IRType)) { -    const llvm::Type *EltTy = ATy->getElementType(); +  if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(IRType)) { +    llvm::Type *EltTy = ATy->getElementType();      unsigned EltSize = TD.getTypeAllocSize(EltTy);      IROffset -= IROffset/EltSize*EltSize;      return ContainsFloatAtOffset(EltTy, IROffset, TD); @@ -1578,7 +1605,7 @@ GetINTEGERTypeAtOffset(llvm::Type *IRType, unsigned IROffset,      }    } -  if (const llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType)) { +  if (llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType)) {      // If this is a struct, recurse into the field at the specified offset.      const llvm::StructLayout *SL = getTargetData().getStructLayout(STy);      if (IROffset < SL->getSizeInBytes()) { @@ -1590,7 +1617,7 @@ GetINTEGERTypeAtOffset(llvm::Type *IRType, unsigned IROffset,      }    } -  if (const llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(IRType)) { +  if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(IRType)) {      llvm::Type *EltTy = ATy->getElementType();      unsigned EltSize = getTargetData().getTypeAllocSize(EltTy);      unsigned EltOffset = IROffset/EltSize*EltSize; @@ -1678,7 +1705,7 @@ classifyReturnType(QualType RetTy) const {    case SSEUp:    case X87Up: -    assert(0 && "Invalid classification for lo word."); +    llvm_unreachable("Invalid classification for lo word.");      // AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via      // hidden argument. @@ -1732,7 +1759,7 @@ classifyReturnType(QualType RetTy) const {      // never occur as a hi class.    case Memory:    case X87: -    assert(0 && "Invalid classification for hi word."); +    llvm_unreachable("Invalid classification for hi word.");    case ComplexX87: // Previously handled.    case NoClass: @@ -1820,7 +1847,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,    case SSEUp:    case X87Up: -    assert(0 && "Invalid classification for lo word."); +    llvm_unreachable("Invalid classification for lo word.");      // AMD64-ABI 3.2.3p3: Rule 2. If the class is INTEGER, the next      // available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8 @@ -1864,8 +1891,7 @@ ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned &neededInt,    case Memory:    case X87:    case ComplexX87: -    assert(0 && "Invalid classification for hi word."); -    break; +    llvm_unreachable("Invalid classification for hi word.");    case NoClass: break; @@ -1970,7 +1996,7 @@ static llvm::Value *EmitVAArgFromMemory(llvm::Value *VAListAddr,    }    // AMD64-ABI 3.5.7p5: Step 8. Fetch type from l->overflow_arg_area. -  const llvm::Type *LTy = CGF.ConvertTypeForMem(Ty); +  llvm::Type *LTy = CGF.ConvertTypeForMem(Ty);    llvm::Value *Res =      CGF.Builder.CreateBitCast(overflow_arg_area,                                llvm::PointerType::getUnqual(LTy)); @@ -2061,22 +2087,22 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,    // collect arguments from different places; often what should result in a    // simple assembling of a structure from scattered addresses has many more    // loads than necessary. Can we clean this up? -  const llvm::Type *LTy = CGF.ConvertTypeForMem(Ty); +  llvm::Type *LTy = CGF.ConvertTypeForMem(Ty);    llvm::Value *RegAddr =      CGF.Builder.CreateLoad(CGF.Builder.CreateStructGEP(VAListAddr, 3),                             "reg_save_area");    if (neededInt && neededSSE) {      // FIXME: Cleanup.      assert(AI.isDirect() && "Unexpected ABI info for mixed regs"); -    const llvm::StructType *ST = cast<llvm::StructType>(AI.getCoerceToType()); +    llvm::StructType *ST = cast<llvm::StructType>(AI.getCoerceToType());      llvm::Value *Tmp = CGF.CreateTempAlloca(ST);      assert(ST->getNumElements() == 2 && "Unexpected ABI info for mixed regs"); -    const llvm::Type *TyLo = ST->getElementType(0); -    const llvm::Type *TyHi = ST->getElementType(1); +    llvm::Type *TyLo = ST->getElementType(0); +    llvm::Type *TyHi = ST->getElementType(1);      assert((TyLo->isFPOrFPVectorTy() ^ TyHi->isFPOrFPVectorTy()) &&             "Unexpected ABI info for mixed regs"); -    const llvm::Type *PTyLo = llvm::PointerType::getUnqual(TyLo); -    const llvm::Type *PTyHi = llvm::PointerType::getUnqual(TyHi); +    llvm::Type *PTyLo = llvm::PointerType::getUnqual(TyLo); +    llvm::Type *PTyHi = llvm::PointerType::getUnqual(TyHi);      llvm::Value *GPAddr = CGF.Builder.CreateGEP(RegAddr, gp_offset);      llvm::Value *FPAddr = CGF.Builder.CreateGEP(RegAddr, fp_offset);      llvm::Value *RegLoAddr = TyLo->isFloatingPointTy() ? FPAddr : GPAddr; @@ -2104,9 +2130,9 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,      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); -    const llvm::Type *DblPtrTy = +    llvm::Type *DblPtrTy =        llvm::PointerType::getUnqual(DoubleTy); -    const llvm::StructType *ST = llvm::StructType::get(DoubleTy, +    llvm::StructType *ST = llvm::StructType::get(DoubleTy,                                                         DoubleTy, NULL);      llvm::Value *V, *Tmp = CGF.CreateTempAlloca(ST);      V = CGF.Builder.CreateLoad(CGF.Builder.CreateBitCast(RegAddrLo, @@ -2166,7 +2192,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty) const {      // FIXME: mingw-w64-gcc emits 128-bit struct as i128      if (Size == 128 && -        getContext().Target.getTriple().getOS() == llvm::Triple::MinGW32) +        getContext().getTargetInfo().getTriple().getOS() == llvm::Triple::MinGW32)        return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),                                                            Size)); @@ -2198,8 +2224,8 @@ void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const {  llvm::Value *WinX86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,                                        CodeGenFunction &CGF) const { -  const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); -  const llvm::Type *BPP = llvm::PointerType::getUnqual(BP); +  llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); +  llvm::Type *BPP = llvm::PointerType::getUnqual(BP);    CGBuilderTy &Builder = CGF.Builder;    llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, @@ -2246,7 +2272,7 @@ PPC32TargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,    CodeGen::CGBuilderTy &Builder = CGF.Builder;    llvm::LLVMContext &Context = CGF.getLLVMContext(); -  const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); +  llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);    llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);    llvm::Value *Eight8 = llvm::ConstantInt::get(i8, 8);    llvm::Value *Sixteen8 = llvm::ConstantInt::get(i8, 16); @@ -2300,6 +2326,11 @@ private:  public:    ARMABIInfo(CodeGenTypes &CGT, ABIKind _Kind) : ABIInfo(CGT), Kind(_Kind) {} +  bool isEABI() const { +    StringRef Env = getContext().getTargetInfo().getTriple().getEnvironmentName(); +    return (Env == "gnueabi" || Env == "eabi"); +  } +  private:    ABIKind getABIKind() const { return Kind; } @@ -2317,11 +2348,15 @@ public:    ARMTargetCodeGenInfo(CodeGenTypes &CGT, ARMABIInfo::ABIKind K)      :TargetCodeGenInfo(new ARMABIInfo(CGT, K)) {} +  const ARMABIInfo &getABIInfo() const { +    return static_cast<const ARMABIInfo&>(TargetCodeGenInfo::getABIInfo()); +  } +    int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const {      return 13;    } -  llvm::StringRef getARCRetainAutoreleasedReturnValueMarker() const { +  StringRef getARCRetainAutoreleasedReturnValueMarker() const {      return "mov\tr7, r7\t\t@ marker for objc_retainAutoreleaseReturnValue";    } @@ -2330,7 +2365,7 @@ public:      CodeGen::CGBuilderTy &Builder = CGF.Builder;      llvm::LLVMContext &Context = CGF.getLLVMContext(); -    const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); +    llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);      llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);      // 0-15 are the 16 integer registers. @@ -2338,6 +2373,11 @@ public:      return false;    } + +  unsigned getSizeOfUnwindException() const { +    if (getABIInfo().isEABI()) return 88; +    return TargetCodeGenInfo::getSizeOfUnwindException(); +  }  };  } @@ -2354,8 +2394,7 @@ void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {    // Calling convention as default by an ABI.    llvm::CallingConv::ID DefaultCC; -  llvm::StringRef Env = getContext().Target.getTriple().getEnvironmentName(); -  if (Env == "gnueabi" || Env == "eabi") +  if (isEABI())      DefaultCC = llvm::CallingConv::ARM_AAPCS;    else      DefaultCC = llvm::CallingConv::ARM_APCS; @@ -2379,6 +2418,73 @@ void ARMABIInfo::computeInfo(CGFunctionInfo &FI) const {    }  } +/// isHomogeneousAggregate - Return true if a type is an AAPCS-VFP homogeneous +/// aggregate.  If HAMembers is non-null, the number of base elements +/// contained in the type is returned through it; this is used for the +/// recursive calls that check aggregate component types. +static bool isHomogeneousAggregate(QualType Ty, const Type *&Base, +                                   ASTContext &Context, +                                   uint64_t *HAMembers = 0) { +  uint64_t Members; +  if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) { +    if (!isHomogeneousAggregate(AT->getElementType(), Base, Context, &Members)) +      return false; +    Members *= AT->getSize().getZExtValue(); +  } else if (const RecordType *RT = Ty->getAs<RecordType>()) { +    const RecordDecl *RD = RT->getDecl(); +    if (RD->isUnion() || RD->hasFlexibleArrayMember()) +      return false; +    if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { +      if (!CXXRD->isAggregate()) +        return false; +    } +    Members = 0; +    for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); +         i != e; ++i) { +      const FieldDecl *FD = *i; +      uint64_t FldMembers; +      if (!isHomogeneousAggregate(FD->getType(), Base, Context, &FldMembers)) +        return false; +      Members += FldMembers; +    } +  } else { +    Members = 1; +    if (const ComplexType *CT = Ty->getAs<ComplexType>()) { +      Members = 2; +      Ty = CT->getElementType(); +    } + +    // Homogeneous aggregates for AAPCS-VFP must have base types of float, +    // double, or 64-bit or 128-bit vectors. +    if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { +      if (BT->getKind() != BuiltinType::Float &&  +          BT->getKind() != BuiltinType::Double) +        return false; +    } else if (const VectorType *VT = Ty->getAs<VectorType>()) { +      unsigned VecSize = Context.getTypeSize(VT); +      if (VecSize != 64 && VecSize != 128) +        return false; +    } else { +      return false; +    } + +    // The base type must be the same for all members.  Vector types of the +    // same total size are treated as being equivalent here. +    const Type *TyPtr = Ty.getTypePtr(); +    if (!Base) +      Base = TyPtr; +    if (Base != TyPtr && +        (!Base->isVectorType() || !TyPtr->isVectorType() || +         Context.getTypeSize(Base) != Context.getTypeSize(TyPtr))) +      return false; +  } + +  // Homogeneous Aggregates can have at most 4 members of the base type. +  if (HAMembers) +    *HAMembers = Members; +  return (Members <= 4); +} +  ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty) const {    if (!isAggregateTypeForABI(Ty)) {      // Treat an enum type as its underlying type. @@ -2398,23 +2504,26 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty) const {    if (isRecordWithNonTrivialDestructorOrCopyConstructor(Ty))      return ABIArgInfo::getIndirect(0, /*ByVal=*/false); +  if (getABIKind() == ARMABIInfo::AAPCS_VFP) { +    // Homogeneous Aggregates need to be expanded. +    const Type *Base = 0; +    if (isHomogeneousAggregate(Ty, Base, getContext())) +      return ABIArgInfo::getExpand(); +  } +    // Otherwise, pass by coercing to a structure of the appropriate size.    // +  // FIXME: This is kind of nasty... but there isn't much choice because the ARM +  // backend doesn't support byval.    // FIXME: This doesn't handle alignment > 64 bits. -  const llvm::Type* ElemTy; +  llvm::Type* ElemTy;    unsigned SizeRegs; -  if (getContext().getTypeSizeInChars(Ty) <= CharUnits::fromQuantity(64)) { -    ElemTy = llvm::Type::getInt32Ty(getVMContext()); -    SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32; -  } else if (getABIKind() == ARMABIInfo::APCS) { -    // Initial ARM ByVal support is APCS-only. -    return ABIArgInfo::getIndirect(0, /*ByVal=*/true); -  } else { -    // FIXME: This is kind of nasty... but there isn't much choice -    // because most of the ARM calling conventions don't yet support -    // byval. +  if (getContext().getTypeAlign(Ty) > 32) {      ElemTy = llvm::Type::getInt64Ty(getVMContext());      SizeRegs = (getContext().getTypeSize(Ty) + 63) / 64; +  } else { +    ElemTy = llvm::Type::getInt32Ty(getVMContext()); +    SizeRegs = (getContext().getTypeSize(Ty) + 31) / 32;    }    llvm::Type *STy = @@ -2579,14 +2688,23 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy) const {  llvm::Value *ARMABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,                                     CodeGenFunction &CGF) const { -  // FIXME: Need to handle alignment -  const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); -  const llvm::Type *BPP = llvm::PointerType::getUnqual(BP); +  llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); +  llvm::Type *BPP = llvm::PointerType::getUnqual(BP);    CGBuilderTy &Builder = CGF.Builder;    llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP,                                                         "ap");    llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); +  // Handle address alignment for type alignment > 32 bits +  uint64_t TyAlign = CGF.getContext().getTypeAlign(Ty) / 8; +  if (TyAlign > 4) { +    assert((TyAlign & (TyAlign - 1)) == 0 && +           "Alignment is not power of 2!"); +    llvm::Value *AddrAsInt = Builder.CreatePtrToInt(Addr, CGF.Int32Ty); +    AddrAsInt = Builder.CreateAdd(AddrAsInt, Builder.getInt32(TyAlign - 1)); +    AddrAsInt = Builder.CreateAnd(AddrAsInt, Builder.getInt32(~(TyAlign - 1))); +    Addr = Builder.CreateIntToPtr(AddrAsInt, BP); +  }    llvm::Type *PTy =      llvm::PointerType::getUnqual(CGF.ConvertType(Ty));    llvm::Value *AddrTyped = Builder.CreateBitCast(Addr, PTy); @@ -2623,6 +2741,9 @@ class PTXTargetCodeGenInfo : public TargetCodeGenInfo {  public:    PTXTargetCodeGenInfo(CodeGenTypes &CGT)      : TargetCodeGenInfo(new PTXABIInfo(CGT)) {} +     +  virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, +                                   CodeGen::CodeGenModule &M) const;  };  ABIArgInfo PTXABIInfo::classifyReturnType(QualType RetTy) const { @@ -2652,13 +2773,21 @@ void PTXABIInfo::computeInfo(CGFunctionInfo &FI) const {    // Calling convention as default by an ABI.    llvm::CallingConv::ID DefaultCC; -  llvm::StringRef Env = getContext().Target.getTriple().getEnvironmentName(); -  if (Env == "device") +  const LangOptions &LangOpts = getContext().getLangOptions(); +  if (LangOpts.OpenCL || LangOpts.CUDA) { +    // If we are in OpenCL or CUDA mode, then default to device functions      DefaultCC = llvm::CallingConv::PTX_Device; -  else -    DefaultCC = llvm::CallingConv::PTX_Kernel; - +  } 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") +      DefaultCC = llvm::CallingConv::PTX_Device; +    else +      DefaultCC = llvm::CallingConv::PTX_Kernel; +  }    FI.setEffectiveCallingConvention(DefaultCC); +     }  llvm::Value *PTXABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, @@ -2667,6 +2796,36 @@ llvm::Value *PTXABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,    return 0;  } +void PTXTargetCodeGenInfo::SetTargetAttributes(const Decl *D, +                                               llvm::GlobalValue *GV, +                                               CodeGen::CodeGenModule &M) const{ +  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); +  if (!FD) return; + +  llvm::Function *F = cast<llvm::Function>(GV); + +  // Perform special handling in OpenCL mode +  if (M.getLangOptions().OpenCL) { +    // Use OpenCL function attributes to set proper calling conventions +    // 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); +      // And kernel functions are not subject to inlining +      F->addFnAttr(llvm::Attribute::NoInline); +    } +  } + +  // Perform special handling in CUDA mode. +  if (M.getLangOptions().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. +    if (FD->getAttr<CUDAGlobalAttr>()) +      F->setCallingConv(llvm::CallingConv::PTX_Kernel); +  } +} +  }  //===----------------------------------------------------------------------===// @@ -2891,7 +3050,7 @@ void MSP430TargetCodeGenInfo::SetTargetAttributes(const Decl *D,        // Step 3: Emit ISR vector alias.        unsigned Num = attr->getNumber() + 0xffe0;        new llvm::GlobalAlias(GV->getType(), llvm::Function::ExternalLinkage, -                            "vector_" + llvm::Twine::utohexstr(Num), +                            "vector_" + Twine::utohexstr(Num),                              GV, &M.getModule());      }    } @@ -2904,6 +3063,7 @@ void MSP430TargetCodeGenInfo::SetTargetAttributes(const Decl *D,  namespace {  class MipsABIInfo : public ABIInfo { +  static const unsigned MinABIStackAlignInBytes = 4;  public:    MipsABIInfo(CodeGenTypes &CGT) : ABIInfo(CGT) {} @@ -2914,10 +3074,13 @@ public:                                   CodeGenFunction &CGF) const;  }; +const unsigned MipsABIInfo::MinABIStackAlignInBytes; +  class MIPSTargetCodeGenInfo : public TargetCodeGenInfo { +  unsigned SizeOfUnwindException;  public: -  MIPSTargetCodeGenInfo(CodeGenTypes &CGT) -    : TargetCodeGenInfo(new MipsABIInfo(CGT)) {} +  MIPSTargetCodeGenInfo(CodeGenTypes &CGT, unsigned SZ) +    : TargetCodeGenInfo(new MipsABIInfo(CGT)), SizeOfUnwindException(SZ) {}    int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const {      return 29; @@ -2925,6 +3088,10 @@ public:    bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,                                 llvm::Value *Address) const; + +  unsigned getSizeOfUnwindException() const { +    return SizeOfUnwindException; +  }  };  } @@ -2934,6 +3101,11 @@ ABIArgInfo MipsABIInfo::classifyArgumentType(QualType Ty) const {      if (getContext().getTypeSize(Ty) == 0)        return ABIArgInfo::getIgnore(); +    // 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);    } @@ -2973,7 +3145,37 @@ void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const {  llvm::Value* MipsABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty,                                      CodeGenFunction &CGF) const { -  return 0; +  llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); +  llvm::Type *BPP = llvm::PointerType::getUnqual(BP); +  +  CGBuilderTy &Builder = CGF.Builder; +  llvm::Value *VAListAddrAsBPP = Builder.CreateBitCast(VAListAddr, BPP, "ap"); +  llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur"); +  unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8; +  llvm::Type *PTy = llvm::PointerType::getUnqual(CGF.ConvertType(Ty)); +  llvm::Value *AddrTyped; + +  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 *And = CGF.Builder.CreateAnd(Add, Mask); +    AddrTyped = CGF.Builder.CreateIntToPtr(And, PTy); +  } +  else +    AddrTyped = Builder.CreateBitCast(Addr, PTy);   + +  llvm::Value *AlignedAddr = Builder.CreateBitCast(AddrTyped, BP); +  TypeAlign = std::max(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), +                      "ap.next"); +  Builder.CreateStore(NextAddr, VAListAddrAsBPP); +   +  return AddrTyped;  }  bool @@ -2987,7 +3189,7 @@ MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,    // Everything on MIPS is 4 bytes.  Double-precision FP registers    // are aliased to pairs of single-precision FP registers. -  const llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context); +  llvm::IntegerType *i8 = llvm::Type::getInt8Ty(Context);    llvm::Value *Four8 = llvm::ConstantInt::get(i8, 4);    // 0-31 are the general purpose registers, $0 - $31. @@ -3009,29 +3211,98 @@ MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,    return false;  } +//===----------------------------------------------------------------------===// +// TCE ABI Implementation (see http://tce.cs.tut.fi). Uses mostly the defaults. +// Currently subclassed only to implement custom OpenCL C function attribute  +// handling. +//===----------------------------------------------------------------------===// + +namespace { + +class TCETargetCodeGenInfo : public DefaultTargetCodeGenInfo { +public: +  TCETargetCodeGenInfo(CodeGenTypes &CGT) +    : DefaultTargetCodeGenInfo(CGT) {} + +  virtual void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV, +                                   CodeGen::CodeGenModule &M) const; +}; + +void TCETargetCodeGenInfo::SetTargetAttributes(const Decl *D, +                                               llvm::GlobalValue *GV, +                                               CodeGen::CodeGenModule &M) const { +  const FunctionDecl *FD = dyn_cast<FunctionDecl>(D); +  if (!FD) return; + +  llvm::Function *F = cast<llvm::Function>(GV); +   +  if (M.getLangOptions().OpenCL) { +    if (FD->hasAttr<OpenCLKernelAttr>()) { +      // OpenCL C Kernel functions are not subject to inlining +      F->addFnAttr(llvm::Attribute::NoInline); +           +      if (FD->hasAttr<ReqdWorkGroupSizeAttr>()) { + +        // Convert the reqd_work_group_size() attributes to metadata. +        llvm::LLVMContext &Context = F->getContext(); +        llvm::NamedMDNode *OpenCLMetadata =  +            M.getModule().getOrInsertNamedMetadata("opencl.kernel_wg_size_info"); + +        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, +                               FD->getAttr<ReqdWorkGroupSizeAttr>()->getYDim()))); +        Operands.push_back(llvm::Constant::getIntegerValue( +                             llvm::Type::getInt32Ty(Context),  +                             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))); + +        OpenCLMetadata->addOperand(llvm::MDNode::get(Context, Operands)); +      } +    } +  } +} + +}  const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {    if (TheTargetCodeGenInfo)      return *TheTargetCodeGenInfo; -  // For now we just cache the TargetCodeGenInfo in CodeGenModule and don't -  // free it. - -  const llvm::Triple &Triple = getContext().Target.getTriple(); +  const llvm::Triple &Triple = getContext().getTargetInfo().getTriple();    switch (Triple.getArch()) {    default:      return *(TheTargetCodeGenInfo = new DefaultTargetCodeGenInfo(Types));    case llvm::Triple::mips:    case llvm::Triple::mipsel: -    return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types)); +    return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, 24)); + +  case llvm::Triple::mips64: +  case llvm::Triple::mips64el: +    return *(TheTargetCodeGenInfo = new MIPSTargetCodeGenInfo(Types, 32));    case llvm::Triple::arm:    case llvm::Triple::thumb:      {        ARMABIInfo::ABIKind Kind = ARMABIInfo::AAPCS; -      if (strcmp(getContext().Target.getABI(), "apcs-gnu") == 0) +      if (strcmp(getContext().getTargetInfo().getABI(), "apcs-gnu") == 0)          Kind = ARMABIInfo::APCS;        else if (CodeGenOpts.FloatABI == "hard")          Kind = ARMABIInfo::AAPCS_VFP; @@ -3055,8 +3326,11 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {    case llvm::Triple::msp430:      return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo(Types)); +  case llvm::Triple::tce: +    return *(TheTargetCodeGenInfo = new TCETargetCodeGenInfo(Types)); +    case llvm::Triple::x86: { -    bool DisableMMX = strcmp(getContext().Target.getABI(), "no-mmx") == 0; +    bool DisableMMX = strcmp(getContext().getTargetInfo().getABI(), "no-mmx") == 0;      if (Triple.isOSDarwin())        return *(TheTargetCodeGenInfo =  | 
