diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp')
| -rw-r--r-- | contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp | 195 |
1 files changed, 146 insertions, 49 deletions
diff --git a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp index eafe26674434..648e6d9c214a 100644 --- a/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp @@ -12,9 +12,9 @@ #include "CodeGenFunction.h" #include "CGBlocks.h" -#include "CGCleanup.h" #include "CGCUDARuntime.h" #include "CGCXXABI.h" +#include "CGCleanup.h" #include "CGDebugInfo.h" #include "CGOpenMPRuntime.h" #include "CodeGenModule.h" @@ -22,6 +22,7 @@ #include "TargetInfo.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTLambda.h" +#include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/StmtCXX.h" @@ -33,6 +34,8 @@ #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/FPEnv.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Operator.h" @@ -47,13 +50,10 @@ static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts, if (CGOpts.DisableLifetimeMarkers) return false; - // Disable lifetime markers in msan builds. - // FIXME: Remove this when msan works with lifetime markers. - if (LangOpts.Sanitize.has(SanitizerKind::Memory)) - return false; - - // Asan uses markers for use-after-scope checks. - if (CGOpts.SanitizeAddressUseAfterScope) + // Sanitizers may use markers. + if (CGOpts.SanitizeAddressUseAfterScope || + LangOpts.Sanitize.has(SanitizerKind::HWAddress) || + LangOpts.Sanitize.has(SanitizerKind::Memory)) return true; // For now, only in optimized builds. @@ -90,6 +90,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) FMF.setAllowReassoc(); } Builder.setFastMathFlags(FMF); + SetFPModel(); } CodeGenFunction::~CodeGenFunction() { @@ -105,6 +106,51 @@ CodeGenFunction::~CodeGenFunction() { CGM.getOpenMPRuntime().functionFinished(*this); } +// Map the LangOption for rounding mode into +// the corresponding enum in the IR. +static llvm::fp::RoundingMode ToConstrainedRoundingMD( + LangOptions::FPRoundingModeKind Kind) { + + switch (Kind) { + case LangOptions::FPR_ToNearest: return llvm::fp::rmToNearest; + case LangOptions::FPR_Downward: return llvm::fp::rmDownward; + case LangOptions::FPR_Upward: return llvm::fp::rmUpward; + case LangOptions::FPR_TowardZero: return llvm::fp::rmTowardZero; + case LangOptions::FPR_Dynamic: return llvm::fp::rmDynamic; + } + llvm_unreachable("Unsupported FP RoundingMode"); +} + +// Map the LangOption for exception behavior into +// the corresponding enum in the IR. +static llvm::fp::ExceptionBehavior ToConstrainedExceptMD( + LangOptions::FPExceptionModeKind Kind) { + + switch (Kind) { + case LangOptions::FPE_Ignore: return llvm::fp::ebIgnore; + case LangOptions::FPE_MayTrap: return llvm::fp::ebMayTrap; + case LangOptions::FPE_Strict: return llvm::fp::ebStrict; + } + llvm_unreachable("Unsupported FP Exception Behavior"); +} + +void CodeGenFunction::SetFPModel() { + auto fpRoundingMode = ToConstrainedRoundingMD( + getLangOpts().getFPRoundingMode()); + auto fpExceptionBehavior = ToConstrainedExceptMD( + getLangOpts().getFPExceptionMode()); + + if (fpExceptionBehavior == llvm::fp::ebIgnore && + fpRoundingMode == llvm::fp::rmToNearest) + // Constrained intrinsics are not used. + ; + else { + Builder.setIsFPConstrained(true); + Builder.setDefaultConstrainedRounding(fpRoundingMode); + Builder.setDefaultConstrainedExcept(fpExceptionBehavior); + } +} + CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment(QualType T, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo) { @@ -197,7 +243,7 @@ TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) { #define NON_CANONICAL_TYPE(name, parent) case Type::name: #define DEPENDENT_TYPE(name, parent) case Type::name: #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name: -#include "clang/AST/TypeNodes.def" +#include "clang/AST/TypeNodes.inc" llvm_unreachable("non-canonical or dependent type in IR-generation"); case Type::Auto: @@ -332,9 +378,15 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { if (HasCleanups) { // Make sure the line table doesn't jump back into the body for // the ret after it's been at EndLoc. - if (CGDebugInfo *DI = getDebugInfo()) + Optional<ApplyDebugLocation> AL; + if (CGDebugInfo *DI = getDebugInfo()) { if (OnlySimpleReturnStmts) DI->EmitLocation(Builder, EndLoc); + else + // We may not have a valid end location. Try to apply it anyway, and + // fall back to an artificial location if needed. + AL = ApplyDebugLocation::CreateDefaultArtificial(*this, EndLoc); + } PopCleanupBlocks(PrologueCleanupDepth); } @@ -434,13 +486,13 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { // Scan function arguments for vector width. for (llvm::Argument &A : CurFn->args()) if (auto *VT = dyn_cast<llvm::VectorType>(A.getType())) - LargestVectorWidth = std::max(LargestVectorWidth, - VT->getPrimitiveSizeInBits()); + LargestVectorWidth = std::max((uint64_t)LargestVectorWidth, + VT->getPrimitiveSizeInBits().getFixedSize()); // Update vector width based on return type. if (auto *VT = dyn_cast<llvm::VectorType>(CurFn->getReturnType())) - LargestVectorWidth = std::max(LargestVectorWidth, - VT->getPrimitiveSizeInBits()); + LargestVectorWidth = std::max((uint64_t)LargestVectorWidth, + VT->getPrimitiveSizeInBits().getFixedSize()); // Add the required-vector-width attribute. This contains the max width from: // 1. min-vector-width attribute used in the source program. @@ -609,6 +661,13 @@ void CodeGenFunction::markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn) { } } +/// Check if the return value of this function requires sanitization. +bool CodeGenFunction::requiresReturnValueCheck() const { + return requiresReturnValueNullabilityCheck() || + (SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) && CurCodeDecl && + CurCodeDecl->getAttr<ReturnsNonNullAttr>()); +} + static bool matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx) { auto *MD = dyn_cast_or_null<CXXMethodDecl>(D); if (!MD || !MD->getDeclName().getAsIdentifierInfo() || @@ -638,8 +697,7 @@ static llvm::Constant *getPrologueSignature(CodeGenModule &CGM, return CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM); } -void CodeGenFunction::StartFunction(GlobalDecl GD, - QualType RetTy, +void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, @@ -732,8 +790,17 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, SanOpts.Mask &= ~SanitizerKind::CFIUnrelatedCast; } - // Apply xray attributes to the function (as a string, for now) + // Ignore null checks in coroutine functions since the coroutines passes + // are not aware of how to move the extra UBSan instructions across the split + // coroutine boundaries. + if (D && SanOpts.has(SanitizerKind::Null)) + if (const auto *FD = dyn_cast<FunctionDecl>(D)) + if (FD->getBody() && + FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass) + SanOpts.Mask &= ~SanitizerKind::Null; + if (D) { + // Apply xray attributes to the function (as a string, for now) if (const auto *XRayAttr = D->getAttr<XRayInstrumentAttr>()) { if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has( XRayInstrKind::Function)) { @@ -752,16 +819,37 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, "xray-instruction-threshold", llvm::itostr(CGM.getCodeGenOpts().XRayInstructionThreshold)); } + + unsigned Count, Offset; + if (const auto *Attr = D->getAttr<PatchableFunctionEntryAttr>()) { + Count = Attr->getCount(); + Offset = Attr->getOffset(); + } else { + Count = CGM.getCodeGenOpts().PatchableFunctionEntryCount; + Offset = CGM.getCodeGenOpts().PatchableFunctionEntryOffset; + } + if (Count && Offset <= Count) { + Fn->addFnAttr("patchable-function-entry", std::to_string(Count - Offset)); + if (Offset) + Fn->addFnAttr("patchable-function-prefix", std::to_string(Offset)); + } } // Add no-jump-tables value. Fn->addFnAttr("no-jump-tables", llvm::toStringRef(CGM.getCodeGenOpts().NoUseJumpTables)); + // Add no-inline-line-tables value. + if (CGM.getCodeGenOpts().NoInlineLineTables) + Fn->addFnAttr("no-inline-line-tables"); + // Add profile-sample-accurate value. if (CGM.getCodeGenOpts().ProfileSampleAccurate) Fn->addFnAttr("profile-sample-accurate"); + if (D && D->hasAttr<CFICanonicalJumpTableAttr>()) + Fn->addFnAttr("cfi-canonical-jump-table"); + if (getLangOpts().OpenCL) { // Add metadata for a kernel function. if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) @@ -811,6 +899,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, if (FD->isMain()) Fn->addFnAttr(llvm::Attribute::NoRecurse); + if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) + if (FD->usesFPIntrin()) + Fn->addFnAttr(llvm::Attribute::StrictFP); + // If a custom alignment is used, force realigning to this alignment on // any main function which certainly will need it. if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) @@ -880,9 +972,30 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, Fn->addFnAttr("instrument-function-entry-inlined", getTarget().getMCountName()); } + if (CGM.getCodeGenOpts().MNopMCount) { + if (!CGM.getCodeGenOpts().CallFEntry) + CGM.getDiags().Report(diag::err_opt_not_valid_without_opt) + << "-mnop-mcount" << "-mfentry"; + Fn->addFnAttr("mnop-mcount"); + } + + if (CGM.getCodeGenOpts().RecordMCount) { + if (!CGM.getCodeGenOpts().CallFEntry) + CGM.getDiags().Report(diag::err_opt_not_valid_without_opt) + << "-mrecord-mcount" << "-mfentry"; + Fn->addFnAttr("mrecord-mcount"); + } } } + if (CGM.getCodeGenOpts().PackedStack) { + if (getContext().getTargetInfo().getTriple().getArch() != + llvm::Triple::systemz) + CGM.getDiags().Report(diag::err_opt_not_valid_on_target) + << "-mpacked-stack"; + Fn->addFnAttr("packed-stack"); + } + if (RetTy->isVoidType()) { // Void type; nothing to return. ReturnValue = Address::invalid(); @@ -954,7 +1067,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, LValue ThisFieldLValue = EmitLValueForLambdaField(LambdaThisCaptureField); if (!LambdaThisCaptureField->getType()->isPointerType()) { // If the enclosing object was captured by value, just use its address. - CXXThisValue = ThisFieldLValue.getAddress().getPointer(); + CXXThisValue = ThisFieldLValue.getAddress(*this).getPointer(); } else { // Load the lvalue pointed to by the field, since '*this' was captured // by reference. @@ -1662,7 +1775,7 @@ CodeGenFunction::EmitNullInitialization(Address DestPtr, QualType Ty) { llvm::GlobalVariable::PrivateLinkage, NullConstant, Twine()); CharUnits NullAlign = DestPtr.getAlignment(); - NullVariable->setAlignment(NullAlign.getQuantity()); + NullVariable->setAlignment(NullAlign.getAsAlign()); Address SrcPtr(Builder.CreateBitCast(NullVariable, Builder.getInt8PtrTy()), NullAlign); @@ -1862,7 +1975,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { #define NON_CANONICAL_TYPE(Class, Base) #define DEPENDENT_TYPE(Class, Base) case Type::Class: #define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base) -#include "clang/AST/TypeNodes.def" +#include "clang/AST/TypeNodes.inc" llvm_unreachable("unexpected dependent type!"); // These types are never variably-modified. @@ -1991,18 +2104,18 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { Address CodeGenFunction::EmitVAListRef(const Expr* E) { if (getContext().getBuiltinVaListType()->isArrayType()) return EmitPointerWithAlignment(E); - return EmitLValue(E).getAddress(); + return EmitLValue(E).getAddress(*this); } Address CodeGenFunction::EmitMSVAListRef(const Expr *E) { - return EmitLValue(E).getAddress(); + return EmitLValue(E).getAddress(*this); } void CodeGenFunction::EmitDeclRefExprDbgValue(const DeclRefExpr *E, const APValue &Init) { assert(Init.hasValue() && "Invalid DeclRefExpr initializer!"); if (CGDebugInfo *Dbg = getDebugInfo()) - if (CGM.getCodeGenOpts().getDebugInfo() >= codegenoptions::LimitedDebugInfo) + if (CGM.getCodeGenOpts().hasReducedDebugInfo()) Dbg->EmitGlobalVariable(E->getDecl(), Init); } @@ -2048,24 +2161,9 @@ void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue, } void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue, - QualType Ty, SourceLocation Loc, - SourceLocation AssumptionLoc, - unsigned Alignment, - llvm::Value *OffsetValue) { - llvm::Value *TheCheck; - llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption( - CGM.getDataLayout(), PtrValue, Alignment, OffsetValue, &TheCheck); - if (SanOpts.has(SanitizerKind::Alignment)) { - llvm::Value *AlignmentVal = llvm::ConstantInt::get(IntPtrTy, Alignment); - EmitAlignmentAssumptionCheck(PtrValue, Ty, Loc, AssumptionLoc, AlignmentVal, - OffsetValue, TheCheck, Assumption); - } -} - -void CodeGenFunction::EmitAlignmentAssumption(llvm::Value *PtrValue, const Expr *E, SourceLocation AssumptionLoc, - unsigned Alignment, + llvm::Value *Alignment, llvm::Value *OffsetValue) { if (auto *CE = dyn_cast<CastExpr>(E)) E = CE->getSubExprAsWritten(); @@ -2159,7 +2257,7 @@ static bool hasRequiredFeatures(const SmallVectorImpl<StringRef> &ReqFeatures, // Now build up the set of caller features and verify that all the required // features are there. llvm::StringMap<bool> CallerFeatureMap; - CGM.getFunctionFeatureMap(CallerFeatureMap, GlobalDecl().getWithDecl(FD)); + CGM.getContext().getFunctionFeatureMap(CallerFeatureMap, FD); // If we have at least one of the features in the feature list return // true, otherwise return false. @@ -2194,7 +2292,7 @@ void CodeGenFunction::checkTargetFeatures(SourceLocation Loc, // Get the current enclosing function if it exists. If it doesn't // we can't check the target features anyhow. - const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl); + const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurCodeDecl); if (!FD) return; @@ -2216,16 +2314,18 @@ void CodeGenFunction::checkTargetFeatures(SourceLocation Loc, << TargetDecl->getDeclName() << CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID); - } else if (TargetDecl->hasAttr<TargetAttr>() || - TargetDecl->hasAttr<CPUSpecificAttr>()) { + } else if (!TargetDecl->isMultiVersion() && + TargetDecl->hasAttr<TargetAttr>()) { // Get the required features for the callee. const TargetAttr *TD = TargetDecl->getAttr<TargetAttr>(); - TargetAttr::ParsedTargetAttr ParsedAttr = CGM.filterFunctionTargetAttrs(TD); + ParsedTargetAttr ParsedAttr = + CGM.getContext().filterFunctionTargetAttrs(TD); SmallVector<StringRef, 1> ReqFeatures; llvm::StringMap<bool> CalleeFeatureMap; - CGM.getFunctionFeatureMap(CalleeFeatureMap, TargetDecl); + CGM.getContext().getFunctionFeatureMap(CalleeFeatureMap, + GlobalDecl(TargetDecl)); for (const auto &F : ParsedAttr.Features) { if (F[0] == '+' && CalleeFeatureMap.lookup(F.substr(1))) @@ -2292,10 +2392,7 @@ static void CreateMultiVersionResolverReturn(CodeGenModule &CGM, void CodeGenFunction::EmitMultiVersionResolver( llvm::Function *Resolver, ArrayRef<MultiVersionResolverOption> Options) { - assert((getContext().getTargetInfo().getTriple().getArch() == - llvm::Triple::x86 || - getContext().getTargetInfo().getTriple().getArch() == - llvm::Triple::x86_64) && + assert(getContext().getTargetInfo().getTriple().isX86() && "Only implemented for x86 targets"); bool SupportsIFunc = getContext().getTargetInfo().supportsIFunc(); |
