commit 4505208821bdac3bf23c3e2ef7e4e9f52c0ae8b9
Author: Duncan P. N. Exon Smith <dexonsmith@apple.com>
Date:   Wed Mar 26 12:43:54 2014 -0700

    InstrProf: Calculate a better function hash
    
    The function hash should change when control flow changes.  This patch
    hashes the type of each AST node that affects counters, rather than just
    counting how many there are.  These types are combined into a small
    enumerator that currently has 16 values.
    
    The new hash algorithm packs the enums for consecutively visited types
    into a `uint64_t`.  In order to save space for new types, the types are
    assumed to be 6-bit values (instead of 4-bit).  In order to minimize
    overhead for functions with little control flow, the `uint64_t` is used
    directly as a hash if it never fills up; if it does, it's passed through
    an MD5 context.
    
    Using hash values with the most significant bit set exposed a bug where
    unsigned values were read using strtol and strtoll.  Changed to strtoul
    and strtoull to keep the tests passing.
    
    <rdar://problem/16435801>

diff --git a/lib/CodeGen/CodeGenPGO.cpp b/lib/CodeGen/CodeGenPGO.cpp
index 7b45650..f83d7ba 100644
--- a/lib/CodeGen/CodeGenPGO.cpp
+++ b/lib/CodeGen/CodeGenPGO.cpp
@@ -8,23 +8,25 @@
 //===----------------------------------------------------------------------===//
 //
 // Instrumentation-based profile-guided optimization
 //
 //===----------------------------------------------------------------------===//
 
 #include "CodeGenPGO.h"
 #include "CodeGenFunction.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/StmtVisitor.h"
-#include "llvm/Config/config.h" // for strtoull()/strtoll() define
+#include "llvm/Config/config.h" // for strtoull()/strtoul() define
 #include "llvm/IR/MDBuilder.h"
+#include "llvm/Support/Endian.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MD5.h"
 
 using namespace clang;
 using namespace CodeGen;
 
 static void ReportBadPGOData(CodeGenModule &CGM, const char *Message) {
   DiagnosticsEngine &Diags = CGM.getDiags();
   unsigned diagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, "%0");
   Diags.Report(diagID) << Message;
 }
 
@@ -62,29 +64,29 @@ PGOProfileData::PGOProfileData(CodeGenModule &CGM, std::string Path)
 
     // Skip over the function hash.
     CurPtr = strchr(++CurPtr, '\n');
     if (!CurPtr) {
       ReportBadPGOData(CGM, "pgo data file is missing the function hash");
       return;
     }
 
     // Read the number of counters.
     char *EndPtr;
-    unsigned NumCounters = strtol(++CurPtr, &EndPtr, 10);
+    unsigned NumCounters = strtoul(++CurPtr, &EndPtr, 10);
     if (EndPtr == CurPtr || *EndPtr != '\n' || NumCounters <= 0) {
       ReportBadPGOData(CGM, "pgo data file has unexpected number of counters");
       return;
     }
     CurPtr = EndPtr;
 
     // Read function count.
-    uint64_t Count = strtoll(CurPtr, &EndPtr, 10);
+    uint64_t Count = strtoull(CurPtr, &EndPtr, 10);
     if (EndPtr == CurPtr || *EndPtr != '\n') {
       ReportBadPGOData(CGM, "pgo-data file has bad count value");
       return;
     }
     CurPtr = EndPtr; // Point to '\n'.
     FunctionCounts[FuncName] = Count;
     MaxCount = Count > MaxCount ? Count : MaxCount;
 
     // There is one line for each counter; skip over those lines.
     // Since function count is already read, we start the loop from 1.
