Index: lib/Transforms/Instrumentation/CFGMST.h =================================================================== --- lib/Transforms/Instrumentation/CFGMST.h +++ lib/Transforms/Instrumentation/CFGMST.h @@ -78,6 +78,14 @@ return *It->second.get(); } + // Give BB, return the auxiliary information if it's available. + BBInfo *findBBInfo(const BasicBlock *BB) const { + auto It = BBInfos.find(BB); + if (It == BBInfos.end()) + return nullptr; + return It->second.get(); + } + // Traverse the CFG using a stack. Find all the edges and assign the weight. // Edges with large weight will be put into MST first so they are less likely // to be instrumented. Index: lib/Transforms/Instrumentation/PGOInstrumentation.cpp =================================================================== --- lib/Transforms/Instrumentation/PGOInstrumentation.cpp +++ lib/Transforms/Instrumentation/PGOInstrumentation.cpp @@ -327,6 +327,9 @@ // Return the auxiliary BB information. BBInfo &getBBInfo(const BasicBlock *BB) const { return MST.getBBInfo(BB); } + // Return the auxiliary BB information if available. + BBInfo *findBBInfo(const BasicBlock *BB) const { return MST.findBBInfo(BB); } + // Dump edges and BB information. void dumpInfo(std::string Str = "") const { MST.dumpEdges(dbgs(), Twine("Dump Function ") + FuncName + " Hash: " + @@ -386,7 +389,10 @@ const TerminatorInst *TI = BB.getTerminator(); for (unsigned I = 0, E = TI->getNumSuccessors(); I != E; ++I) { BasicBlock *Succ = TI->getSuccessor(I); - uint32_t Index = getBBInfo(Succ).Index; + auto BI = findBBInfo(Succ); + if (BI == nullptr) + continue; + uint32_t Index = BI->Index; for (int J = 0; J < 4; J++) Indexes.push_back((char)(Index >> (J * 8))); } @@ -672,6 +678,11 @@ return FuncInfo.getBBInfo(BB); } + // Return the auxiliary BB information if available. + UseBBInfo *findBBInfo(const BasicBlock *BB) const { + return FuncInfo.findBBInfo(BB); + } + private: Function &F; Module *M; @@ -857,27 +868,29 @@ // For efficient traversal, it's better to start from the end as most // of the instrumented edges are at the end. for (auto &BB : reverse(F)) { - UseBBInfo &Count = getBBInfo(&BB); - if (!Count.CountValid) { - if (Count.UnknownCountOutEdge == 0) { - Count.CountValue = sumEdgeCount(Count.OutEdges); - Count.CountValid = true; + UseBBInfo *Count = findBBInfo(&BB); + if (Count == nullptr) + continue; + if (!Count->CountValid) { + if (Count->UnknownCountOutEdge == 0) { + Count->CountValue = sumEdgeCount(Count->OutEdges); + Count->CountValid = true; Changes = true; - } else if (Count.UnknownCountInEdge == 0) { - Count.CountValue = sumEdgeCount(Count.InEdges); - Count.CountValid = true; + } else if (Count->UnknownCountInEdge == 0) { + Count->CountValue = sumEdgeCount(Count->InEdges); + Count->CountValid = true; Changes = true; } } - if (Count.CountValid) { - if (Count.UnknownCountOutEdge == 1) { - uint64_t Total = Count.CountValue - sumEdgeCount(Count.OutEdges); - setEdgeCount(Count.OutEdges, Total); + if (Count->CountValid) { + if (Count->UnknownCountOutEdge == 1) { + uint64_t Total = Count->CountValue - sumEdgeCount(Count->OutEdges); + setEdgeCount(Count->OutEdges, Total); Changes = true; } - if (Count.UnknownCountInEdge == 1) { - uint64_t Total = Count.CountValue - sumEdgeCount(Count.InEdges); - setEdgeCount(Count.InEdges, Total); + if (Count->UnknownCountInEdge == 1) { + uint64_t Total = Count->CountValue - sumEdgeCount(Count->InEdges); + setEdgeCount(Count->InEdges, Total); Changes = true; } } @@ -887,14 +900,22 @@ DEBUG(dbgs() << "Populate counts in " << NumPasses << " passes.\n"); #ifndef NDEBUG // Assert every BB has a valid counter. - for (auto &BB : F) - assert(getBBInfo(&BB).CountValid && "BB count is not valid"); + for (auto &BB : F) { + auto BI = findBBInfo(&BB); + if (BI == nullptr) + continue; + assert(BI->CountValid && "BB count is not valid"); + } #endif uint64_t FuncEntryCount = getBBInfo(&*F.begin()).CountValue; F.setEntryCount(FuncEntryCount); uint64_t FuncMaxCount = FuncEntryCount; - for (auto &BB : F) - FuncMaxCount = std::max(FuncMaxCount, getBBInfo(&BB).CountValue); + for (auto &BB : F) { + auto BI = findBBInfo(&BB); + if (BI == nullptr) + continue; + FuncMaxCount = std::max(FuncMaxCount, BI->CountValue); + } markFunctionAttributes(FuncEntryCount, FuncMaxCount); // Now annotate select instructions @@ -974,7 +995,10 @@ uint64_t SCounts[2]; SCounts[0] = CountFromProfile[*CurCtrIdx]; // True count ++(*CurCtrIdx); - uint64_t TotalCount = UseFunc->getBBInfo(SI.getParent()).CountValue; + uint64_t TotalCount = 0; + auto BI = UseFunc->findBBInfo(SI.getParent()); + if (BI != nullptr) + TotalCount = BI->CountValue; // False Count SCounts[1] = (TotalCount > SCounts[0] ? TotalCount - SCounts[0] : 0); uint64_t MaxCount = std::max(SCounts[0], SCounts[1]); Index: test/Transforms/PGOProfile/Inputs/unreachable_bb.proftext =================================================================== --- /dev/null +++ test/Transforms/PGOProfile/Inputs/unreachable_bb.proftext @@ -0,0 +1,9 @@ +# IR level Instrumentation Flag +:ir +foo +# Func Hash: +12884901887 +# Num Counters: +1 +# Counter Values: +0 Index: test/Transforms/PGOProfile/unreachable_bb.ll =================================================================== --- /dev/null +++ test/Transforms/PGOProfile/unreachable_bb.ll @@ -0,0 +1,23 @@ +; RUN: llvm-profdata merge %S/Inputs/unreachable_bb.proftext -o %t.profdata +; RUN: opt < %s -pgo-instr-use -pgo-test-profile-file=%t.profdata -S | FileCheck %s --check-prefix=USE +; RUN: opt < %s -passes=pgo-instr-use -pgo-test-profile-file=%t.profdata -S | FileCheck %s --check-prefix=USE + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @foo() { +entry: + call void @bar() + unreachable +return: + ret void +} + +declare void @bar() + +;USE: !0 = !{i32 1, !"ProfileSummary", !1} +;USE: !1 = !{!2, !3, !4, !5, !6, !7, !8, !9} +;USE: !2 = !{!"ProfileFormat", !"InstrProf"} +;USE: !3 = !{!"TotalCount", i64 0} + +