diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-02-16 20:13:02 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-02-16 20:13:02 +0000 |
commit | b60736ec1405bb0a8dd40989f67ef4c93da068ab (patch) | |
tree | 5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | cfca06d7963fa0909f90483b42a6d7d194d01e08 (diff) |
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 315 |
1 files changed, 234 insertions, 81 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 4a7c84562dee..b393c88f7751 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -25,6 +25,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/Expr.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" #include "clang/Basic/Builtins.h" @@ -32,6 +33,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/CodeGen/CGFunctionInfo.h" #include "clang/Frontend/FrontendDiagnostic.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Frontend/OpenMP/OMPIRBuilder.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" @@ -40,6 +42,8 @@ #include "llvm/IR/Intrinsics.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Operator.h" +#include "llvm/Support/CRC.h" +#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h" #include "llvm/Transforms/Utils/PromoteMemToReg.h" using namespace clang; using namespace CodeGen; @@ -128,10 +132,24 @@ void CodeGenFunction::SetFastMathFlags(FPOptions FPFeatures) { } CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF, + const Expr *E) + : CGF(CGF) { + ConstructorHelper(E->getFPFeaturesInEffect(CGF.getLangOpts())); +} + +CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF, FPOptions FPFeatures) - : CGF(CGF), OldFPFeatures(CGF.CurFPFeatures) { + : CGF(CGF) { + ConstructorHelper(FPFeatures); +} + +void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(FPOptions FPFeatures) { + OldFPFeatures = CGF.CurFPFeatures; CGF.CurFPFeatures = FPFeatures; + OldExcept = CGF.Builder.getDefaultConstrainedExcept(); + OldRounding = CGF.Builder.getDefaultConstrainedRounding(); + if (OldFPFeatures == FPFeatures) return; @@ -172,6 +190,8 @@ CodeGenFunction::CGFPOptionsRAII::CGFPOptionsRAII(CodeGenFunction &CGF, CodeGenFunction::CGFPOptionsRAII::~CGFPOptionsRAII() { CGF.CurFPFeatures = OldFPFeatures; + CGF.Builder.setDefaultConstrainedExcept(OldExcept); + CGF.Builder.setDefaultConstrainedRounding(OldRounding); } LValue CodeGenFunction::MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T) { @@ -772,13 +792,16 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, SanOpts.Mask &= ~SanitizerKind::Null; // Apply xray attributes to the function (as a string, for now) + bool AlwaysXRayAttr = false; if (const auto *XRayAttr = D ? D->getAttr<XRayInstrumentAttr>() : nullptr) { if (CGM.getCodeGenOpts().XRayInstrumentationBundle.has( XRayInstrKind::FunctionEntry) || CGM.getCodeGenOpts().XRayInstrumentationBundle.has( XRayInstrKind::FunctionExit)) { - if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction()) + if (XRayAttr->alwaysXRayInstrument() && ShouldXRayInstrumentFunction()) { Fn->addFnAttr("function-instrument", "xray-always"); + AlwaysXRayAttr = true; + } if (XRayAttr->neverXRayInstrument()) Fn->addFnAttr("function-instrument", "xray-never"); if (const auto *LogArgs = D->getAttr<XRayLogArgsAttr>()) @@ -804,8 +827,22 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (!CGM.getCodeGenOpts().XRayInstrumentationBundle.has( XRayInstrKind::FunctionEntry)) Fn->addFnAttr("xray-skip-entry"); + + auto FuncGroups = CGM.getCodeGenOpts().XRayTotalFunctionGroups; + if (FuncGroups > 1) { + auto FuncName = llvm::makeArrayRef<uint8_t>( + CurFn->getName().bytes_begin(), CurFn->getName().bytes_end()); + auto Group = crc32(FuncName) % FuncGroups; + if (Group != CGM.getCodeGenOpts().XRaySelectedFunctionGroup && + !AlwaysXRayAttr) + Fn->addFnAttr("function-instrument", "xray-never"); + } } + if (CGM.getCodeGenOpts().getProfileInstr() != CodeGenOptions::ProfileNone) + if (CGM.isProfileInstrExcluded(Fn, Loc)) + Fn->addFnAttr(llvm::Attribute::NoProfile); + unsigned Count, Offset; if (const auto *Attr = D ? D->getAttr<PatchableFunctionEntryAttr>() : nullptr) { @@ -899,8 +936,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, } if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { - Builder.setIsFPConstrained(FD->usesFPIntrin()); - if (FD->usesFPIntrin()) + Builder.setIsFPConstrained(FD->hasAttr<StrictFPAttr>()); + if (FD->hasAttr<StrictFPAttr>()) Fn->addFnAttr(llvm::Attribute::StrictFP); } @@ -944,8 +981,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, ArgTypes.push_back(VD->getType()); QualType FnType = getContext().getFunctionType( RetTy, ArgTypes, FunctionProtoType::ExtProtoInfo(CC)); - DI->EmitFunctionStart(GD, Loc, StartLoc, FnType, CurFn, CurFuncIsThunk, - Builder); + DI->emitFunctionStart(GD, Loc, StartLoc, FnType, CurFn, CurFuncIsThunk); } if (ShouldInstrumentFunction()) { @@ -1104,11 +1140,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, MD->getParent()->getLambdaCaptureDefault() == LCD_None) SkippedChecks.set(SanitizerKind::Null, true); - EmitTypeCheck(isa<CXXConstructorDecl>(MD) ? TCK_ConstructorCall - : TCK_MemberCall, - Loc, CXXABIThisValue, ThisTy, - getContext().getTypeAlignInChars(ThisTy->getPointeeType()), - SkippedChecks); + EmitTypeCheck( + isa<CXXConstructorDecl>(MD) ? TCK_ConstructorCall : TCK_MemberCall, + Loc, CXXABIThisValue, ThisTy, CXXABIThisAlignment, SkippedChecks); } } @@ -1143,10 +1177,18 @@ 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 EmitStmt(Body); + + // This is checked after emitting the function body so we know if there + // are any permitted infinite loops. + if (FnIsMustProgress) + CurFn->addFnAttr(llvm::Attribute::MustProgress); } /// When instrumenting to collect profile data, the counts for some blocks @@ -1462,16 +1504,99 @@ bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond, return true; } +/// Determine whether the given condition is an instrumentable condition +/// (i.e. no "&&" or "||"). +bool CodeGenFunction::isInstrumentedCondition(const Expr *C) { + // Bypass simplistic logical-NOT operator before determining whether the + // condition contains any other logical operator. + if (const UnaryOperator *UnOp = dyn_cast<UnaryOperator>(C->IgnoreParens())) + if (UnOp->getOpcode() == UO_LNot) + C = UnOp->getSubExpr(); + + const BinaryOperator *BOp = dyn_cast<BinaryOperator>(C->IgnoreParens()); + return (!BOp || !BOp->isLogicalOp()); +} + +/// EmitBranchToCounterBlock - Emit a conditional branch to a new block that +/// increments a profile counter based on the semantics of the given logical +/// operator opcode. This is used to instrument branch condition coverage for +/// logical operators. +void CodeGenFunction::EmitBranchToCounterBlock( + const Expr *Cond, BinaryOperator::Opcode LOp, llvm::BasicBlock *TrueBlock, + llvm::BasicBlock *FalseBlock, uint64_t TrueCount /* = 0 */, + Stmt::Likelihood LH /* =None */, const Expr *CntrIdx /* = nullptr */) { + // If not instrumenting, just emit a branch. + bool InstrumentRegions = CGM.getCodeGenOpts().hasProfileClangInstr(); + if (!InstrumentRegions || !isInstrumentedCondition(Cond)) + return EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount, LH); + + llvm::BasicBlock *ThenBlock = NULL; + llvm::BasicBlock *ElseBlock = NULL; + llvm::BasicBlock *NextBlock = NULL; + + // Create the block we'll use to increment the appropriate counter. + llvm::BasicBlock *CounterIncrBlock = createBasicBlock("lop.rhscnt"); + + // Set block pointers according to Logical-AND (BO_LAnd) semantics. This + // means we need to evaluate the condition and increment the counter on TRUE: + // + // if (Cond) + // goto CounterIncrBlock; + // else + // goto FalseBlock; + // + // CounterIncrBlock: + // Counter++; + // goto TrueBlock; + if (LOp == BO_LAnd) { + ThenBlock = CounterIncrBlock; + ElseBlock = FalseBlock; + NextBlock = TrueBlock; + } + + // Set block pointers according to Logical-OR (BO_LOr) semantics. This means + // we need to evaluate the condition and increment the counter on FALSE: + // + // if (Cond) + // goto TrueBlock; + // else + // goto CounterIncrBlock; + // + // CounterIncrBlock: + // Counter++; + // goto FalseBlock; + + else if (LOp == BO_LOr) { + ThenBlock = TrueBlock; + ElseBlock = CounterIncrBlock; + NextBlock = FalseBlock; + } else { + llvm_unreachable("Expected Opcode must be that of a Logical Operator"); + } + + // Emit Branch based on condition. + EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, TrueCount, LH); + + // Emit the block containing the counter increment(s). + EmitBlock(CounterIncrBlock); + + // Increment corresponding counter; if index not provided, use Cond as index. + incrementProfileCounter(CntrIdx ? CntrIdx : Cond); + + // Go to the next block. + EmitBranch(NextBlock); +} /// EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g. for an if /// statement) to the specified blocks. Based on the condition, this might try /// to simplify the codegen of the conditional based on the branch. -/// +/// \param LH The value of the likelihood attribute on the True branch. void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, - uint64_t TrueCount) { + uint64_t TrueCount, + Stmt::Likelihood LH) { Cond = Cond->IgnoreParens(); if (const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) { @@ -1485,8 +1610,8 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, ConstantBool) { // br(1 && X) -> br(X). incrementProfileCounter(CondBOp); - return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock, - TrueCount); + return EmitBranchToCounterBlock(CondBOp->getRHS(), BO_LAnd, TrueBlock, + FalseBlock, TrueCount, LH); } // If we have "X && 1", simplify the code to use an uncond branch. @@ -1494,8 +1619,8 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) && ConstantBool) { // br(X && 1) -> br(X). - return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock, - TrueCount); + return EmitBranchToCounterBlock(CondBOp->getLHS(), BO_LAnd, TrueBlock, + FalseBlock, TrueCount, LH, CondBOp); } // Emit the LHS as a conditional. If the LHS conditional is false, we @@ -1508,7 +1633,11 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, ConditionalEvaluation eval(*this); { ApplyDebugLocation DL(*this, Cond); - EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock, RHSCount); + // Propagate the likelihood attribute like __builtin_expect + // __builtin_expect(X && Y, 1) -> X and Y are likely + // __builtin_expect(X && Y, 0) -> only Y is unlikely + EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock, RHSCount, + LH == Stmt::LH_Unlikely ? Stmt::LH_None : LH); EmitBlock(LHSTrue); } @@ -1517,7 +1646,8 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, // Any temporaries created here are conditional. eval.begin(*this); - EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock, TrueCount); + EmitBranchToCounterBlock(CondBOp->getRHS(), BO_LAnd, TrueBlock, + FalseBlock, TrueCount, LH); eval.end(*this); return; @@ -1531,8 +1661,8 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, !ConstantBool) { // br(0 || X) -> br(X). incrementProfileCounter(CondBOp); - return EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock, - TrueCount); + return EmitBranchToCounterBlock(CondBOp->getRHS(), BO_LOr, TrueBlock, + FalseBlock, TrueCount, LH); } // If we have "X || 0", simplify the code to use an uncond branch. @@ -1540,8 +1670,8 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, if (ConstantFoldsToSimpleInteger(CondBOp->getRHS(), ConstantBool) && !ConstantBool) { // br(X || 0) -> br(X). - return EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, FalseBlock, - TrueCount); + return EmitBranchToCounterBlock(CondBOp->getLHS(), BO_LOr, TrueBlock, + FalseBlock, TrueCount, LH, CondBOp); } // Emit the LHS as a conditional. If the LHS conditional is true, we @@ -1556,8 +1686,12 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, ConditionalEvaluation eval(*this); { + // Propagate the likelihood attribute like __builtin_expect + // __builtin_expect(X || Y, 1) -> only Y is likely + // __builtin_expect(X || Y, 0) -> both X and Y are unlikely ApplyDebugLocation DL(*this, Cond); - EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse, LHSCount); + EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse, LHSCount, + LH == Stmt::LH_Likely ? Stmt::LH_None : LH); EmitBlock(LHSFalse); } @@ -1566,7 +1700,8 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, // Any temporaries created here are conditional. eval.begin(*this); - EmitBranchOnBoolExpr(CondBOp->getRHS(), TrueBlock, FalseBlock, RHSCount); + EmitBranchToCounterBlock(CondBOp->getRHS(), BO_LOr, TrueBlock, FalseBlock, + RHSCount, LH); eval.end(*this); @@ -1579,9 +1714,11 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, if (CondUOp->getOpcode() == UO_LNot) { // Negate the count. uint64_t FalseCount = getCurrentProfileCount() - TrueCount; + // The values of the enum are chosen to make this negation possible. + LH = static_cast<Stmt::Likelihood>(-LH); // Negate the condition and swap the destination blocks. return EmitBranchOnBoolExpr(CondUOp->getSubExpr(), FalseBlock, TrueBlock, - FalseCount); + FalseCount, LH); } } @@ -1590,9 +1727,11 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *LHSBlock = createBasicBlock("cond.true"); llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false"); + // The ConditionalOperator itself has no likelihood information for its + // true and false branches. This matches the behavior of __builtin_expect. ConditionalEvaluation cond(*this); EmitBranchOnBoolExpr(CondOp->getCond(), LHSBlock, RHSBlock, - getProfileCount(CondOp)); + getProfileCount(CondOp), Stmt::LH_None); // When computing PGO branch weights, we only know the overall count for // the true block. This code is essentially doing tail duplication of the @@ -1612,14 +1751,14 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, { ApplyDebugLocation DL(*this, Cond); EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock, - LHSScaledTrueCount); + LHSScaledTrueCount, LH); } cond.end(*this); cond.begin(*this); EmitBlock(RHSBlock); EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock, - TrueCount - LHSScaledTrueCount); + TrueCount - LHSScaledTrueCount, LH); cond.end(*this); return; @@ -1648,11 +1787,11 @@ void CodeGenFunction::EmitBranchOnBoolExpr(const Expr *Cond, } } - // Create branch weights based on the number of times we get here and the - // number of times the condition should be true. - uint64_t CurrentCount = std::max(getCurrentProfileCount(), TrueCount); - llvm::MDNode *Weights = - createProfileWeights(TrueCount, CurrentCount - TrueCount); + llvm::MDNode *Weights = createBranchWeights(LH); + if (!Weights) { + uint64_t CurrentCount = std::max(getCurrentProfileCount(), TrueCount); + Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount); + } // Emit the code with the fully general case. llvm::Value *CondV; @@ -2075,7 +2214,6 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) { case Type::UnaryTransform: case Type::Attributed: case Type::SubstTemplateTypeParm: - case Type::PackExpansion: case Type::MacroQualified: // Keep walking after single level desugaring. type = type.getSingleStepDesugaredType(getContext()); @@ -2206,13 +2344,16 @@ void CodeGenFunction::emitAlignmentAssumption(llvm::Value *PtrValue, llvm::Value *CodeGenFunction::EmitAnnotationCall(llvm::Function *AnnotationFn, llvm::Value *AnnotatedVal, StringRef AnnotationStr, - SourceLocation Location) { - llvm::Value *Args[4] = { - AnnotatedVal, - Builder.CreateBitCast(CGM.EmitAnnotationString(AnnotationStr), Int8PtrTy), - Builder.CreateBitCast(CGM.EmitAnnotationUnit(Location), Int8PtrTy), - CGM.EmitAnnotationLineNo(Location) + SourceLocation Location, + const AnnotateAttr *Attr) { + SmallVector<llvm::Value *, 5> Args = { + AnnotatedVal, + Builder.CreateBitCast(CGM.EmitAnnotationString(AnnotationStr), Int8PtrTy), + Builder.CreateBitCast(CGM.EmitAnnotationUnit(Location), Int8PtrTy), + CGM.EmitAnnotationLineNo(Location), }; + if (Attr) + Args.push_back(CGM.EmitAnnotationArgs(Attr)); return Builder.CreateCall(AnnotationFn, Args); } @@ -2223,7 +2364,7 @@ void CodeGenFunction::EmitVarAnnotations(const VarDecl *D, llvm::Value *V) { for (const auto *I : D->specific_attrs<AnnotateAttr>()) EmitAnnotationCall(CGM.getIntrinsic(llvm::Intrinsic::var_annotation), Builder.CreateBitCast(V, CGM.Int8PtrTy, V->getName()), - I->getAnnotation(), D->getLocation()); + I->getAnnotation(), D->getLocation(), I); } Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D, @@ -2240,7 +2381,7 @@ Address CodeGenFunction::EmitFieldAnnotations(const FieldDecl *D, // itself. if (VTy != CGM.Int8PtrTy) V = Builder.CreateBitCast(V, CGM.Int8PtrTy); - V = EmitAnnotationCall(F, V, I->getAnnotation(), D->getLocation()); + V = EmitAnnotationCall(F, V, I->getAnnotation(), D->getLocation(), I); V = Builder.CreateBitCast(V, VTy); } @@ -2276,34 +2417,6 @@ void CGBuilderInserter::InsertHelper( CGF->InsertHelper(I, Name, BB, InsertPt); } -static bool hasRequiredFeatures(const SmallVectorImpl<StringRef> &ReqFeatures, - CodeGenModule &CGM, const FunctionDecl *FD, - std::string &FirstMissing) { - // If there aren't any required features listed then go ahead and return. - if (ReqFeatures.empty()) - return false; - - // Now build up the set of caller features and verify that all the required - // features are there. - llvm::StringMap<bool> CallerFeatureMap; - CGM.getContext().getFunctionFeatureMap(CallerFeatureMap, FD); - - // If we have at least one of the features in the feature list return - // true, otherwise return false. - return std::all_of( - ReqFeatures.begin(), ReqFeatures.end(), [&](StringRef Feature) { - SmallVector<StringRef, 1> OrFeatures; - Feature.split(OrFeatures, '|'); - return llvm::any_of(OrFeatures, [&](StringRef Feature) { - if (!CallerFeatureMap.lookup(Feature)) { - FirstMissing = Feature.str(); - return false; - } - return true; - }); - }); -} - // Emits an error if we don't have a valid set of target features for the // called function. void CodeGenFunction::checkTargetFeatures(const CallExpr *E, @@ -2330,19 +2443,20 @@ void CodeGenFunction::checkTargetFeatures(SourceLocation Loc, // listed cpu and any listed features. unsigned BuiltinID = TargetDecl->getBuiltinID(); std::string MissingFeature; + llvm::StringMap<bool> CallerFeatureMap; + CGM.getContext().getFunctionFeatureMap(CallerFeatureMap, FD); if (BuiltinID) { - SmallVector<StringRef, 1> ReqFeatures; - const char *FeatureList = - CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID); + StringRef FeatureList( + CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID)); // Return if the builtin doesn't have any required features. - if (!FeatureList || StringRef(FeatureList) == "") + if (FeatureList.empty()) return; - StringRef(FeatureList).split(ReqFeatures, ','); - if (!hasRequiredFeatures(ReqFeatures, CGM, FD, MissingFeature)) + assert(FeatureList.find(' ') == StringRef::npos && + "Space in feature list"); + TargetFeatures TF(CallerFeatureMap); + if (!TF.hasRequiredFeatures(FeatureList)) CGM.getDiags().Report(Loc, diag::err_builtin_needs_feature) - << TargetDecl->getDeclName() - << CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID); - + << TargetDecl->getDeclName() << FeatureList; } else if (!TargetDecl->isMultiVersion() && TargetDecl->hasAttr<TargetAttr>()) { // Get the required features for the callee. @@ -2365,7 +2479,13 @@ void CodeGenFunction::checkTargetFeatures(SourceLocation Loc, if (F.getValue()) ReqFeatures.push_back(F.getKey()); } - if (!hasRequiredFeatures(ReqFeatures, CGM, FD, MissingFeature)) + if (!llvm::all_of(ReqFeatures, [&](StringRef Feature) { + if (!CallerFeatureMap.lookup(Feature)) { + MissingFeature = Feature.str(); + return false; + } + return true; + })) CGM.getDiags().Report(Loc, diag::err_function_needs_feature) << FD->getDeclName() << TargetDecl->getDeclName() << MissingFeature; } @@ -2521,3 +2641,36 @@ llvm::DebugLoc CodeGenFunction::SourceLocToDebugLoc(SourceLocation Location) { return llvm::DebugLoc(); } + +static Optional<std::pair<uint32_t, uint32_t>> +getLikelihoodWeights(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; + case Stmt::LH_Likely: + return std::pair<uint32_t, uint32_t>(llvm::LikelyBranchWeight, + llvm::UnlikelyBranchWeight); + } + 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; +} |