diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp | 129 |
1 files changed, 90 insertions, 39 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp index a2384456ea94..d87cf2d49720 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp @@ -45,6 +45,7 @@ #include "llvm/Support/CRC.h" #include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" + using namespace clang; using namespace CodeGen; @@ -78,7 +79,6 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) EHStack.setCGF(this); SetFastMathFlags(CurFPFeatures); - SetFPModel(); } CodeGenFunction::~CodeGenFunction() { @@ -109,17 +109,6 @@ clang::ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind) { llvm_unreachable("Unsupported FP Exception Behavior"); } -void CodeGenFunction::SetFPModel() { - llvm::RoundingMode RM = getLangOpts().getFPRoundingMode(); - auto fpExceptionBehavior = ToConstrainedExceptMD( - getLangOpts().getFPExceptionMode()); - - Builder.setDefaultConstrainedRounding(RM); - Builder.setDefaultConstrainedExcept(fpExceptionBehavior); - Builder.setIsFPConstrained(fpExceptionBehavior != llvm::fp::ebIgnore || - RM != llvm::RoundingMode::NearestTiesToEven); -} - void CodeGenFunction::SetFastMathFlags(FPOptions FPFeatures) { llvm::FastMathFlags FMF; FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate()); @@ -393,6 +382,9 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { "__cyg_profile_func_exit"); } + if (ShouldSkipSanitizerInstrumentation()) + CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation); + // Emit debug descriptor for function end. if (CGDebugInfo *DI = getDebugInfo()) DI->EmitFunctionEnd(Builder, CurFn); @@ -432,6 +424,14 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { AllocaInsertPt = nullptr; Ptr->eraseFromParent(); + // PostAllocaInsertPt, if created, was lazily created when it was required, + // remove it now since it was just created for our own convenience. + if (PostAllocaInsertPt) { + llvm::Instruction *PostPtr = PostAllocaInsertPt; + PostAllocaInsertPt = nullptr; + PostPtr->eraseFromParent(); + } + // If someone took the address of a label but never did an indirect goto, we // made a zero entry PHI node, which is illegal, zap it now. if (IndirectBranch) { @@ -496,11 +496,13 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { // function. CurFn->addFnAttr("min-legal-vector-width", llvm::utostr(LargestVectorWidth)); - // Add vscale attribute if appropriate. - if (getLangOpts().ArmSveVectorBits) { - unsigned VScale = getLangOpts().ArmSveVectorBits / 128; - CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(getLLVMContext(), - VScale, VScale)); + // Add vscale_range attribute if appropriate. + Optional<std::pair<unsigned, unsigned>> VScaleRange = + getContext().getTargetInfo().getVScaleRange(getLangOpts()); + if (VScaleRange) { + CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs( + getLLVMContext(), VScaleRange.getValue().first, + VScaleRange.getValue().second)); } // If we generated an unreachable return block, delete it now. @@ -529,6 +531,12 @@ bool CodeGenFunction::ShouldInstrumentFunction() { return true; } +bool CodeGenFunction::ShouldSkipSanitizerInstrumentation() { + if (!CurFuncDecl) + return false; + return CurFuncDecl->hasAttr<DisableSanitizerInstrumentationAttr>(); +} + /// ShouldXRayInstrument - Return true if the current function should be /// instrumented with XRay nop sleds. bool CodeGenFunction::ShouldXRayInstrumentFunction() const { @@ -947,10 +955,16 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, (getLangOpts().CUDA && FD->hasAttr<CUDAGlobalAttr>()))) Fn->addFnAttr(llvm::Attribute::NoRecurse); - if (FD) { - Builder.setIsFPConstrained(FD->hasAttr<StrictFPAttr>()); - if (FD->hasAttr<StrictFPAttr>()) - Fn->addFnAttr(llvm::Attribute::StrictFP); + llvm::RoundingMode RM = getLangOpts().getFPRoundingMode(); + llvm::fp::ExceptionBehavior FPExceptionBehavior = + ToConstrainedExceptMD(getLangOpts().getFPExceptionMode()); + Builder.setDefaultConstrainedRounding(RM); + Builder.setDefaultConstrainedExcept(FPExceptionBehavior); + if ((FD && (FD->UsesFPIntrin() || FD->hasAttr<StrictFPAttr>())) || + (!FD && (FPExceptionBehavior != llvm::fp::ebIgnore || + RM != llvm::RoundingMode::NearestTiesToEven))) { + Builder.setIsFPConstrained(true); + Fn->addFnAttr(llvm::Attribute::StrictFP); } // If a custom alignment is used, force realigning to this alignment on @@ -975,7 +989,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // precise source location of the checked return statement. if (requiresReturnValueCheck()) { ReturnLocation = CreateDefaultAlignTempAlloca(Int8PtrTy, "return.sloc.ptr"); - InitTempAlloca(ReturnLocation, llvm::ConstantPointerNull::get(Int8PtrTy)); + Builder.CreateStore(llvm::ConstantPointerNull::get(Int8PtrTy), + ReturnLocation); } // Emit subprogram debug descriptor. @@ -983,16 +998,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // Reconstruct the type from the argument list so that implicit parameters, // such as 'this' and 'vtt', show up in the debug info. Preserve the calling // convention. - CallingConv CC = CallingConv::CC_C; - if (FD) - if (const auto *SrcFnTy = FD->getType()->getAs<FunctionType>()) - CC = SrcFnTy->getCallConv(); - SmallVector<QualType, 16> ArgTypes; - for (const VarDecl *VD : Args) - ArgTypes.push_back(VD->getType()); - QualType FnType = getContext().getFunctionType( - RetTy, ArgTypes, FunctionProtoType::ExtProtoInfo(CC)); - DI->emitFunctionStart(GD, Loc, StartLoc, FnType, CurFn, CurFuncIsThunk); + DI->emitFunctionStart(GD, Loc, StartLoc, + DI->getFunctionType(FD, RetTy, Args), CurFn, + CurFuncIsThunk); } if (ShouldInstrumentFunction()) { @@ -1044,7 +1052,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, Fn->addFnAttr("packed-stack"); } - if (CGM.getCodeGenOpts().WarnStackSize != UINT_MAX) + if (CGM.getCodeGenOpts().WarnStackSize != UINT_MAX && + !CGM.getDiags().isIgnored(diag::warn_fe_backend_frame_larger_than, Loc)) Fn->addFnAttr("warn-stack-size", std::to_string(CGM.getCodeGenOpts().WarnStackSize)); @@ -1295,6 +1304,45 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, FunctionArgList Args; QualType ResTy = BuildFunctionArgList(GD, Args); + // When generating code for a builtin with an inline declaration, use a + // mangled name to hold the actual body, while keeping an external definition + // in case the function pointer is referenced somewhere. + if (Fn) { + if (FD->isInlineBuiltinDeclaration()) { + std::string FDInlineName = (Fn->getName() + ".inline").str(); + llvm::Module *M = Fn->getParent(); + llvm::Function *Clone = M->getFunction(FDInlineName); + if (!Clone) { + Clone = llvm::Function::Create(Fn->getFunctionType(), + llvm::GlobalValue::InternalLinkage, + Fn->getAddressSpace(), FDInlineName, M); + Clone->addFnAttr(llvm::Attribute::AlwaysInline); + } + Fn->setLinkage(llvm::GlobalValue::ExternalLinkage); + Fn = Clone; + } + + // Detect the unusual situation where an inline version is shadowed by a + // non-inline version. In that case we should pick the external one + // everywhere. That's GCC behavior too. Unfortunately, I cannot find a way + // to detect that situation before we reach codegen, so do some late + // replacement. + else { + for (const FunctionDecl *PD = FD->getPreviousDecl(); PD; + PD = PD->getPreviousDecl()) { + if (LLVM_UNLIKELY(PD->isInlineBuiltinDeclaration())) { + std::string FDInlineName = (Fn->getName() + ".inline").str(); + llvm::Module *M = Fn->getParent(); + if (llvm::Function *Clone = M->getFunction(FDInlineName)) { + Clone->replaceAllUsesWith(Fn); + Clone->eraseFromParent(); + } + break; + } + } + } + } + // Check if we should generate debug info for this function. if (FD->hasAttr<NoDebugAttr>()) { // Clear non-distinct debug info that was possibly attached to the function @@ -2399,15 +2447,19 @@ Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D, assert(D->hasAttr<AnnotateAttr>() && "no annotate attribute"); llvm::Value *V = Addr.getPointer(); llvm::Type *VTy = V->getType(); - llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation, - CGM.Int8PtrTy); + auto *PTy = dyn_cast<llvm::PointerType>(VTy); + unsigned AS = PTy ? PTy->getAddressSpace() : 0; + llvm::PointerType *IntrinTy = + llvm::PointerType::getWithSamePointeeType(CGM.Int8PtrTy, AS); + llvm::Function *F = + CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation, IntrinTy); for (const auto *I : D->specific_attrs<AnnotateAttr>()) { // FIXME Always emit the cast inst so we can differentiate between // annotation on the first field of a struct and annotation on the struct // itself. - if (VTy != CGM.Int8PtrTy) - V = Builder.CreateBitCast(V, CGM.Int8PtrTy); + if (VTy != IntrinTy) + V = Builder.CreateBitCast(V, IntrinTy); V = EmitAnnotationCall(F, V, I->getAnnotation(), D->getLocation(), I); V = Builder.CreateBitCast(V, VTy); } @@ -2478,8 +2530,7 @@ void CodeGenFunction::checkTargetFeatures(SourceLocation Loc, // Return if the builtin doesn't have any required features. if (FeatureList.empty()) return; - assert(FeatureList.find(' ') == StringRef::npos && - "Space in feature list"); + assert(!FeatureList.contains(' ') && "Space in feature list"); TargetFeatures TF(CallerFeatureMap); if (!TF.hasRequiredFeatures(FeatureList)) CGM.getDiags().Report(Loc, diag::err_builtin_needs_feature) |