@@ -112,36 +114,36 @@ bool PGOProfileData::getFunctionCounts(StringRef FuncName, uint64_t &FuncHash,
   if (OffsetIter == DataOffsets.end())
     return true;
   const char *CurPtr = DataBuffer->getBufferStart() + OffsetIter->getValue();
 
   // Skip over the function name.
   CurPtr = strchr(CurPtr, '\n');
   assert(CurPtr && "pgo-data has corrupted function entry");
 
   char *EndPtr;
   // Read the function hash.
-  FuncHash = strtoll(++CurPtr, &EndPtr, 10);
+  FuncHash = strtoull(++CurPtr, &EndPtr, 10);
   assert(EndPtr != CurPtr && *EndPtr == '\n' &&
          "pgo-data file has corrupted function hash");
   CurPtr = EndPtr;
 
   // Read the number of counters.
-  unsigned NumCounters = strtol(++CurPtr, &EndPtr, 10);
+  unsigned NumCounters = strtoul(++CurPtr, &EndPtr, 10);
   assert(EndPtr != CurPtr && *EndPtr == '\n' && NumCounters > 0 &&
          "pgo-data file has corrupted number of counters");
   CurPtr = EndPtr;
 
   Counts.reserve(NumCounters);
 
   for (unsigned N = 0; N < NumCounters; ++N) {
     // Read the count value.
-    uint64_t Count = strtoll(CurPtr, &EndPtr, 10);
+    uint64_t Count = strtoull(CurPtr, &EndPtr, 10);
     if (EndPtr == CurPtr || *EndPtr != '\n') {
       ReportBadPGOData(CGM, "pgo-data file has bad count value");
       return true;
     }
     Counts.push_back(Count);
     CurPtr = EndPtr + 1;
   }
 
   // Make sure the number of counters matches up.
   if (Counts.size() != NumCounters) {
@@ -315,156 +317,212 @@ llvm::Function *CodeGenPGO::emitInitialization(CodeGenModule &CGM) {
 
   // Add the basic block and the necessary calls.
   CGBuilderTy Builder(llvm::BasicBlock::Create(CGM.getLLVMContext(), "", F));
   Builder.CreateCall(RegisterF);
   Builder.CreateRetVoid();
 
   return F;
 }
 
 namespace {
+
+/// \brief Stable hasher for PGO region counters.
+///
+/// PGOHash produces a stable hash of a given function's control flow.
+///
+/// Changing the output of this hash will invalidate all previously generated
+/// profiles -- i.e., don't do it.
+class PGOHash {
+public:
+  /// \brief Hash values for AST nodes.
+  ///
+  /// Distinct values for AST nodes that have region counters attached.
+  ///
+  /// These values must be stable.  All new members must be added at the end,
+  /// and no members should be removed.  Changing the enumeration value for an
+  /// AST node will affect the hash of every function that contains that node.
+  enum HashType : unsigned char {
+    FunctionLikeDecl = 0,
+    LabelStmt,
+    WhileStmt,
+    DoStmt,
+    ForStmt,
+    CXXForRangeStmt,
+    ObjCForCollectionStmt,
+    SwitchStmt,
+    CaseStmt,
+    DefaultStmt,
+    IfStmt,
+    CXXTryStmt,
+    CXXCatchStmt,
+    ConditionalOperator,
+    BinaryOperatorLAnd,
+    BinaryOperatorLOr
+  };
+
+private:
+  constexpr static int NumBitsPerType = 6;
+  constexpr static unsigned NumTypesPerWord =
+      sizeof(uint64_t) * 8 / NumBitsPerType;
+  uint64_t Working;
+  unsigned Count;
+  llvm::MD5 MD5;
+
+public:
+  PGOHash() : Working(0), Count(0) {}
+  void combine(HashType Type);
+  uint64_t finalize();
+};
+
   /// A StmtVisitor that fills a map of statements to PGO counters.
   struct MapRegionCounters : public ConstStmtVisitor<MapRegionCounters> {
     /// The next counter value to assign.
     unsigned NextCounter;
+    /// The function hash.
+    PGOHash Hash;
     /// The map of statements to counters.
     llvm::DenseMap<const Stmt *, unsigned> &CounterMap;
 
     MapRegionCounters(llvm::DenseMap<const Stmt *, unsigned> &CounterMap)
         : NextCounter(0), CounterMap(CounterMap) {}
 
+  private:
+    void assignCounter(const Decl *D);
+    void assignCounter(const Stmt *S);
+
+  public:
     void VisitChildren(const Stmt *S) {
       for (Stmt::const_child_range I = S->children(); I; ++I)
         if (*I)
          this->Visit(*I);
     }
     void VisitStmt(const Stmt *S) { VisitChildren(S); }
 
     /// Assign a counter to track entry to the function body.
-    void VisitFunctionDecl(const FunctionDecl *S) {
-      CounterMap[S->getBody()] = NextCounter++;
-      Visit(S->getBody());
+    void VisitFunctionDecl(const FunctionDecl *D) {
+      assignCounter(D);
+      Visit(D->getBody());
     }
-    void VisitObjCMethodDecl(const ObjCMethodDecl *S) {
-      CounterMap[S->getBody()] = NextCounter++;
-      Visit(S->getBody());
+    void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
+      assignCounter(D);
+      Visit(D->getBody());
     }
-    void VisitBlockDecl(const BlockDecl *S) {
-      CounterMap[S->getBody()] = NextCounter++;
-      Visit(S->getBody());
+    void VisitBlockDecl(const BlockDecl *D) {
+      assignCounter(D);
+      Visit(D->getBody());
     }
     /// Assign a counter to track the block following a label.
     void VisitLabelStmt(const LabelStmt *S) {
-      CounterMap[S] = NextCounter++;
+      assignCounter(S);
       Visit(S->getSubStmt());
     }
     /// Assign a counter for the body of a while loop.
     void VisitWhileStmt(const WhileStmt *S) {
-      CounterMap[S] = NextCounter++;
+      assignCounter(S);
       Visit(S->getCond());
       Visit(S->getBody());
     }
     /// Assign a counter for the body of a do-while loop.
     void VisitDoStmt(const DoStmt *S) {
-      CounterMap[S] = NextCounter++;
+      assignCounter(S);
       Visit(S->getBody());
       Visit(S->getCond());
     }
     /// Assign a counter for the body of a for loop.
     void VisitForStmt(const ForStmt *S) {
-      CounterMap[S] = NextCounter++;
+      assignCounter(S);
       if (S->getInit())
         Visit(S->getInit());
       const Expr *E;
       if ((E = S->getCond()))
         Visit(E);
       if ((E = S->getInc()))
         Visit(E);
       Visit(S->getBody());
     }
     /// Assign a counter for the body of a for-range loop.
     void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
-      CounterMap[S] = NextCounter++;
+      assignCounter(S);
       Visit(S->getRangeStmt());
       Visit(S->getBeginEndStmt());
       Visit(S->getCond());
       Visit(S->getLoopVarStmt());
       Visit(S->getBody());
       Visit(S->getInc());
     }
     /// Assign a counter for the body of a for-collection loop.
     void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
-      CounterMap[S] = NextCounter++;
+      assignCounter(S);
       Visit(S->getElement());
       Visit(S->getBody());
     }
     /// Assign a counter for the exit block of the switch statement.
     void VisitSwitchStmt(const SwitchStmt *S) {
-      CounterMap[S] = NextCounter++;
+      assignCounter(S);
       Visit(S->getCond());
       Visit(S->getBody());
     }
     /// Assign a counter for a particular case in a switch. This counts jumps
     /// from the switch header as well as fallthrough from the case before this
     /// one.
     void VisitCaseStmt(const CaseStmt *S) {
-      CounterMap[S] = NextCounter++;
+      assignCounter(S);
       Visit(S->getSubStmt());
     }
     /// Assign a counter for the default case of a switch statement. The count
     /// is the number of branches from the loop header to the default, and does
     /// not include fallthrough from previous cases. If we have multiple
     /// conditional branch blocks from the switch instruction to the default
     /// block, as with large GNU case ranges, this is the counter for the last
     /// edge in that series, rather than the first.
     void VisitDefaultStmt(const DefaultStmt *S) {
-      CounterMap[S] = NextCounter++;
+      assignCounter(S);
       Visit(S->getSubStmt());
     }
     /// Assign a counter for the "then" part of an if statement. The count for
     /// the "else" part, if it exists, will be calculated from this counter.
     void VisitIfStmt(const IfStmt *S) {
-      CounterMap[S] = NextCounter++;
+      assignCounter(S);
       Visit(S->getCond());
       Visit(S->getThen());
       if (S->getElse())
         Visit(S->getElse());
     }
     /// Assign a counter for the continuation block of a C++ try statement.
     void VisitCXXTryStmt(const CXXTryStmt *S) {
-      CounterMap[S] = NextCounter++;
+      assignCounter(S);
       Visit(S->getTryBlock());
       for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I)
         Visit(S->getHandler(I));
     }
     /// Assign a counter for a catch statement's handler block.
     void VisitCXXCatchStmt(const CXXCatchStmt *S) {
-      CounterMap[S] = NextCounter++;
+      assignCounter(S);
       Visit(S->getHandlerBlock());
     }
     /// Assign a counter for the "true" part of a conditional operator. The
     /// count in the "false" part will be calculated from this counter.
     void VisitConditionalOperator(const ConditionalOperator *E) {
-      CounterMap[E] = NextCounter++;
+      assignCounter(E);
       Visit(E->getCond());
       Visit(E->getTrueExpr());
       Visit(E->getFalseExpr());
     }
     /// Assign a counter for the right hand side of a logical and operator.
     void VisitBinLAnd(const BinaryOperator *E) {
-      CounterMap[E] = NextCounter++;
+      assignCounter(E);
       Visit(E->getLHS());
       Visit(E->getRHS());
     }
     /// Assign a counter for the right hand side of a logical or operator.
     void VisitBinLOr(const BinaryOperator *E) {
-      CounterMap[E] = NextCounter++;
+      assignCounter(E);
       Visit(E->getLHS());
       Visit(E->getRHS());
     }
   };
 
   /// A StmtVisitor that propagates the raw counts through the AST and
   /// records the count at statements where the value may change.
   struct ComputeRegionCounts : public ConstStmtVisitor<ComputeRegionCounts> {
     /// PGO state.
     CodeGenPGO &PGO;
@@ -807,20 +865,125 @@ namespace {
       Cnt.beginRegion();
       CountMap[E->getRHS()] = PGO.getCurrentRegionCount();
       Visit(E->getRHS());
       Cnt.adjustForControlFlow();
       Cnt.applyAdjustmentsToRegion(0);
       RecordNextStmtCount = true;
     }
   };
 }
 
+void PGOHash::combine(HashType Type) {
+  // Check that we only have six bits.
+  assert(unsigned(Type) < 1u << NumBitsPerType &&
+         "Hash is invalid: too many types");
+
+  // Check for FunctionLikeDecl.  It has value 0, and should always (and only)
+  // occur as the first element.
+  static_assert(!FunctionLikeDecl, "FunctionLikeDecl should have value 0");
+  if (Type == FunctionLikeDecl) {
+    assert(!Count && "FunctionLikeDecl should always get the first counter");
+    return;
+  }
+
+  // Check that we never try to combine 0, since it won't be noticed.
+  assert(Type && "Hash is invalid: unexpected type 0");
+
+  // Pass through MD5 if enough work has built up.
+  if (Count && !(Count % NumTypesPerWord)) {
+    using namespace llvm::support;
+    uint64_t Swapped = endian::byte_swap<uint64_t, little>(Working);
+    MD5.update(llvm::makeArrayRef((uint8_t *)&Swapped, sizeof(Swapped)));
+    Working = 0;
+  }
+
+  // Accumulate the current type.
+  ++Count;
+  Working = Working << NumBitsPerType | Type;
+}
+
+uint64_t PGOHash::finalize() {
+  // Use Working as the hash directly if we never used MD5.
+  if (Count <= NumTypesPerWord)
+    return Working;
+
+  // Check for remaining work in Working.
+  if (Working)
+    MD5.update(Working);
+
+  // Finalize the MD5 and return the hash.
+  llvm::MD5::MD5Result Result;
+  MD5.final(Result);
+  using namespace llvm::support;
+  return endian::read<uint64_t, little, unaligned>(Result);
+}
+
+static PGOHash::HashType hashDecl(const Decl &Decl) {
+  return PGOHash::FunctionLikeDecl;
+}
+
+static PGOHash::HashType hashBinaryOperator(const Stmt &S) {
+  switch (cast<BinaryOperator>(S).getOpcode()) {
+  case BO_LAnd:
+    return PGOHash::BinaryOperatorLAnd;
+  case BO_LOr:
+    return PGOHash::BinaryOperatorLOr;
+  default:
+    llvm_unreachable("binary operator does not get counters");
+  }
+}
+
+static PGOHash::HashType hashStmt(const Stmt &S) {
+  switch (S.getStmtClass()) {
+  case Stmt::LabelStmtClass:
+    return PGOHash::LabelStmt;
+  case Stmt::WhileStmtClass:
+    return PGOHash::WhileStmt;
+  case Stmt::DoStmtClass:
+    return PGOHash::DoStmt;
+  case Stmt::ForStmtClass:
+    return PGOHash::ForStmt;
+  case Stmt::CXXForRangeStmtClass:
+    return PGOHash::CXXForRangeStmt;
+  case Stmt::ObjCForCollectionStmtClass:
+    return PGOHash::ObjCForCollectionStmt;
+  case Stmt::SwitchStmtClass:
+    return PGOHash::SwitchStmt;
+  case Stmt::CaseStmtClass:
+    return PGOHash::CaseStmt;
+  case Stmt::DefaultStmtClass:
+    return PGOHash::DefaultStmt;
+  case Stmt::IfStmtClass:
+    return PGOHash::IfStmt;
+  case Stmt::CXXTryStmtClass:
+    return PGOHash::CXXTryStmt;
+  case Stmt::CXXCatchStmtClass:
+    return PGOHash::CXXCatchStmt;
+  case Stmt::ConditionalOperatorClass:
+    return PGOHash::ConditionalOperator;
+  case Stmt::BinaryOperatorClass:
+    return hashBinaryOperator(S);
+  default:
+    llvm_unreachable("stmt class does not get counters");
+  }
+}
+
+void MapRegionCounters::assignCounter(const Decl *D) {
+  CounterMap[D->getBody()] = NextCounter++;
+  Hash.combine(hashDecl(*D));
+}
+
+void MapRegionCounters::assignCounter(const Stmt *S) {
+  CounterMap[S] = NextCounter++;
+  Hash.combine(hashStmt(*S));
+}
+
 void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
   bool InstrumentRegions = CGM.getCodeGenOpts().ProfileInstrGenerate;
   PGOProfileData *PGOData = CGM.getPGOData();
   if (!InstrumentRegions && !PGOData)
     return;
   if (!D)
     return;
   setFuncName(Fn);
 
   // Set the linkage for variables based on the function linkage.  Usually, we
@@ -851,22 +1014,21 @@ void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
 void CodeGenPGO::mapRegionCounters(const Decl *D) {
   RegionCounterMap.reset(new llvm::DenseMap<const Stmt *, unsigned>);
   MapRegionCounters Walker(*RegionCounterMap);
   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
     Walker.VisitFunctionDecl(FD);
   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
     Walker.VisitObjCMethodDecl(MD);
   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
     Walker.VisitBlockDecl(BD);
   NumRegionCounters = Walker.NextCounter;
-  // FIXME: The number of counters isn't sufficient for the hash
-  FunctionHash = NumRegionCounters;
+  FunctionHash = Walker.Hash.finalize();
 }
 
 void CodeGenPGO::computeRegionCounts(const Decl *D) {
   StmtCountMap.reset(new llvm::DenseMap<const Stmt *, uint64_t>);
   ComputeRegionCounts Walker(*StmtCountMap, *this);
   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
     Walker.VisitFunctionDecl(FD);
   else if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
     Walker.VisitObjCMethodDecl(MD);
   else if (const BlockDecl *BD = dyn_cast_or_null<BlockDecl>(D))
diff --git a/test/Profile/Inputs/c-attributes.profdata b/test/Profile/Inputs/c-attributes.profdata
index 97e6824..e4d4694 100644
--- a/test/Profile/Inputs/c-attributes.profdata
+++ b/test/Profile/Inputs/c-attributes.profdata
@@ -16,19 +16,19 @@ normal_func
 20000
 199990000
 
 cold_func
 2
 2
 500
 124750
 
 main
-6
+219169028
 6
 1
 0
 100000
 40000
 20000
 500
 
diff --git a/test/Profile/Inputs/c-counter-overflows.profdata b/test/Profile/Inputs/c-counter-overflows.profdata
index 2486378..5a3633e 100644
--- a/test/Profile/Inputs/c-counter-overflows.profdata
+++ b/test/Profile/Inputs/c-counter-overflows.profdata
@@ -1,12 +1,12 @@
 main
-8
+285734896137
 8
 1
 68719476720
 64424509425
 68719476720
 21474836475
 21474836475
 21474836475
 4294967295
 
diff --git a/test/Profile/Inputs/c-general.profdata b/test/Profile/Inputs/c-general.profdata
index a1d5610..e807c66 100644
--- a/test/Profile/Inputs/c-general.profdata
+++ b/test/Profile/Inputs/c-general.profdata
@@ -1,48 +1,48 @@
 simple_loops
-4
+16515
 4
 1
 100
 100
 75
 
 conditionals
-11
+74917022372782735
 11
 1
 100
 50
 50
 33
 33
 16
 99
 100
 99
 100
 
 early_exits
-9
+44128811889290
 9
 1
 0
 51
 1
 25
 1
 25
 1
 0
 
 jumps
-22
+2016037664281362839
 22
 1
 1
 0
 1
 0
 0
 1
 0
 1
@@ -54,21 +54,21 @@ jumps
 0
 1
 1
 1
 10
 0
 10
 9
 
 switches
-19
+2745195701975551402
 19
 1
 1
 1
 15
 7
 1
 0
 2
 2
@@ -77,74 +77,74 @@ switches
 4
 4
 0
 4
 4
 5
 1
 0
 
 big_switch
-17
+10218718452081869619
 17
 1
 32
 32
 1
 0
 1
 1
 11
 11
 1
 1
 15
 15
 1
 1
 2
 2
 
 boolean_operators
-8
+291222909838
 8
 1
 100
 34
 66
 17
 34
 33
 50
 
 boolop_loops
-9
+9760565944591
 9
 1
 50
 51
 50
 26
 50
 51
 50
 26
 
 do_fallthrough
-4
+16586
 4
 1
 10
 2
 8
 
 main
-1
+0
 1
 1
 
 c-general.c:static_func
-2
+4
 2
 1
 10
 
diff --git a/test/Profile/Inputs/c-outdated-data.profdata b/test/Profile/Inputs/c-outdated-data.profdata
index 27015be..d57a6e9 100644
--- a/test/Profile/Inputs/c-outdated-data.profdata
+++ b/test/Profile/Inputs/c-outdated-data.profdata
@@ -1,12 +1,12 @@
 no_usable_data
-3
+650
 3
 1
 0
 0
 
 main
-1
+0
 1
 1
 
diff --git a/test/Profile/Inputs/cxx-class.profdata b/test/Profile/Inputs/cxx-class.profdata
index 756640d..b4645ed 100644
--- a/test/Profile/Inputs/cxx-class.profdata
+++ b/test/Profile/Inputs/cxx-class.profdata
@@ -1,41 +1,41 @@
 _Z14simple_wrapperv
-2
+4
 2
 1
 100
 
 main
-1
+0
 1
 1
 
 _ZN6SimpleD1Ev
-2
+10
 2
 0
 0
 
 _ZN6SimpleD2Ev
-2
+10
 2
 100
 99
 
 _ZN6Simple6methodEv
-2
+10
 2
 100
 99
 
 _ZN6SimpleC1Ei
-2
+10
 2
 0
 0
 
 _ZN6SimpleC2Ei
-2
+10
 2
 100
 99
 
diff --git a/test/Profile/Inputs/cxx-throws.profdata b/test/Profile/Inputs/cxx-throws.profdata
index 01e6c3c..4016eca 100644
--- a/test/Profile/Inputs/cxx-throws.profdata
+++ b/test/Profile/Inputs/cxx-throws.profdata
@@ -1,18 +1,18 @@
 _Z6throwsv
-9
+18359008150154
 9
 1
 100
 100
 66
 33
 17
 50
 33
 100
 
 main
-1
+0
 1
 1
 
diff --git a/test/Profile/Inputs/objc-general.profdata b/test/Profile/Inputs/objc-general.profdata
index 8841e90..8d6771f 100644
--- a/test/Profile/Inputs/objc-general.profdata
+++ b/test/Profile/Inputs/objc-general.profdata
@@ -1,17 +1,17 @@
 objc-general.m:__13+[A foreach:]_block_invoke
-2
+10
 2
 2
 1
 
 objc-general.m:+[A foreach:]
-2
+6
 2
 1
 2
 
 main
-1
+0
 1
 1
 
diff --git a/test/Profile/c-linkage-available_externally.c b/test/Profile/c-linkage-available_externally.c
index cbdf306..adc1e6e 100644
--- a/test/Profile/c-linkage-available_externally.c
+++ b/test/Profile/c-linkage-available_externally.c
@@ -1,12 +1,12 @@
 // Make sure instrementation data from available_externally functions doesn't
 // get thrown out.
 // RUN: %clang_cc1 -O2 -triple x86_64-apple-macosx10.9 -main-file-name c-linkage-available_externally.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck %s
 
 // CHECK: @__llvm_profile_counters_foo = linkonce_odr global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
 // CHECK: @__llvm_profile_name_foo = linkonce_odr constant [3 x i8] c"foo", section "__DATA,__llvm_prf_names", align 1
-// CHECK: @__llvm_profile_data_foo = linkonce_odr constant { i32, i32, i64, i8*, i64* } { i32 3, i32 1, i64 1, i8* getelementptr inbounds ([3 x i8]* @__llvm_profile_name_foo, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_foo, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+// CHECK: @__llvm_profile_data_foo = linkonce_odr constant { i32, i32, i64, i8*, i64* } { i32 3, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([3 x i8]* @__llvm_profile_name_foo, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_foo, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
 inline int foo(void) { return 1; }
 
 int main(void) {
   return foo();
 }
diff --git a/test/Profile/c-linkage.c b/test/Profile/c-linkage.c
index a688197..77a3899 100644
--- a/test/Profile/c-linkage.c
+++ b/test/Profile/c-linkage.c
@@ -1,31 +1,31 @@
 // Check the data structures emitted by instrumentation.
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-linkage.c %s -o - -emit-llvm -fprofile-instr-generate | FileCheck %s
 
 // CHECK: @__llvm_profile_counters_foo = global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
 // CHECK: @__llvm_profile_name_foo = constant [3 x i8] c"foo", section "__DATA,__llvm_prf_names", align 1
-// CHECK: @__llvm_profile_data_foo = constant { i32, i32, i64, i8*, i64* } { i32 3, i32 1, i64 1, i8* getelementptr inbounds ([3 x i8]* @__llvm_profile_name_foo, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_foo, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+// CHECK: @__llvm_profile_data_foo = constant { i32, i32, i64, i8*, i64* } { i32 3, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([3 x i8]* @__llvm_profile_name_foo, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_foo, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
 void foo(void) { }
 
 // CHECK: @__llvm_profile_counters_foo_weak = weak global [5 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
 // CHECK: @__llvm_profile_name_foo_weak = weak constant [8 x i8] c"foo_weak", section "__DATA,__llvm_prf_names", align 1
-// CHECK: @__llvm_profile_data_foo_weak = weak constant { i32, i32, i64, i8*, i64* } { i32 8, i32 5, i64 5, i8* getelementptr inbounds ([8 x i8]* @__llvm_profile_name_foo_weak, i32 0, i32 0), i64* getelementptr inbounds ([5 x i64]* @__llvm_profile_counters_foo_weak, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+// CHECK: @__llvm_profile_data_foo_weak = weak constant { i32, i32, i64, i8*, i64* } { i32 8, i32 5, i64 {{[0-9]+}}, i8* getelementptr inbounds ([8 x i8]* @__llvm_profile_name_foo_weak, i32 0, i32 0), i64* getelementptr inbounds ([5 x i64]* @__llvm_profile_counters_foo_weak, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
 void foo_weak(void) __attribute__((weak));
 void foo_weak(void) { if (0){} if (0){} if (0){} if (0){} }
 
 // CHECK: @__llvm_profile_counters_main = global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
 // CHECK: @__llvm_profile_name_main = constant [4 x i8] c"main", section "__DATA,__llvm_prf_names", align 1
-// CHECK: @__llvm_profile_data_main = constant { i32, i32, i64, i8*, i64* } { i32 4, i32 1, i64 1, i8* getelementptr inbounds ([4 x i8]* @__llvm_profile_name_main, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_main, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+// CHECK: @__llvm_profile_data_main = constant { i32, i32, i64, i8*, i64* } { i32 4, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([4 x i8]* @__llvm_profile_name_main, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_main, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
 static void foo_internal(void);
 int main(void) {
   foo();
   foo_internal();
   foo_weak();
   return 0;
 }
 
 // CHECK: @__llvm_profile_counters_foo_internal = internal global [3 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
 // CHECK: @__llvm_profile_name_foo_internal = internal constant [24 x i8] c"c-linkage.c:foo_internal", section "__DATA,__llvm_prf_names", align 1
-// CHECK: @__llvm_profile_data_foo_internal = internal constant { i32, i32, i64, i8*, i64* } { i32 24, i32 3, i64 3, i8* getelementptr inbounds ([24 x i8]* @__llvm_profile_name_foo_internal, i32 0, i32 0), i64* getelementptr inbounds ([3 x i64]* @__llvm_profile_counters_foo_internal, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+// CHECK: @__llvm_profile_data_foo_internal = internal constant { i32, i32, i64, i8*, i64* } { i32 24, i32 3, i64 {{[0-9]+}}, i8* getelementptr inbounds ([24 x i8]* @__llvm_profile_name_foo_internal, i32 0, i32 0), i64* getelementptr inbounds ([3 x i64]* @__llvm_profile_counters_foo_internal, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
 static void foo_internal(void) { if (0){} if (0){} }
 
 // CHECK: @llvm.used = appending global [4 x i8*] [i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_foo to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_foo_weak to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_main to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_foo_internal to i8*)], section "llvm.metadata"
diff --git a/test/Profile/cxx-linkage.cpp b/test/Profile/cxx-linkage.cpp
index 16f84a6..57c0a96 100644
--- a/test/Profile/cxx-linkage.cpp
+++ b/test/Profile/cxx-linkage.cpp
@@ -1,30 +1,30 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -emit-llvm -main-file-name cxx-linkage.cpp %s -o - -fprofile-instr-generate | FileCheck %s
 
 // CHECK: @__llvm_profile_counters__Z3foov = global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
 // CHECK: @__llvm_profile_name__Z3foov = constant [7 x i8] c"_Z3foov", section "__DATA,__llvm_prf_names", align 1
-// CHECK: @__llvm_profile_data__Z3foov = constant { i32, i32, i64, i8*, i64* } { i32 7, i32 1, i64 1, i8* getelementptr inbounds ([7 x i8]* @__llvm_profile_name__Z3foov, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters__Z3foov, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+// CHECK: @__llvm_profile_data__Z3foov = constant { i32, i32, i64, i8*, i64* } { i32 7, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([7 x i8]* @__llvm_profile_name__Z3foov, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters__Z3foov, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
 void foo(void) { }
 
 // CHECK: @__llvm_profile_counters__Z8foo_weakv = weak global [5 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
 // CHECK: @__llvm_profile_name__Z8foo_weakv = weak constant [12 x i8] c"_Z8foo_weakv", section "__DATA,__llvm_prf_names", align 1
-// CHECK: @__llvm_profile_data__Z8foo_weakv = weak constant { i32, i32, i64, i8*, i64* } { i32 12, i32 5, i64 5, i8* getelementptr inbounds ([12 x i8]* @__llvm_profile_name__Z8foo_weakv, i32 0, i32 0), i64* getelementptr inbounds ([5 x i64]* @__llvm_profile_counters__Z8foo_weakv, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+// CHECK: @__llvm_profile_data__Z8foo_weakv = weak constant { i32, i32, i64, i8*, i64* } { i32 12, i32 5, i64 {{[0-9]+}}, i8* getelementptr inbounds ([12 x i8]* @__llvm_profile_name__Z8foo_weakv, i32 0, i32 0), i64* getelementptr inbounds ([5 x i64]* @__llvm_profile_counters__Z8foo_weakv, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
 void foo_weak(void) __attribute__((weak));
 void foo_weak(void) { if (0){} if (0){} if (0){} if (0){} }
 
 // CHECK: @__llvm_profile_counters_main = global [1 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
 // CHECK: @__llvm_profile_name_main = constant [4 x i8] c"main", section "__DATA,__llvm_prf_names", align 1
-// CHECK: @__llvm_profile_data_main = constant { i32, i32, i64, i8*, i64* } { i32 4, i32 1, i64 1, i8* getelementptr inbounds ([4 x i8]* @__llvm_profile_name_main, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_main, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+// CHECK: @__llvm_profile_data_main = constant { i32, i32, i64, i8*, i64* } { i32 4, i32 1, i64 {{[0-9]+}}, i8* getelementptr inbounds ([4 x i8]* @__llvm_profile_name_main, i32 0, i32 0), i64* getelementptr inbounds ([1 x i64]* @__llvm_profile_counters_main, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
 inline void foo_inline(void);
 int main(void) {
   foo();
   foo_inline();
   foo_weak();
   return 0;
 }
 
 // CHECK: @__llvm_profile_counters__Z10foo_inlinev = linkonce_odr global [7 x i64] zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
 // CHECK: @__llvm_profile_name__Z10foo_inlinev = linkonce_odr constant [15 x i8] c"_Z10foo_inlinev", section "__DATA,__llvm_prf_names", align 1
-// CHECK: @__llvm_profile_data__Z10foo_inlinev = linkonce_odr constant { i32, i32, i64, i8*, i64* } { i32 15, i32 7, i64 7, i8* getelementptr inbounds ([15 x i8]* @__llvm_profile_name__Z10foo_inlinev, i32 0, i32 0), i64* getelementptr inbounds ([7 x i64]* @__llvm_profile_counters__Z10foo_inlinev, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
+// CHECK: @__llvm_profile_data__Z10foo_inlinev = linkonce_odr constant { i32, i32, i64, i8*, i64* } { i32 15, i32 7, i64 {{[0-9]+}}, i8* getelementptr inbounds ([15 x i8]* @__llvm_profile_name__Z10foo_inlinev, i32 0, i32 0), i64* getelementptr inbounds ([7 x i64]* @__llvm_profile_counters__Z10foo_inlinev, i32 0, i32 0) }, section "__DATA,__llvm_prf_data", align 8
 inline void foo_inline(void) { if (0){} if (0){} if (0){} if (0){} if (0){} if (0){}}
 
 // CHECK: @llvm.used = appending global [4 x i8*] [i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data__Z3foov to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data__Z8foo_weakv to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data_main to i8*), i8* bitcast ({ i32, i32, i64, i8*, i64* }* @__llvm_profile_data__Z10foo_inlinev to i8*)], section "llvm.metadata"
