18#include "llvm/IR/Intrinsics.h"
19#include "llvm/IR/MDBuilder.h"
20#include "llvm/Support/CommandLine.h"
21#include "llvm/Support/Endian.h"
22#include "llvm/Support/FileSystem.h"
23#include "llvm/Support/MD5.h"
26static llvm::cl::opt<bool>
28 llvm::cl::desc(
"Enable value profiling"),
29 llvm::cl::Hidden, llvm::cl::init(
false));
32using namespace CodeGen;
34void CodeGenPGO::setFuncName(StringRef Name,
35 llvm::GlobalValue::LinkageTypes
Linkage) {
36 llvm::IndexedInstrProfReader *PGOReader = CGM.
getPGOReader();
37 FuncName = llvm::getPGOFuncName(
39 PGOReader ? PGOReader->getVersion() : llvm::IndexedInstrProf::Version);
43 FuncNameVar = llvm::createPGOFuncNameVar(CGM.
getModule(),
Linkage, FuncName);
46void CodeGenPGO::setFuncName(llvm::Function *Fn) {
47 setFuncName(Fn->getName(), Fn->getLinkage());
49 llvm::createPGOFuncNameMetadata(*Fn, FuncName);
79 static const int NumBitsPerType = 6;
80 static const unsigned NumTypesPerWord =
sizeof(
uint64_t) * 8 / NumBitsPerType;
81 static const unsigned TooBig = 1u << NumBitsPerType;
91 enum HashType :
unsigned char {
132 static_assert(LastHashType <= TooBig,
"Too many types in HashType");
135 : Working(0), Count(0), HashVersion(HashVersion) {}
136 void combine(HashType
Type);
140const int PGOHash::NumBitsPerType;
141const unsigned PGOHash::NumTypesPerWord;
142const unsigned PGOHash::TooBig;
145static PGOHashVersion getPGOHashVersion(llvm::IndexedInstrProfReader *PGOReader,
147 if (PGOReader->getVersion() <= 4)
149 if (PGOReader->getVersion() <= 5)
159 unsigned NextCounter;
163 llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
167 MapRegionCounters(
PGOHashVersion HashVersion, uint64_t ProfileVersion,
168 llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
169 : NextCounter(0), Hash(HashVersion), CounterMap(CounterMap),
170 ProfileVersion(ProfileVersion) {}
174 bool TraverseBlockExpr(
BlockExpr *BE) {
return true; }
177 for (
auto C : zip(
LE->captures(),
LE->capture_inits()))
178 TraverseLambdaCapture(LE, &std::get<0>(
C), std::get<1>(
C));
181 bool TraverseCapturedStmt(
CapturedStmt *CS) {
return true; }
183 bool VisitDecl(
const Decl *D) {
188 case Decl::CXXMethod:
189 case Decl::CXXConstructor:
190 case Decl::CXXDestructor:
191 case Decl::CXXConversion:
192 case Decl::ObjCMethod:
195 CounterMap[D->
getBody()] = NextCounter++;
203 PGOHash::HashType updateCounterMappings(
Stmt *S) {
205 if (
Type != PGOHash::None)
206 CounterMap[S] = NextCounter++;
215 if (ProfileVersion >= llvm::IndexedInstrProf::Version7)
216 if (S->isLogicalOp() &&
217 CodeGenFunction::isInstrumentedCondition(S->getRHS()))
218 CounterMap[S->getRHS()] = NextCounter++;
219 return Base::VisitBinaryOperator(S);
223 bool VisitStmt(
Stmt *S) {
224 auto Type = updateCounterMappings(S);
226 Type = getHashType(Hash.getHashVersion(), S);
227 if (
Type != PGOHash::None)
232 bool TraverseIfStmt(
IfStmt *If) {
235 return Base::TraverseIfStmt(If);
243 Hash.combine(PGOHash::IfThenBranch);
245 Hash.combine(PGOHash::IfElseBranch);
248 Hash.combine(PGOHash::EndOfScope);
255#define DEFINE_NESTABLE_TRAVERSAL(N) \
256 bool Traverse##N(N *S) { \
257 Base::Traverse##N(S); \
258 if (Hash.getHashVersion() != PGO_HASH_V1) \
259 Hash.combine(PGOHash::EndOfScope); \
273 switch (S->getStmtClass()) {
276 case Stmt::LabelStmtClass:
277 return PGOHash::LabelStmt;
278 case Stmt::WhileStmtClass:
279 return PGOHash::WhileStmt;
280 case Stmt::DoStmtClass:
281 return PGOHash::DoStmt;
282 case Stmt::ForStmtClass:
283 return PGOHash::ForStmt;
284 case Stmt::CXXForRangeStmtClass:
285 return PGOHash::CXXForRangeStmt;
286 case Stmt::ObjCForCollectionStmtClass:
287 return PGOHash::ObjCForCollectionStmt;
288 case Stmt::SwitchStmtClass:
289 return PGOHash::SwitchStmt;
290 case Stmt::CaseStmtClass:
291 return PGOHash::CaseStmt;
292 case Stmt::DefaultStmtClass:
293 return PGOHash::DefaultStmt;
294 case Stmt::IfStmtClass:
295 return PGOHash::IfStmt;
296 case Stmt::CXXTryStmtClass:
297 return PGOHash::CXXTryStmt;
298 case Stmt::CXXCatchStmtClass:
299 return PGOHash::CXXCatchStmt;
300 case Stmt::ConditionalOperatorClass:
301 return PGOHash::ConditionalOperator;
302 case Stmt::BinaryConditionalOperatorClass:
303 return PGOHash::BinaryConditionalOperator;
304 case Stmt::BinaryOperatorClass: {
307 return PGOHash::BinaryOperatorLAnd;
309 return PGOHash::BinaryOperatorLOr;
315 return PGOHash::BinaryOperatorLT;
317 return PGOHash::BinaryOperatorGT;
319 return PGOHash::BinaryOperatorLE;
321 return PGOHash::BinaryOperatorGE;
323 return PGOHash::BinaryOperatorEQ;
325 return PGOHash::BinaryOperatorNE;
333 switch (S->getStmtClass()) {
336 case Stmt::GotoStmtClass:
337 return PGOHash::GotoStmt;
338 case Stmt::IndirectGotoStmtClass:
339 return PGOHash::IndirectGotoStmt;
340 case Stmt::BreakStmtClass:
341 return PGOHash::BreakStmt;
342 case Stmt::ContinueStmtClass:
343 return PGOHash::ContinueStmt;
344 case Stmt::ReturnStmtClass:
345 return PGOHash::ReturnStmt;
346 case Stmt::CXXThrowExprClass:
347 return PGOHash::ThrowExpr;
348 case Stmt::UnaryOperatorClass: {
351 return PGOHash::UnaryOperatorLNot;
357 return PGOHash::None;
369 bool RecordNextStmtCount;
375 llvm::DenseMap<const Stmt *, uint64_t> &
CountMap;
378 struct BreakContinue {
381 BreakContinue() =
default;
385 ComputeRegionCounts(llvm::DenseMap<const Stmt *, uint64_t> &
CountMap,
389 void RecordStmtCount(
const Stmt *S) {
390 if (RecordNextStmtCount) {
392 RecordNextStmtCount =
false;
398 CurrentCount = Count;
402 void VisitStmt(
const Stmt *S) {
404 for (
const Stmt *Child : S->children())
435 void VisitBlockDecl(
const BlockDecl *D) {
444 if (S->getRetValue())
445 Visit(S->getRetValue());
447 RecordNextStmtCount =
true;
455 RecordNextStmtCount =
true;
458 void VisitGotoStmt(
const GotoStmt *S) {
461 RecordNextStmtCount =
true;
464 void VisitLabelStmt(
const LabelStmt *S) {
465 RecordNextStmtCount =
false;
469 Visit(S->getSubStmt());
472 void VisitBreakStmt(
const BreakStmt *S) {
474 assert(!BreakContinueStack.empty() &&
"break not in a loop or switch!");
475 BreakContinueStack.back().BreakCount += CurrentCount;
477 RecordNextStmtCount =
true;
482 assert(!BreakContinueStack.empty() &&
"continue stmt not in a loop!");
483 BreakContinueStack.back().ContinueCount += CurrentCount;
485 RecordNextStmtCount =
true;
488 void VisitWhileStmt(
const WhileStmt *S) {
490 uint64_t ParentCount = CurrentCount;
492 BreakContinueStack.push_back(BreakContinue());
496 CountMap[S->getBody()] = CurrentCount;
498 uint64_t BackedgeCount = CurrentCount;
504 BreakContinue BC = BreakContinueStack.pop_back_val();
506 setCount(ParentCount + BackedgeCount + BC.ContinueCount);
509 setCount(BC.BreakCount + CondCount - BodyCount);
510 RecordNextStmtCount =
true;
513 void VisitDoStmt(
const DoStmt *S) {
517 BreakContinueStack.push_back(BreakContinue());
519 uint64_t BodyCount = setCount(LoopCount + CurrentCount);
522 uint64_t BackedgeCount = CurrentCount;
524 BreakContinue BC = BreakContinueStack.pop_back_val();
527 uint64_t CondCount = setCount(BackedgeCount + BC.ContinueCount);
530 setCount(BC.BreakCount + CondCount - LoopCount);
531 RecordNextStmtCount =
true;
534 void VisitForStmt(
const ForStmt *S) {
539 uint64_t ParentCount = CurrentCount;
541 BreakContinueStack.push_back(BreakContinue());
547 uint64_t BackedgeCount = CurrentCount;
548 BreakContinue BC = BreakContinueStack.pop_back_val();
553 uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
560 setCount(ParentCount + BackedgeCount + BC.ContinueCount);
565 setCount(BC.BreakCount + CondCount - BodyCount);
566 RecordNextStmtCount =
true;
573 Visit(S->getLoopVarStmt());
574 Visit(S->getRangeStmt());
575 Visit(S->getBeginStmt());
576 Visit(S->getEndStmt());
578 uint64_t ParentCount = CurrentCount;
579 BreakContinueStack.push_back(BreakContinue());
585 uint64_t BackedgeCount = CurrentCount;
586 BreakContinue BC = BreakContinueStack.pop_back_val();
590 uint64_t IncCount = setCount(BackedgeCount + BC.ContinueCount);
596 setCount(ParentCount + BackedgeCount + BC.ContinueCount);
599 setCount(BC.BreakCount + CondCount - BodyCount);
600 RecordNextStmtCount =
true;
605 Visit(S->getElement());
606 uint64_t ParentCount = CurrentCount;
607 BreakContinueStack.push_back(BreakContinue());
612 uint64_t BackedgeCount = CurrentCount;
613 BreakContinue BC = BreakContinueStack.pop_back_val();
615 setCount(BC.BreakCount + ParentCount + BackedgeCount + BC.ContinueCount -
617 RecordNextStmtCount =
true;
626 BreakContinueStack.push_back(BreakContinue());
629 BreakContinue BC = BreakContinueStack.pop_back_val();
630 if (!BreakContinueStack.empty())
631 BreakContinueStack.back().ContinueCount += BC.ContinueCount;
634 RecordNextStmtCount =
true;
638 RecordNextStmtCount =
false;
643 setCount(CurrentCount + CaseCount);
647 RecordNextStmtCount =
true;
648 Visit(S->getSubStmt());
651 void VisitIfStmt(
const IfStmt *S) {
654 if (S->isConsteval()) {
655 const Stmt *Stm = S->isNegatedConsteval() ? S->getThen() : S->getElse();
661 uint64_t ParentCount = CurrentCount;
673 uint64_t ElseCount = ParentCount - ThenCount;
678 OutCount += CurrentCount;
680 OutCount += ElseCount;
682 RecordNextStmtCount =
true;
687 Visit(S->getTryBlock());
688 for (
unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
689 Visit(S->getHandler(I));
692 RecordNextStmtCount =
true;
696 RecordNextStmtCount =
false;
700 Visit(S->getHandlerBlock());
705 uint64_t ParentCount = CurrentCount;
715 uint64_t FalseCount = setCount(ParentCount - TrueCount);
718 OutCount += CurrentCount;
721 RecordNextStmtCount =
true;
726 uint64_t ParentCount = CurrentCount;
732 setCount(ParentCount + RHSCount - CurrentCount);
733 RecordNextStmtCount =
true;
738 uint64_t ParentCount = CurrentCount;
744 setCount(ParentCount + RHSCount - CurrentCount);
745 RecordNextStmtCount =
true;
750void PGOHash::combine(HashType
Type) {
752 assert(
Type &&
"Hash is invalid: unexpected type 0");
753 assert(
unsigned(
Type) < TooBig &&
"Hash is invalid: too many types");
756 if (Count && Count % NumTypesPerWord == 0) {
757 using namespace llvm::support;
759 endian::byte_swap<uint64_t, llvm::endianness::little>(Working);
766 Working = Working << NumBitsPerType |
Type;
771 if (Count <= NumTypesPerWord)
782 MD5.update({(uint8_t)Working});
784 using namespace llvm::support;
786 endian::byte_swap<uint64_t, llvm::endianness::little>(Working);
792 llvm::MD5::MD5Result
Result;
808 llvm::IndexedInstrProfReader *PGOReader = CGM.
getPGOReader();
809 if (!InstrumentRegions && !PGOReader)
817 if (
const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
826 if (Fn->hasFnAttribute(llvm::Attribute::NoProfile))
828 if (Fn->hasFnAttribute(llvm::Attribute::SkipProfile))
833 mapRegionCounters(D);
835 emitCounterRegionMapping(D);
838 loadRegionCounts(PGOReader,
SM.isInMainFile(D->
getLocation()));
839 computeRegionCounts(D);
840 applyFunctionAttributes(PGOReader, Fn);
844void CodeGenPGO::mapRegionCounters(
const Decl *D) {
848 uint64_t ProfileVersion = llvm::IndexedInstrProf::Version;
850 HashVersion = getPGOHashVersion(PGOReader, CGM);
851 ProfileVersion = PGOReader->getVersion();
854 RegionCounterMap.reset(
new llvm::DenseMap<const Stmt *, unsigned>);
855 MapRegionCounters Walker(HashVersion, ProfileVersion, *RegionCounterMap);
856 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
858 else if (
const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
860 else if (
const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
861 Walker.TraverseDecl(
const_cast<BlockDecl *
>(BD));
862 else if (
const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
864 assert(Walker.NextCounter > 0 &&
"no entry counter mapped for decl");
865 NumRegionCounters = Walker.NextCounter;
866 FunctionHash = Walker.Hash.finalize();
869bool CodeGenPGO::skipRegionMappingForDecl(
const Decl *D) {
879 !D->
hasAttr<CUDAGlobalAttr>()) ||
881 (D->
hasAttr<CUDAGlobalAttr>() ||
888 return SM.isInSystemHeader(Loc);
891void CodeGenPGO::emitCounterRegionMapping(
const Decl *D) {
892 if (skipRegionMappingForDecl(D))
895 std::string CoverageMapping;
896 llvm::raw_string_ostream OS(CoverageMapping);
900 MappingGen.emitCounterMapping(D, OS);
903 if (CoverageMapping.empty())
907 FuncNameVar, FuncName, FunctionHash, CoverageMapping);
912 llvm::GlobalValue::LinkageTypes
Linkage) {
913 if (skipRegionMappingForDecl(D))
916 std::string CoverageMapping;
917 llvm::raw_string_ostream OS(CoverageMapping);
924 if (CoverageMapping.empty())
929 FuncNameVar, FuncName, FunctionHash, CoverageMapping,
false);
932void CodeGenPGO::computeRegionCounts(
const Decl *D) {
933 StmtCountMap.reset(
new llvm::DenseMap<const Stmt *, uint64_t>);
934 ComputeRegionCounts Walker(*StmtCountMap, *
this);
935 if (
const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
936 Walker.VisitFunctionDecl(FD);
937 else if (
const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
938 Walker.VisitObjCMethodDecl(MD);
939 else if (
const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
940 Walker.VisitBlockDecl(BD);
941 else if (
const CapturedDecl *CD = dyn_cast_or_null<CapturedDecl>(D))
942 Walker.VisitCapturedDecl(
const_cast<CapturedDecl *
>(CD));
946CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
947 llvm::Function *Fn) {
952 Fn->setEntryCount(FunctionCount);
956 llvm::Value *StepV) {
957 if (!RegionCounterMap || !Builder.GetInsertBlock())
960 unsigned Counter = (*RegionCounterMap)[S];
962 llvm::Value *Args[] = {FuncNameVar,
963 Builder.getInt64(FunctionHash),
964 Builder.getInt32(NumRegionCounters),
965 Builder.getInt32(Counter), StepV};
967 Builder.CreateCall(CGM.
getIntrinsic(llvm::Intrinsic::instrprof_increment),
971 CGM.
getIntrinsic(llvm::Intrinsic::instrprof_increment_step),
977 M.addModuleFlag(llvm::Module::Warning,
"EnableValueProfiling",
984 llvm::Instruction *ValueSite, llvm::Value *ValuePtr) {
989 if (!ValuePtr || !ValueSite || !Builder.GetInsertBlock())
992 if (isa<llvm::Constant>(ValuePtr))
996 if (InstrumentValueSites && RegionCounterMap) {
997 auto BuilderInsertPoint = Builder.saveIP();
998 Builder.SetInsertPoint(ValueSite);
999 llvm::Value *Args[5] = {
1001 Builder.getInt64(FunctionHash),
1002 Builder.CreatePtrToInt(ValuePtr, Builder.getInt64Ty()),
1003 Builder.getInt32(ValueKind),
1004 Builder.getInt32(NumValueSites[ValueKind]++)
1007 CGM.
getIntrinsic(llvm::Intrinsic::instrprof_value_profile), Args);
1008 Builder.restoreIP(BuilderInsertPoint);
1012 llvm::IndexedInstrProfReader *PGOReader = CGM.
getPGOReader();
1020 if (NumValueSites[ValueKind] >= ProfRecord->getNumValueSites(ValueKind))
1023 llvm::annotateValueSite(CGM.
getModule(), *ValueSite, *ProfRecord,
1024 (llvm::InstrProfValueKind)ValueKind,
1025 NumValueSites[ValueKind]);
1027 NumValueSites[ValueKind]++;
1031void CodeGenPGO::loadRegionCounts(llvm::IndexedInstrProfReader *PGOReader,
1032 bool IsInMainFile) {
1034 RegionCounts.clear();
1036 PGOReader->getInstrProfRecord(FuncName, FunctionHash);
1037 if (
auto E = RecordExpected.takeError()) {
1038 auto IPE = std::get<0>(llvm::InstrProfError::take(std::move(E)));
1039 if (IPE == llvm::instrprof_error::unknown_function)
1041 else if (IPE == llvm::instrprof_error::hash_mismatch)
1043 else if (IPE == llvm::instrprof_error::malformed)
1049 std::make_unique<llvm::InstrProfRecord>(std::move(RecordExpected.get()));
1050 RegionCounts = ProfRecord->Counts;
1058 return MaxWeight < UINT32_MAX ? 1 : MaxWeight / UINT32_MAX + 1;
1071 assert(Scale &&
"scale by 0?");
1072 uint64_t Scaled = Weight / Scale + 1;
1073 assert(Scaled <= UINT32_MAX &&
"overflow 32-bits");
1077llvm::MDNode *CodeGenFunction::createProfileWeights(uint64_t TrueCount,
1078 uint64_t FalseCount)
const {
1080 if (!TrueCount && !FalseCount)
1094 if (Weights.size() < 2)
1098 uint64_t MaxWeight = *std::max_element(Weights.begin(), Weights.end());
1106 ScaledWeights.reserve(Weights.size());
1107 for (uint64_t W : Weights)
1111 return MDHelper.createBranchWeights(ScaledWeights);
1115CodeGenFunction::createProfileWeightsForLoop(
const Stmt *Cond,
1116 uint64_t LoopCount)
const {
1119 std::optional<uint64_t> CondCount = PGO.
getStmtCount(Cond);
1120 if (!CondCount || *CondCount == 0)
1122 return createProfileWeights(LoopCount,
1123 std::max(*CondCount, LoopCount) - LoopCount);
llvm::ImmutableMap< CountKey, unsigned > CountMap
#define DEFINE_NESTABLE_TRAVERSAL(N)
static llvm::cl::opt< bool > EnableValueProfiling("enable-value-profiling", llvm::cl::desc("Enable value profiling"), llvm::cl::Hidden, llvm::cl::init(false))
PGOHashVersion
The version of the PGO hash algorithm.
static uint64_t calculateWeightScale(uint64_t MaxWeight)
Calculate what to divide by to scale weights.
static uint32_t scaleBranchWeight(uint64_t Weight, uint64_t Scale)
Scale an individual branch weight (and add 1).
SourceManager & getSourceManager()
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?: operator.
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
A builtin binary operation expression such as "x + y" or "x <= y".
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
BreakStmt - This represents a break.
CXXCatchStmt - This represents a C++ catch block.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
A C++ throw-expression (C++ [except.throw]).
const Expr * getSubExpr() const
CXXTryStmt - A C++ try block, including all handlers.
Represents the body of a CapturedStmt, and serves as its DeclContext.
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
This captures a statement into a function.
CaseStmt - Represent a case statement.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
std::string MainFileName
The user provided name for the "main file", if non-empty.
static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor)
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
const LangOptions & getLangOpts() const
const TargetInfo & getTarget() const
llvm::IndexedInstrProfReader * getPGOReader() const
CoverageMappingModuleGen * getCoverageMapping() const
InstrProfStats & getPGOStats()
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
void ClearUnusedCoverageMapping(const Decl *D)
Remove the deferred empty coverage mapping as this declaration is actually instrumented.
void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)
Assign counters to regions and configure them for PGO of a given function.
std::optional< uint64_t > getStmtCount(const Stmt *S) const
Check if an execution count is known for a given statement.
uint64_t getRegionCount(const Stmt *S)
Return the region count for the counter at the given index.
void setValueProfilingFlag(llvm::Module &M)
void valueProfile(CGBuilderTy &Builder, uint32_t ValueKind, llvm::Instruction *ValueSite, llvm::Value *ValuePtr)
void emitEmptyCounterMapping(const Decl *D, StringRef FuncName, llvm::GlobalValue::LinkageTypes Linkage)
Emit a coverage mapping range with a counter zero for an unused declaration.
void emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S, llvm::Value *StepV)
bool haveRegionCounts() const
Whether or not we have PGO region data for the current function.
Organizes the per-function state that is used while generating code coverage mapping data.
void emitEmptyMapping(const Decl *D, llvm::raw_ostream &OS)
Emit the coverage mapping data for an unused function.
void addFunctionMappingRecord(llvm::GlobalVariable *FunctionName, StringRef FunctionNameValue, uint64_t FunctionHash, const std::string &CoverageMapping, bool IsUsed=true)
Add a function's coverage mapping record to the collection of the function mapping records.
void addMissing(bool MainFile)
Record that a function we've visited has no profile data.
void addMismatched(bool MainFile)
Record that a function we've visited has mismatched profile data.
void addVisited(bool MainFile)
Record that we've visited a function and whether or not that function was in the main source file.
ConditionalOperator - The ?: ternary operator.
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
ContinueStmt - This represents a continue.
Decl - This represents one declaration (or definition), e.g.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
virtual bool hasBody() const
Returns true if this Decl represents a declaration for a body of code, such as a function or method d...
SourceLocation getLocation() const
DoStmt - This represents a 'do/while' stmt.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Represents a function declaration or definition.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
CXXDtorType getDtorType() const
const Decl * getDecl() const
GotoStmt - This represents a direct goto.
IfStmt - This represents an if/then/else.
IndirectGotoStmt - This represents an indirect goto.
LabelStmt - Represents a label, which has a substatement.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Represents Objective-C's collection statement.
ObjCMethodDecl - Represents an instance or class method declaration.
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
This class handles loading and caching of source files into memory.
Stmt - This represents one statement.
SourceLocation getBeginLoc() const LLVM_READONLY
SwitchStmt - This represents a 'switch' stmt.
bool hasConstructorVariants() const
Does this ABI have different entrypoints for complete-object and base-subobject constructors?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
The base class of the type hierarchy.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
WhileStmt - This represents a 'while' stmt.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
bool LE(InterpState &S, CodePtr OpPC)
@ Ctor_Base
Base object ctor.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ Result
The result type of a method or function.
@ Dtor_Base
Base object dtor.
void finalize(TemplateInstantiationCallbackPtrs &Callbacks, const Sema &TheSema)
@ None
The alignment was not explicit in code.