diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-07-29 20:15:26 +0000 |
commit | 344a3780b2e33f6ca763666c380202b18aab72a3 (patch) | |
tree | f0b203ee6eb71d7fdd792373e3c81eb18d6934dd /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) |
vendor/llvm-project/llvmorg-13-init-16847-g88e66fa60ae5vendor/llvm-project/llvmorg-12.0.1-rc2-0-ge7dac564cd0evendor/llvm-project/llvmorg-12.0.1-0-gfed41342a82f
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 258 |
1 files changed, 138 insertions, 120 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index b393c88f7751..a2384456ea94 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -75,6 +75,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) shouldEmitLifetimeMarkers(CGM.getCodeGenOpts(), CGM.getLangOpts())) { if (!suppressNewContext) CGM.getCXXABI().getMangleContext().startNewFunction(); + EHStack.setCGF(this); SetFastMathFlags(CurFPFeatures); SetFPModel(); @@ -91,8 +92,8 @@ CodeGenFunction::~CodeGenFunction() { // seems to be a reasonable spot. We do it here, as opposed to the deletion // time of the CodeGenModule, because we have to ensure the IR has not yet // been "emitted" to the outside, thus, modifications are still sensible. - if (CGM.getLangOpts().OpenMPIRBuilder) - CGM.getOpenMPRuntime().getOMPBuilder().finalize(); + if (CGM.getLangOpts().OpenMPIRBuilder && CurFn) + CGM.getOpenMPRuntime().getOMPBuilder().finalize(CurFn); } // Map the LangOption for exception behavior into @@ -174,7 +175,7 @@ void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(FPOptions FPFeatures) { auto mergeFnAttrValue = [&](StringRef Name, bool Value) { auto OldValue = - CGF.CurFn->getFnAttribute(Name).getValueAsString() == "true"; + CGF.CurFn->getFnAttribute(Name).getValueAsBool(); auto NewValue = OldValue & Value; if (OldValue != NewValue) CGF.CurFn->addFnAttr(Name, llvm::toStringRef(NewValue)); @@ -452,13 +453,13 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { if (CGM.getCodeGenOpts().EmitDeclMetadata) EmitDeclMetadata(); - for (SmallVectorImpl<std::pair<llvm::Instruction *, llvm::Value *> >::iterator - I = DeferredReplacements.begin(), - E = DeferredReplacements.end(); - I != E; ++I) { - I->first->replaceAllUsesWith(I->second); - I->first->eraseFromParent(); + for (const auto &R : DeferredReplacements) { + if (llvm::Value *Old = R.first) { + Old->replaceAllUsesWith(R.second); + cast<llvm::Instruction>(Old)->eraseFromParent(); + } } + DeferredReplacements.clear(); // Eliminate CleanupDestSlot alloca by replacing it with SSA values and // PHIs if the current function is a coroutine. We don't do it for all @@ -495,6 +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)); + } + // If we generated an unreachable return block, delete it now. if (ReturnBlock.isValid() && ReturnBlock.getBlock()->use_empty()) { Builder.ClearInsertionPoint(); @@ -702,23 +710,23 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, DidCallStackSave = false; CurCodeDecl = D; - if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) - if (FD->usesSEHTry()) - CurSEHParent = FD; + const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D); + if (FD && FD->usesSEHTry()) + CurSEHParent = FD; CurFuncDecl = (D ? D->getNonClosureContext() : nullptr); FnRetTy = RetTy; CurFn = Fn; CurFnInfo = &FnInfo; assert(CurFn->isDeclaration() && "Function already has body?"); - // If this function has been blacklisted for any of the enabled sanitizers, + // If this function is ignored for any of the enabled sanitizers, // disable the sanitizer for the function. do { #define SANITIZER(NAME, ID) \ if (SanOpts.empty()) \ break; \ if (SanOpts.has(SanitizerKind::ID)) \ - if (CGM.isInSanitizerBlacklist(SanitizerKind::ID, Fn, Loc)) \ + if (CGM.isInNoSanitizeList(SanitizerKind::ID, Fn, Loc)) \ SanOpts.set(SanitizerKind::ID, false); #include "clang/Basic/Sanitizers.def" @@ -726,8 +734,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, } while (0); if (D) { - // Apply the no_sanitize* attributes to SanOpts. + bool NoSanitizeCoverage = false; + for (auto Attr : D->specific_attrs<NoSanitizeAttr>()) { + // Apply the no_sanitize* attributes to SanOpts. SanitizerMask mask = Attr->getMask(); SanOpts.Mask &= ~mask; if (mask & SanitizerKind::Address) @@ -738,7 +748,14 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, SanOpts.set(SanitizerKind::KernelHWAddress, false); if (mask & SanitizerKind::KernelHWAddress) SanOpts.set(SanitizerKind::HWAddress, false); + + // SanitizeCoverage is not handled by SanOpts. + if (Attr->hasCoverage()) + NoSanitizeCoverage = true; } + + if (NoSanitizeCoverage && CGM.getCodeGenOpts().hasSanitizeCoverage()) + Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage); } // Apply sanitizer attributes to the function. @@ -786,10 +803,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // 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 (FD && FD->getBody() && + FD->getBody()->getStmtClass() == Stmt::CoroutineBodyStmtClass) + SanOpts.Mask &= ~SanitizerKind::Null; // Apply xray attributes to the function (as a string, for now) bool AlwaysXRayAttr = false; @@ -859,8 +875,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, } // Add no-jump-tables value. - Fn->addFnAttr("no-jump-tables", - llvm::toStringRef(CGM.getCodeGenOpts().NoUseJumpTables)); + if (CGM.getCodeGenOpts().NoUseJumpTables) + Fn->addFnAttr("no-jump-tables", "true"); // Add no-inline-line-tables value. if (CGM.getCodeGenOpts().NoInlineLineTables) @@ -876,32 +892,30 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (D && D->hasAttr<CFICanonicalJumpTableAttr>()) Fn->addFnAttr("cfi-canonical-jump-table"); - if (getLangOpts().OpenCL) { + if (D && D->hasAttr<NoProfileFunctionAttr>()) + Fn->addFnAttr(llvm::Attribute::NoProfile); + + if (FD && getLangOpts().OpenCL) { // Add metadata for a kernel function. - if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) - EmitOpenCLKernelMetadata(FD, Fn); + EmitOpenCLKernelMetadata(FD, Fn); } // If we are checking function types, emit a function type signature as // prologue data. - if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function)) { - if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { - if (llvm::Constant *PrologueSig = getPrologueSignature(CGM, FD)) { - // Remove any (C++17) exception specifications, to allow calling e.g. a - // noexcept function through a non-noexcept pointer. - auto ProtoTy = - getContext().getFunctionTypeWithExceptionSpec(FD->getType(), - EST_None); - llvm::Constant *FTRTTIConst = - CGM.GetAddrOfRTTIDescriptor(ProtoTy, /*ForEH=*/true); - llvm::Constant *FTRTTIConstEncoded = - EncodeAddrForUseInPrologue(Fn, FTRTTIConst); - llvm::Constant *PrologueStructElems[] = {PrologueSig, - FTRTTIConstEncoded}; - llvm::Constant *PrologueStructConst = - llvm::ConstantStruct::getAnon(PrologueStructElems, /*Packed=*/true); - Fn->setPrologueData(PrologueStructConst); - } + if (FD && getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function)) { + if (llvm::Constant *PrologueSig = getPrologueSignature(CGM, FD)) { + // Remove any (C++17) exception specifications, to allow calling e.g. a + // noexcept function through a non-noexcept pointer. + auto ProtoTy = getContext().getFunctionTypeWithExceptionSpec( + FD->getType(), EST_None); + llvm::Constant *FTRTTIConst = + CGM.GetAddrOfRTTIDescriptor(ProtoTy, /*ForEH=*/true); + llvm::Constant *FTRTTIConstEncoded = + EncodeAddrForUseInPrologue(Fn, FTRTTIConst); + llvm::Constant *PrologueStructElems[] = {PrologueSig, FTRTTIConstEncoded}; + llvm::Constant *PrologueStructConst = + llvm::ConstantStruct::getAnon(PrologueStructElems, /*Packed=*/true); + Fn->setPrologueData(PrologueStructConst); } } @@ -928,14 +942,12 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // kernels cannot include RTTI information, exception classes, // recursive code, virtual functions or make use of C++ libraries that // are not compiled for the device. - if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { - if ((getLangOpts().CPlusPlus && FD->isMain()) || getLangOpts().OpenCL || - getLangOpts().SYCLIsDevice || - (getLangOpts().CUDA && FD->hasAttr<CUDAGlobalAttr>())) - Fn->addFnAttr(llvm::Attribute::NoRecurse); - } + if (FD && ((getLangOpts().CPlusPlus && FD->isMain()) || + getLangOpts().OpenCL || getLangOpts().SYCLIsDevice || + (getLangOpts().CUDA && FD->hasAttr<CUDAGlobalAttr>()))) + Fn->addFnAttr(llvm::Attribute::NoRecurse); - if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { + if (FD) { Builder.setIsFPConstrained(FD->hasAttr<StrictFPAttr>()); if (FD->hasAttr<StrictFPAttr>()) Fn->addFnAttr(llvm::Attribute::StrictFP); @@ -943,10 +955,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // 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)) - if ((FD->isMain() || FD->isMSVCRTEntryPoint()) && - CGM.getCodeGenOpts().StackAlignment) - Fn->addFnAttr("stackrealign"); + if (FD && ((FD->isMain() || FD->isMSVCRTEntryPoint()) && + CGM.getCodeGenOpts().StackAlignment)) + Fn->addFnAttr("stackrealign"); llvm::BasicBlock *EntryBB = createBasicBlock("entry", CurFn); @@ -973,7 +984,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // such as 'this' and 'vtt', show up in the debug info. Preserve the calling // convention. CallingConv CC = CallingConv::CC_C; - if (auto *FD = dyn_cast_or_null<FunctionDecl>(D)) + if (FD) if (const auto *SrcFnTy = FD->getType()->getAs<FunctionType>()) CC = SrcFnTy->getCallConv(); SmallVector<QualType, 16> ArgTypes; @@ -1033,6 +1044,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, Fn->addFnAttr("packed-stack"); } + if (CGM.getCodeGenOpts().WarnStackSize != UINT_MAX) + Fn->addFnAttr("warn-stack-size", + std::to_string(CGM.getCodeGenOpts().WarnStackSize)); + if (RetTy->isVoidType()) { // Void type; nothing to return. ReturnValue = Address::invalid(); @@ -1060,9 +1075,12 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, unsigned Idx = CurFnInfo->getReturnInfo().getInAllocaFieldIndex(); llvm::Function::arg_iterator EI = CurFn->arg_end(); --EI; - llvm::Value *Addr = Builder.CreateStructGEP(nullptr, &*EI, Idx); + llvm::Value *Addr = Builder.CreateStructGEP( + EI->getType()->getPointerElementType(), &*EI, Idx); + llvm::Type *Ty = + cast<llvm::GetElementPtrInst>(Addr)->getResultElementType(); ReturnValuePointer = Address(Addr, getPointerAlign()); - Addr = Builder.CreateAlignedLoad(Addr, getPointerAlign(), "agg.result"); + Addr = Builder.CreateAlignedLoad(Ty, Addr, getPointerAlign(), "agg.result"); ReturnValue = Address(Addr, CGM.getNaturalTypeAlignment(RetTy)); } else { ReturnValue = CreateIRTemp(RetTy, "retval"); @@ -1177,9 +1195,6 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { incrementProfileCounter(Body); - if (CPlusPlusWithProgress()) - FnIsMustProgress = true; - if (const CompoundStmt *S = dyn_cast<CompoundStmt>(Body)) EmitCompoundStmtWithoutScope(*S); else @@ -1187,7 +1202,7 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { // This is checked after emitting the function body so we know if there // are any permitted infinite loops. - if (FnIsMustProgress) + if (checkIfFunctionMustProgress()) CurFn->addFnAttr(llvm::Attribute::MustProgress); } @@ -1272,19 +1287,6 @@ QualType CodeGenFunction::BuildFunctionArgList(GlobalDecl GD, return ResTy; } -static bool -shouldUseUndefinedBehaviorReturnOptimization(const FunctionDecl *FD, - const ASTContext &Context) { - QualType T = FD->getReturnType(); - // Avoid the optimization for functions that return a record type with a - // trivial destructor or another trivially copyable type. - if (const RecordType *RT = T.getCanonicalType()->getAs<RecordType>()) { - if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) - return !ClassDecl->hasTrivialDestructor(); - } - return !T.isTriviallyCopyableType(Context); -} - void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, const CGFunctionInfo &FnInfo) { const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl()); @@ -1294,8 +1296,14 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, QualType ResTy = BuildFunctionArgList(GD, Args); // Check if we should generate debug info for this function. - if (FD->hasAttr<NoDebugAttr>()) - DebugInfo = nullptr; // disable debug info indefinitely for this function + if (FD->hasAttr<NoDebugAttr>()) { + // Clear non-distinct debug info that was possibly attached to the function + // due to an earlier declaration without the nodebug attribute + if (Fn) + Fn->setSubprogram(nullptr); + // Disable debug info indefinitely for this function + DebugInfo = nullptr; + } // The function might not have a body if we're generating thunks for a // function declaration. @@ -1321,14 +1329,25 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, Stmt *Body = FD->getBody(); - // Initialize helper which will detect jumps which can cause invalid lifetime - // markers. - if (Body && ShouldEmitLifetimeMarkers) - Bypasses.Init(Body); + if (Body) { + // Coroutines always emit lifetime markers. + if (isa<CoroutineBodyStmt>(Body)) + ShouldEmitLifetimeMarkers = true; + + // Initialize helper which will detect jumps which can cause invalid + // lifetime markers. + if (ShouldEmitLifetimeMarkers) + Bypasses.Init(Body); + } // Emit the standard function prologue. StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin()); + // Save parameters for coroutine function. + if (Body && isa_and_nonnull<CoroutineBodyStmt>(Body)) + for (const auto *ParamDecl : FD->parameters()) + FnArgs.push_back(ParamDecl); + // Generate the body of the function. PGO.assignRegionCounters(GD, CurFn); if (isa<CXXDestructorDecl>(FD)) @@ -1365,7 +1384,7 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, !FD->getReturnType()->isVoidType() && Builder.GetInsertBlock()) { bool ShouldEmitUnreachable = CGM.getCodeGenOpts().StrictReturn || - shouldUseUndefinedBehaviorReturnOptimization(FD, getContext()); + !CGM.MayDropFunctionReturn(FD->getASTContext(), FD->getReturnType()); if (SanOpts.has(SanitizerKind::Return)) { SanitizerScope SanScope(this); llvm::Value *IsFalse = Builder.getFalse(); @@ -1774,10 +1793,19 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, return; } + // Emit the code with the fully general case. + llvm::Value *CondV; + { + ApplyDebugLocation DL(*this, Cond); + CondV = EvaluateExprAsBool(Cond); + } + + llvm::MDNode *Weights = nullptr; + llvm::MDNode *Unpredictable = nullptr; + // If the branch has a condition wrapped by __builtin_unpredictable, // create metadata that specifies that the branch is unpredictable. // Don't bother if not optimizing because that metadata would not be used. - llvm::MDNode *Unpredictable = nullptr; auto *Call = dyn_cast<CallExpr>(Cond->IgnoreImpCasts()); if (Call && CGM.getCodeGenOpts().OptimizationLevel != 0) { auto *FD = dyn_cast_or_null<FunctionDecl>(Call->getCalleeDecl()); @@ -1787,18 +1815,17 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, } } - llvm::MDNode *Weights = createBranchWeights(LH); - if (!Weights) { + // If there is a Likelihood knowledge for the cond, lower it. + // Note that if not optimizing this won't emit anything. + llvm::Value *NewCondV = emitCondLikelihoodViaExpectIntrinsic(CondV, LH); + if (CondV != NewCondV) + CondV = NewCondV; + else { + // Otherwise, lower profile counts. Note that we do this even at -O0. uint64_t CurrentCount = std::max(getCurrentProfileCount(), TrueCount); Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount); } - // Emit the code with the fully general case. - llvm::Value *CondV; - { - ApplyDebugLocation DL(*this, Cond); - CondV = EvaluateExprAsBool(Cond); - } Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, Weights, Unpredictable); } @@ -1826,8 +1853,8 @@ static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType, Address begin = Builder.CreateElementBitCast(dest, CGF.Int8Ty, "vla.begin"); - llvm::Value *end = - Builder.CreateInBoundsGEP(begin.getPointer(), sizeInChars, "vla.end"); + llvm::Value *end = Builder.CreateInBoundsGEP( + begin.getElementType(), begin.getPointer(), sizeInChars, "vla.end"); llvm::BasicBlock *originBB = CGF.Builder.GetInsertBlock(); llvm::BasicBlock *loopBB = CGF.createBasicBlock("vla-init.loop"); @@ -2034,9 +2061,9 @@ llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType, addr = Builder.CreateElementBitCast(addr, baseType, "array.begin"); } else { // Create the actual GEP. - addr = Address(Builder.CreateInBoundsGEP(addr.getPointer(), - gepIndices, "array.begin"), - addr.getAlignment()); + addr = Address(Builder.CreateInBoundsGEP( + addr.getElementType(), addr.getPointer(), gepIndices, "array.begin"), + addr.getAlignment()); } baseType = eltType; @@ -2642,35 +2669,26 @@ llvm::DebugLoc CodeGenFunction::SourceLocToDebugLoc(SourceLocation Location) { return llvm::DebugLoc(); } -static Optional<std::pair<uint32_t, uint32_t>> -getLikelihoodWeights(Stmt::Likelihood LH) { +llvm::Value * +CodeGenFunction::emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond, + Stmt::Likelihood LH) { switch (LH) { - case Stmt::LH_Unlikely: - return std::pair<uint32_t, uint32_t>(llvm::UnlikelyBranchWeight, - llvm::LikelyBranchWeight); case Stmt::LH_None: - return None; + return Cond; case Stmt::LH_Likely: - return std::pair<uint32_t, uint32_t>(llvm::LikelyBranchWeight, - llvm::UnlikelyBranchWeight); + case Stmt::LH_Unlikely: + // Don't generate llvm.expect on -O0 as the backend won't use it for + // anything. + if (CGM.getCodeGenOpts().OptimizationLevel == 0) + return Cond; + llvm::Type *CondTy = Cond->getType(); + assert(CondTy->isIntegerTy(1) && "expecting condition to be a boolean"); + llvm::Function *FnExpect = + CGM.getIntrinsic(llvm::Intrinsic::expect, CondTy); + llvm::Value *ExpectedValueOfCond = + llvm::ConstantInt::getBool(CondTy, LH == Stmt::LH_Likely); + return Builder.CreateCall(FnExpect, {Cond, ExpectedValueOfCond}, + Cond->getName() + ".expval"); } llvm_unreachable("Unknown Likelihood"); } - -llvm::MDNode *CodeGenFunction::createBranchWeights(Stmt::Likelihood LH) const { - Optional<std::pair<uint32_t, uint32_t>> LHW = getLikelihoodWeights(LH); - if (!LHW) - return nullptr; - - llvm::MDBuilder MDHelper(CGM.getLLVMContext()); - return MDHelper.createBranchWeights(LHW->first, LHW->second); -} - -llvm::MDNode *CodeGenFunction::createProfileOrBranchWeightsForLoop( - const Stmt *Cond, uint64_t LoopCount, const Stmt *Body) const { - llvm::MDNode *Weights = createProfileWeightsForLoop(Cond, LoopCount); - if (!Weights && CGM.getCodeGenOpts().OptimizationLevel) - Weights = createBranchWeights(Stmt::getLikelihood(Body)); - - return Weights; -} |