Index: include/llvm/ProfileData/SampleProf.h =================================================================== --- include/llvm/ProfileData/SampleProf.h +++ include/llvm/ProfileData/SampleProf.h @@ -18,6 +18,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/raw_ostream.h" #include @@ -188,16 +189,16 @@ Num); } - /// Return the sample record at the given location. - /// Each location is specified by \p LineOffset and \p Discriminator. - SampleRecord &sampleRecordAt(const LineLocation &Loc) { - return BodySamples[Loc]; - } - /// Return the number of samples collected at the given location. /// Each location is specified by \p LineOffset and \p Discriminator. - unsigned samplesAt(int LineOffset, unsigned Discriminator) { - return sampleRecordAt(LineLocation(LineOffset, Discriminator)).getSamples(); + /// If the location is not found in profile, return error. + ErrorOr findSamplesAt(int LineOffset, + unsigned Discriminator) const { + const auto &ret = BodySamples.find(LineLocation(LineOffset, Discriminator)); + if (ret == BodySamples.end()) + return std::error_code(); + else + return ret->second.getSamples(); } bool empty() const { return BodySamples.empty(); } @@ -219,7 +220,7 @@ for (const auto &I : Other.getBodySamples()) { const LineLocation &Loc = I.first; const SampleRecord &Rec = I.second; - sampleRecordAt(Loc).merge(Rec); + BodySamples[Loc].merge(Rec); } } Index: lib/Transforms/IPO/SampleProfile.cpp =================================================================== --- lib/Transforms/IPO/SampleProfile.cpp +++ lib/Transforms/IPO/SampleProfile.cpp @@ -43,6 +43,7 @@ #include "llvm/ProfileData/SampleProfReader.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorOr.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/IPO.h" #include @@ -63,11 +64,12 @@ "sample block/edge weights through the CFG.")); namespace { -typedef DenseMap BlockWeightMap; -typedef DenseMap EquivalenceClassMap; -typedef std::pair Edge; +typedef DenseMap BlockWeightMap; +typedef DenseMap EquivalenceClassMap; +typedef std::pair Edge; typedef DenseMap EdgeWeightMap; -typedef DenseMap> BlockEdgeMap; +typedef DenseMap> + BlockEdgeMap; /// \brief Sample profile pass. /// @@ -101,11 +103,11 @@ bool runOnFunction(Function &F); unsigned getFunctionLoc(Function &F); bool emitAnnotations(Function &F); - unsigned getInstWeight(Instruction &I); - unsigned getBlockWeight(BasicBlock *BB); + ErrorOr getInstWeight(const Instruction &I) const; + ErrorOr getBlockWeight(const BasicBlock *BB) const; void printEdgeWeight(raw_ostream &OS, Edge E); - void printBlockWeight(raw_ostream &OS, BasicBlock *BB); - void printBlockEquivalence(raw_ostream &OS, BasicBlock *BB); + void printBlockWeight(raw_ostream &OS, const BasicBlock *BB) const; + void printBlockEquivalence(raw_ostream &OS, const BasicBlock *BB); bool computeBlockWeights(Function &F); void findEquivalenceClasses(Function &F); void findEquivalencesFor(BasicBlock *BB1, @@ -134,7 +136,7 @@ EdgeWeightMap EdgeWeights; /// \brief Set of visited blocks during propagation. - SmallPtrSet VisitedBlocks; + SmallPtrSet VisitedBlocks; /// \brief Set of visited edges during propagation. SmallSet VisitedEdges; @@ -186,8 +188,8 @@ /// \param OS Stream to emit the output to. /// \param BB Block to print. void SampleProfileLoader::printBlockEquivalence(raw_ostream &OS, - BasicBlock *BB) { - BasicBlock *Equiv = EquivalenceClass[BB]; + const BasicBlock *BB) { + const BasicBlock *Equiv = EquivalenceClass[BB]; OS << "equivalence[" << BB->getName() << "]: " << ((Equiv) ? EquivalenceClass[BB]->getName() : "NONE") << "\n"; } @@ -196,8 +198,11 @@ /// /// \param OS Stream to emit the output to. /// \param BB Block to print. -void SampleProfileLoader::printBlockWeight(raw_ostream &OS, BasicBlock *BB) { - OS << "weight[" << BB->getName() << "]: " << BlockWeights[BB] << "\n"; +void SampleProfileLoader::printBlockWeight(raw_ostream &OS, + const BasicBlock *BB) const { + const auto &I = BlockWeights.find(BB); + unsigned W = (I == BlockWeights.end() ? 0 : I->second); + OS << "weight[" << BB->getName() << "]: " << W << "\n"; } /// \brief Get the weight for an instruction. @@ -208,53 +213,55 @@ /// function. We use HeaderLineno to compute the offset. We then /// look up the samples collected for \p Inst using BodySamples. /// +/// \param Weight The weight of \p Inst. /// \param Inst Instruction to query. /// -/// \returns The profiled weight of I. -unsigned SampleProfileLoader::getInstWeight(Instruction &Inst) { +/// \returns true if profile is found for \p Inst. +ErrorOr +SampleProfileLoader::getInstWeight(const Instruction &Inst) const { DebugLoc DLoc = Inst.getDebugLoc(); if (!DLoc) - return 0; + return std::error_code(); unsigned Lineno = DLoc.getLine(); if (Lineno < HeaderLineno) - return 0; + return std::error_code(); const DILocation *DIL = DLoc; - int LOffset = Lineno - HeaderLineno; - unsigned Discriminator = DIL->getDiscriminator(); - unsigned Weight = Samples->samplesAt(LOffset, Discriminator); - DEBUG(dbgs() << " " << Lineno << "." << Discriminator << ":" << Inst - << " (line offset: " << LOffset << "." << Discriminator - << " - weight: " << Weight << ")\n"); - return Weight; + ErrorOr R = + Samples->findSamplesAt(Lineno - HeaderLineno, DIL->getDiscriminator()); + if (R) + DEBUG(dbgs() << " " << Lineno << "." << DIL->getDiscriminator() << ":" + << Inst << " (line offset: " << Lineno - HeaderLineno << "." + << DIL->getDiscriminator() << " - weight: " << R.get() + << ")\n"); + return R; } /// \brief Compute the weight of a basic block. /// /// The weight of basic block \p BB is the maximum weight of all the -/// instructions in BB. The weight of \p BB is computed and cached in -/// the BlockWeights map. +/// instructions in BB. /// +/// \param Weight The weight of the \p BB. /// \param BB The basic block to query. /// -/// \returns The computed weight of BB. -unsigned SampleProfileLoader::getBlockWeight(BasicBlock *BB) { - // If we've computed BB's weight before, return it. - std::pair Entry = - BlockWeights.insert(std::make_pair(BB, 0)); - if (!Entry.second) - return Entry.first->second; - - // Otherwise, compute and cache BB's weight. +/// \returns true if profile is found for \p BB. +ErrorOr +SampleProfileLoader::getBlockWeight(const BasicBlock *BB) const { + bool Found = false; unsigned Weight = 0; for (auto &I : BB->getInstList()) { - unsigned InstWeight = getInstWeight(I); - if (InstWeight > Weight) - Weight = InstWeight; + const ErrorOr &R = getInstWeight(I); + if (R && R.get() >= Weight) { + Weight = R.get(); + Found = true; + } } - Entry.first->second = Weight; - return Weight; + if (Found) + return Weight; + else + return std::error_code(); } /// \brief Compute and store the weights of every basic block. @@ -266,9 +273,12 @@ bool SampleProfileLoader::computeBlockWeights(Function &F) { bool Changed = false; DEBUG(dbgs() << "Block weights\n"); - for (auto &BB : F) { - unsigned Weight = getBlockWeight(&BB); - Changed |= (Weight > 0); + for (const auto &BB : F) { + ErrorOr Weight = getBlockWeight(&BB); + if (Weight) { + BlockWeights[&BB] = Weight.get(); + Changed = true; + } DEBUG(printBlockWeight(dbgs(), &BB)); } @@ -301,7 +311,7 @@ void SampleProfileLoader::findEquivalencesFor( BasicBlock *BB1, SmallVector Descendants, DominatorTreeBase *DomTree) { - for (auto *BB2 : Descendants) { + for (const auto *BB2 : Descendants) { bool IsDomParent = DomTree->dominates(BB2, BB1); bool IsInSameLoop = LI->getLoopFor(BB1) == LI->getLoopFor(BB2); if (BB1 != BB2 && VisitedBlocks.insert(BB2).second && IsDomParent && @@ -385,8 +395,8 @@ // to all the blocks in that equivalence class. DEBUG(dbgs() << "\nAssign the same weight to all blocks in the same class\n"); for (auto &BI : F) { - BasicBlock *BB = &BI; - BasicBlock *EquivBB = EquivalenceClass[BB]; + const BasicBlock *BB = &BI; + const BasicBlock *EquivBB = EquivalenceClass[BB]; if (BB != EquivBB) BlockWeights[BB] = BlockWeights[EquivBB]; DEBUG(printBlockWeight(dbgs(), BB));