diff options
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r-- | lib/CodeGen/CGCall.cpp | 128 |
1 files changed, 91 insertions, 37 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index fa51dc30c58b9..7d494bb1f1c76 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -23,11 +23,11 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/TargetBuiltins.h" #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/CodeGen/SwiftCallingConv.h" -#include "clang/Frontend/CodeGenOptions.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/Analysis/ValueTracking.h" @@ -59,6 +59,7 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) { case CC_X86Pascal: return llvm::CallingConv::C; // TODO: Add support for __vectorcall to LLVM. case CC_X86VectorCall: return llvm::CallingConv::X86_VectorCall; + case CC_AArch64VectorCall: return llvm::CallingConv::AArch64_VectorCall; case CC_SpirFunction: return llvm::CallingConv::SPIR_FUNC; case CC_OpenCLKernel: return CGM.getTargetCodeGenInfo().getOpenCLKernelCallingConv(); case CC_PreserveMost: return llvm::CallingConv::PreserveMost; @@ -67,11 +68,13 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) { } } -/// Derives the 'this' type for codegen purposes, i.e. ignoring method +/// Derives the 'this' type for codegen purposes, i.e. ignoring method CVR /// qualification. -/// FIXME: address space qualification? -static CanQualType GetThisType(ASTContext &Context, const CXXRecordDecl *RD) { +static CanQualType GetThisType(ASTContext &Context, const CXXRecordDecl *RD, + const CXXMethodDecl *MD) { QualType RecTy = Context.getTagDeclType(RD)->getCanonicalTypeInternal(); + if (MD) + RecTy = Context.getAddrSpaceQualType(RecTy, MD->getTypeQualifiers().getAddressSpace()); return Context.getPointerType(CanQualType::CreateUnsafe(RecTy)); } @@ -214,6 +217,9 @@ static CallingConv getCallingConventionForDecl(const Decl *D, bool IsWindows) { if (PcsAttr *PCS = D->getAttr<PcsAttr>()) return (PCS->getPCS() == PcsAttr::AAPCS ? CC_AAPCS : CC_AAPCS_VFP); + if (D->hasAttr<AArch64VectorPcsAttr>()) + return CC_AArch64VectorCall; + if (D->hasAttr<IntelOclBiccAttr>()) return CC_IntelOclBicc; @@ -246,7 +252,7 @@ CodeGenTypes::arrangeCXXMethodType(const CXXRecordDecl *RD, // Add the 'this' pointer. if (RD) - argTypes.push_back(GetThisType(Context, RD)); + argTypes.push_back(GetThisType(Context, RD, MD)); else argTypes.push_back(Context.VoidPtrTy); @@ -302,7 +308,7 @@ CodeGenTypes::arrangeCXXStructorDeclaration(const CXXMethodDecl *MD, SmallVector<CanQualType, 16> argTypes; SmallVector<FunctionProtoType::ExtParameterInfo, 16> paramInfos; - argTypes.push_back(GetThisType(Context, MD->getParent())); + argTypes.push_back(GetThisType(Context, MD->getParent(), MD)); bool PassParams = true; @@ -529,7 +535,7 @@ const CGFunctionInfo & CodeGenTypes::arrangeUnprototypedMustTailThunk(const CXXMethodDecl *MD) { assert(MD->isVirtual() && "only methods have thunks"); CanQual<FunctionProtoType> FTP = GetFormalType(MD); - CanQualType ArgTys[] = { GetThisType(Context, MD->getParent()) }; + CanQualType ArgTys[] = { GetThisType(Context, MD->getParent(), MD) }; return arrangeLLVMFunctionInfo(Context.VoidTy, /*instanceMethod=*/false, /*chainCall=*/false, ArgTys, FTP->getExtInfo(), {}, RequiredArgs(1)); @@ -543,7 +549,7 @@ CodeGenTypes::arrangeMSCtorClosure(const CXXConstructorDecl *CD, CanQual<FunctionProtoType> FTP = GetFormalType(CD); SmallVector<CanQualType, 2> ArgTys; const CXXRecordDecl *RD = CD->getParent(); - ArgTys.push_back(GetThisType(Context, RD)); + ArgTys.push_back(GetThisType(Context, RD, CD)); if (CT == Ctor_CopyingClosure) ArgTys.push_back(*FTP->param_type_begin()); if (RD->getNumVBases() > 0) @@ -741,8 +747,8 @@ CodeGenTypes::arrangeLLVMFunctionInfo(CanQualType resultType, FunctionType::ExtInfo info, ArrayRef<FunctionProtoType::ExtParameterInfo> paramInfos, RequiredArgs required) { - assert(std::all_of(argTypes.begin(), argTypes.end(), - [](CanQualType T) { return T.isCanonicalAsParam(); })); + assert(llvm::all_of(argTypes, + [](CanQualType T) { return T.isCanonicalAsParam(); })); // Lookup or create unique function info. llvm::FoldingSetNodeID ID; @@ -1253,8 +1259,8 @@ static llvm::Value *CreateCoercedLoad(Address Src, llvm::Type *Ty, // Otherwise do coercion through memory. This is stupid, but simple. Address Tmp = CreateTempAllocaForCoercion(CGF, Ty, Src.getAlignment()); - Address Casted = CGF.Builder.CreateBitCast(Tmp, CGF.AllocaInt8PtrTy); - Address SrcCasted = CGF.Builder.CreateBitCast(Src, CGF.AllocaInt8PtrTy); + Address Casted = CGF.Builder.CreateElementBitCast(Tmp,CGF.Int8Ty); + Address SrcCasted = CGF.Builder.CreateElementBitCast(Src,CGF.Int8Ty); CGF.Builder.CreateMemCpy(Casted, SrcCasted, llvm::ConstantInt::get(CGF.IntPtrTy, SrcSize), false); @@ -1335,8 +1341,8 @@ static void CreateCoercedStore(llvm::Value *Src, // to that information. Address Tmp = CreateTempAllocaForCoercion(CGF, SrcTy, Dst.getAlignment()); CGF.Builder.CreateStore(Src, Tmp); - Address Casted = CGF.Builder.CreateBitCast(Tmp, CGF.AllocaInt8PtrTy); - Address DstCasted = CGF.Builder.CreateBitCast(Dst, CGF.AllocaInt8PtrTy); + Address Casted = CGF.Builder.CreateElementBitCast(Tmp,CGF.Int8Ty); + Address DstCasted = CGF.Builder.CreateElementBitCast(Dst,CGF.Int8Ty); CGF.Builder.CreateMemCpy(DstCasted, Casted, llvm::ConstantInt::get(CGF.IntPtrTy, DstSize), false); @@ -1709,6 +1715,8 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone, if (CodeGenOpts.DisableRedZone) FuncAttrs.addAttribute(llvm::Attribute::NoRedZone); + if (CodeGenOpts.IndirectTlsSegRefs) + FuncAttrs.addAttribute("indirect-tls-seg-refs"); if (CodeGenOpts.NoImplicitFloat) FuncAttrs.addAttribute(llvm::Attribute::NoImplicitFloat); @@ -1784,6 +1792,11 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone, FuncAttrs.addAttribute("stackrealign"); if (CodeGenOpts.Backchain) FuncAttrs.addAttribute("backchain"); + + // FIXME: The interaction of this attribute with the SLH command line flag + // has not been determined. + if (CodeGenOpts.SpeculativeLoadHardening) + FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening); } if (getLangOpts().assumeFunctionsAreConvergent()) { @@ -1803,6 +1816,12 @@ void CodeGenModule::ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone, if (CodeGenOpts.FlushDenorm) FuncAttrs.addAttribute("nvptx-f32ftz", "true"); } + + for (StringRef Attr : CodeGenOpts.DefaultFunctionAttrs) { + StringRef Var, Value; + std::tie(Var, Value) = Attr.split('='); + FuncAttrs.addAttribute(Var, Value); + } } void CodeGenModule::AddDefaultFnAttrs(llvm::Function &F) { @@ -1828,7 +1847,7 @@ void CodeGenModule::ConstructAttributeList( AddAttributesFromFunctionProtoType(getContext(), FuncAttrs, CalleeInfo.getCalleeFunctionProtoType()); - const Decl *TargetDecl = CalleeInfo.getCalleeDecl(); + const Decl *TargetDecl = CalleeInfo.getCalleeDecl().getDecl(); bool HasOptnone = false; // FIXME: handle sseregparm someday... @@ -1845,6 +1864,8 @@ void CodeGenModule::ConstructAttributeList( FuncAttrs.addAttribute(llvm::Attribute::NoDuplicate); if (TargetDecl->hasAttr<ConvergentAttr>()) FuncAttrs.addAttribute(llvm::Attribute::Convergent); + if (TargetDecl->hasAttr<SpeculativeLoadHardeningAttr>()) + FuncAttrs.addAttribute(llvm::Attribute::SpeculativeLoadHardening); if (const FunctionDecl *Fn = dyn_cast<FunctionDecl>(TargetDecl)) { AddAttributesFromFunctionProtoType( @@ -1936,7 +1957,7 @@ void CodeGenModule::ConstructAttributeList( FuncAttrs.addAttribute("disable-tail-calls", llvm::toStringRef(DisableTailCalls)); - GetCPUAndFeaturesAttributes(TargetDecl, FuncAttrs); + GetCPUAndFeaturesAttributes(CalleeInfo.getCalleeDecl(), FuncAttrs); } ClangToLLVMArgMapping IRFunctionArgs(getContext(), FI); @@ -2327,7 +2348,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, } else { // Load scalar value from indirect argument. llvm::Value *V = - EmitLoadOfScalar(ParamAddr, false, Ty, Arg->getLocStart()); + EmitLoadOfScalar(ParamAddr, false, Ty, Arg->getBeginLoc()); if (isPromoted) V = emitArgumentDemotion(*this, Arg, V); @@ -2389,7 +2410,10 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, if (!AVAttr) if (const auto *TOTy = dyn_cast<TypedefType>(OTy)) AVAttr = TOTy->getDecl()->getAttr<AlignValueAttr>(); - if (AVAttr) { + if (AVAttr && !SanOpts.has(SanitizerKind::Alignment)) { + // If alignment-assumption sanitizer is enabled, we do *not* add + // alignment attribute here, but emit normal alignment assumption, + // so the UBSAN check could function. llvm::Value *AlignmentValue = EmitScalarExpr(AVAttr->getAlignment()); llvm::ConstantInt *AlignmentCI = @@ -2490,7 +2514,7 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, // Match to what EmitParmDecl is expecting for this type. if (CodeGenFunction::hasScalarEvaluationKind(Ty)) { llvm::Value *V = - EmitLoadOfScalar(Alloca, false, Ty, Arg->getLocStart()); + EmitLoadOfScalar(Alloca, false, Ty, Arg->getBeginLoc()); if (isPromoted) V = emitArgumentDemotion(*this, Arg, V); ArgVals.push_back(ParamValue::forDirect(V)); @@ -3063,8 +3087,9 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args, QualType type = param->getType(); - assert(!isInAllocaArgument(CGM.getCXXABI(), type) && - "cannot emit delegate call arguments for inalloca arguments!"); + if (isInAllocaArgument(CGM.getCXXABI(), type)) { + CGM.ErrorUnsupported(param, "forwarded non-trivially copyable parameter"); + } // GetAddrOfLocalVar returns a pointer-to-pointer for references, // but the argument needs to be the original pointer. @@ -3945,15 +3970,28 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, } else if (I->hasLValue()) { auto LV = I->getKnownLValue(); auto AS = LV.getAddressSpace(); + if ((!ArgInfo.getIndirectByVal() && (LV.getAlignment() >= - getContext().getTypeAlignInChars(I->Ty))) || - (ArgInfo.getIndirectByVal() && - ((AS != LangAS::Default && AS != LangAS::opencl_private && - AS != CGM.getASTAllocaAddressSpace())))) { + getContext().getTypeAlignInChars(I->Ty)))) { + NeedCopy = true; + } + if (!getLangOpts().OpenCL) { + if ((ArgInfo.getIndirectByVal() && + (AS != LangAS::Default && + AS != CGM.getASTAllocaAddressSpace()))) { + NeedCopy = true; + } + } + // For OpenCL even if RV is located in default or alloca address space + // we don't want to perform address space cast for it. + else if ((ArgInfo.getIndirectByVal() && + Addr.getType()->getAddressSpace() != IRFuncTy-> + getParamType(FirstIRArg)->getPointerAddressSpace())) { NeedCopy = true; } } + if (NeedCopy) { // Create an aligned temporary, and copy to it. Address AI = CreateMemTempWithoutCast( @@ -4235,6 +4273,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, } #endif + // Update the largest vector width if any arguments have vector types. + for (unsigned i = 0; i < IRCallArgs.size(); ++i) { + if (auto *VT = dyn_cast<llvm::VectorType>(IRCallArgs[i]->getType())) + LargestVectorWidth = std::max(LargestVectorWidth, + VT->getPrimitiveSizeInBits()); + } + // Compute the calling convention and attributes. unsigned CallingConv; llvm::AttributeList Attrs; @@ -4248,8 +4293,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // Apply always_inline to all calls within flatten functions. // FIXME: should this really take priority over __try, below? if (CurCodeDecl && CurCodeDecl->hasAttr<FlattenAttr>() && - !(Callee.getAbstractInfo().getCalleeDecl() && - Callee.getAbstractInfo().getCalleeDecl()->hasAttr<NoInlineAttr>())) { + !(Callee.getAbstractInfo().getCalleeDecl().getDecl() && + Callee.getAbstractInfo() + .getCalleeDecl() + .getDecl() + ->hasAttr<NoInlineAttr>())) { Attrs = Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex, llvm::Attribute::AlwaysInline); @@ -4315,6 +4363,11 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, if (!CI->getType()->isVoidTy()) CI->setName("call"); + // Update largest vector width from the return type. + if (auto *VT = dyn_cast<llvm::VectorType>(CI->getType())) + LargestVectorWidth = std::max(LargestVectorWidth, + VT->getPrimitiveSizeInBits()); + // Insert instrumentation or attach profile metadata at indirect call sites. // For more details, see the comment before the definition of // IPVK_IndirectCallTarget in InstrProfData.inc. @@ -4329,7 +4382,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, // Suppress tail calls if requested. if (llvm::CallInst *Call = dyn_cast<llvm::CallInst>(CI)) { - const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl(); + const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl(); if (TargetDecl && TargetDecl->hasAttr<NotTailCalledAttr>()) Call->setTailCallKind(llvm::CallInst::TCK_NoTail); } @@ -4476,7 +4529,7 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, } (); // Emit the assume_aligned check on the return value. - const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl(); + const Decl *TargetDecl = Callee.getAbstractInfo().getCalleeDecl().getDecl(); if (Ret.isScalar() && TargetDecl) { if (const auto *AA = TargetDecl->getAttr<AssumeAlignedAttr>()) { llvm::Value *OffsetValue = nullptr; @@ -4485,13 +4538,14 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, llvm::Value *Alignment = EmitScalarExpr(AA->getAlignment()); llvm::ConstantInt *AlignmentCI = cast<llvm::ConstantInt>(Alignment); - EmitAlignmentAssumption(Ret.getScalarVal(), AlignmentCI->getZExtValue(), - OffsetValue); + EmitAlignmentAssumption(Ret.getScalarVal(), RetTy, Loc, AA->getLocation(), + AlignmentCI->getZExtValue(), OffsetValue); } else if (const auto *AA = TargetDecl->getAttr<AllocAlignAttr>()) { - llvm::Value *ParamVal = - CallArgs[AA->getParamIndex().getLLVMIndex()].getRValue( - *this).getScalarVal(); - EmitAlignmentAssumption(Ret.getScalarVal(), ParamVal); + llvm::Value *AlignmentVal = CallArgs[AA->getParamIndex().getLLVMIndex()] + .getRValue(*this) + .getScalarVal(); + EmitAlignmentAssumption(Ret.getScalarVal(), RetTy, Loc, AA->getLocation(), + AlignmentVal); } } @@ -4502,8 +4556,8 @@ CGCallee CGCallee::prepareConcreteCallee(CodeGenFunction &CGF) const { if (isVirtual()) { const CallExpr *CE = getVirtualCallExpr(); return CGF.CGM.getCXXABI().getVirtualFunctionPointer( - CGF, getVirtualMethodDecl(), getThisAddress(), - getFunctionType(), CE ? CE->getLocStart() : SourceLocation()); + CGF, getVirtualMethodDecl(), getThisAddress(), getFunctionType(), + CE ? CE->getBeginLoc() : SourceLocation()); } return *this; |