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<BasicBlock *, unsigned> BlockWeightMap;
-typedef DenseMap<BasicBlock *, BasicBlock *> EquivalenceClassMap;
-typedef std::pair<BasicBlock *, BasicBlock *> Edge;
+typedef DenseMap<const BasicBlock *, unsigned> BlockWeightMap;
+typedef DenseMap<const BasicBlock *, const BasicBlock *> EquivalenceClassMap;
+typedef std::pair<const BasicBlock *, const BasicBlock *> Edge;
 typedef DenseMap<Edge, unsigned> EdgeWeightMap;
-typedef DenseMap<BasicBlock *, SmallVector<BasicBlock *, 8>> BlockEdgeMap;
+typedef DenseMap<const BasicBlock *, SmallVector<const BasicBlock *, 8>> 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<BasicBlock *, 128> VisitedBlocks;
+  SmallPtrSet<const BasicBlock *, 128> VisitedBlocks;
 
   /// \brief Set of visited edges during propagation.
   SmallSet<Edge, 128> 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<BlockWeightMap::iterator, bool> 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<BasicBlock *, 8> Descendants,
     DominatorTreeBase<BasicBlock> *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));