Index: include/llvm/ProfileData/SampleProf.h =================================================================== --- include/llvm/ProfileData/SampleProf.h +++ include/llvm/ProfileData/SampleProf.h @@ -188,16 +188,15 @@ Num); } - /// Return the sample record at the given location. + /// Save the number of samples collected at the given location in \p Weight. /// 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 false. + bool findSamplesAt(unsigned &Weight, int LineOffset, unsigned Discriminator) const { + const auto &ret = BodySamples.find(LineLocation(LineOffset, Discriminator)); + if (ret == BodySamples.end()) + return false; + Weight = ret->second.getSamples(); + return true; } bool empty() const { return BodySamples.empty(); } @@ -219,7 +218,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 @@ -63,11 +63,11 @@ "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 +101,11 @@ bool runOnFunction(Function &F); unsigned getFunctionLoc(Function &F); bool emitAnnotations(Function &F); - unsigned getInstWeight(Instruction &I); - unsigned getBlockWeight(BasicBlock *BB); + bool getInstWeight(unsigned &Weight, const Instruction &I) const; + bool getBlockWeight(unsigned &Weight, 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 +134,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 +186,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 +196,10 @@ /// /// \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,10 +210,11 @@ /// 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. +bool SampleProfileLoader::getInstWeight(unsigned &Weight, const Instruction &Inst) const { DebugLoc DLoc = Inst.getDebugLoc(); if (!DLoc) return 0; @@ -221,40 +224,29 @@ return 0; 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; + return Samples->findSamplesAt(Weight, Lineno - HeaderLineno, DIL->getDiscriminator()); } /// \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. - unsigned Weight = 0; +/// \returns true if profile is found for \p BB. +bool SampleProfileLoader::getBlockWeight(unsigned &Weight, const BasicBlock *BB) const { + bool Found = false; + Weight = 0; for (auto &I : BB->getInstList()) { - unsigned InstWeight = getInstWeight(I); - if (InstWeight > Weight) + unsigned InstWeight; + if (getInstWeight(InstWeight, I) && InstWeight > Weight) { Weight = InstWeight; + Found = true; + } } - Entry.first->second = Weight; - return Weight; + return Found; } /// \brief Compute and store the weights of every basic block. @@ -266,9 +258,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) { + unsigned Weight; + if (getBlockWeight(Weight, &BB)) { + BlockWeights[&BB] = Weight; + Changed = true; + } DEBUG(printBlockWeight(dbgs(), &BB)); } @@ -301,7 +296,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 +380,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));