commit f59c98c9d9cf46ad13c8ecef075f536f597bc0a8
Author: Duncan P. N. Exon Smith <dexonsmith@apple.com>
Date:   Mon Mar 24 09:10:00 2014 -0700

    InstrProf: Calculate a useful 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.
    
    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.

diff --git a/lib/CodeGen/CodeGenPGO.cpp b/lib/CodeGen/CodeGenPGO.cpp
index 99109f4..31de50b 100644
--- a/lib/CodeGen/CodeGenPGO.cpp
+++ b/lib/CodeGen/CodeGenPGO.cpp
@@ -8,21 +8,21 @@
 //===----------------------------------------------------------------------===//
 //
 // 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/FileSystem.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 +62,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 +112,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,157 +315,192 @@ 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 Hash values for AST nodes.
+  ///
+  /// Distinct values for AST nodes that have 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 ASTHash {
+    FunctionDeclHash = 1,
+    LabelStmtHash,
+    WhileStmtHash,
+    DoStmtHash,
+    ForStmtHash,
+    CXXForRangeStmtHash,
+    ObjCForCollectionStmtHash,
+    SwitchStmtHash,
+    CaseStmtHash,
+    DefaultStmtHash,
+    IfStmtHash,
+    CXXTryStmtHash,
+    CXXCatchStmtHash,
+    ConditionalOperatorHash,
+    BinaryOperatorLAndHash,
+    BinaryOperatorLOrHash
+  };
+
   /// 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.
+    uint64_t Hash;
     /// The map of statements to counters.
     llvm::DenseMap<const Stmt*, unsigned> *CounterMap;
 
     MapRegionCounters(llvm::DenseMap<const Stmt*, unsigned> *CounterMap) :
-      NextCounter(0), CounterMap(CounterMap) {
+      NextCounter(0), Hash(0), CounterMap(CounterMap) {
     }
 
+  private:
+    void combineHash(ASTHash Val);
+    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 +842,66 @@ namespace {
       RegionCounter Cnt(PGO, E);
       Visit(E->getLHS());
       Cnt.beginRegion();
       (*CountMap)[E->getRHS()] = PGO.getCurrentRegionCount();
       Visit(E->getRHS());
       Cnt.adjustForControlFlow();
       Cnt.applyAdjustmentsToRegion(0);
       RecordNextStmtCount = true;
     }
   };
+
+}
+
+static ASTHash hashDecl(const Decl &Decl) { return FunctionDeclHash; }
+
+static ASTHash hashBinaryOperator(const Stmt &S) {
+  switch (cast<BinaryOperator>(S).getOpcode()) {
+  case BO_LAnd: return BinaryOperatorLAndHash;
+  case BO_LOr:  return BinaryOperatorLOrHash;
+  default: llvm_unreachable("binary operator does not get counters");
+  }
+}
+
+static ASTHash hashStmt(const Stmt &S) {
+  switch (S.getStmtClass()) {
+  case Stmt::LabelStmtClass:             return LabelStmtHash;
+  case Stmt::WhileStmtClass:             return WhileStmtHash;
+  case Stmt::DoStmtClass:                return DoStmtHash;
+  case Stmt::ForStmtClass:               return ForStmtHash;
+  case Stmt::CXXForRangeStmtClass:       return CXXForRangeStmtHash;
+  case Stmt::ObjCForCollectionStmtClass: return ObjCForCollectionStmtHash;
+  case Stmt::SwitchStmtClass:            return SwitchStmtHash;
+  case Stmt::CaseStmtClass:              return CaseStmtHash;
+  case Stmt::DefaultStmtClass:           return DefaultStmtHash;
+  case Stmt::IfStmtClass:                return IfStmtHash;
+  case Stmt::CXXTryStmtClass:            return CXXTryStmtHash;
+  case Stmt::CXXCatchStmtClass:          return CXXCatchStmtHash;
+  case Stmt::ConditionalOperatorClass:   return ConditionalOperatorHash;
+  case Stmt::BinaryOperatorClass:        return hashBinaryOperator(S);
+  default: llvm_unreachable("stmt class does not get counters");
+  }
+}
+
+void MapRegionCounters::combineHash(ASTHash Val) {
+  // Use Bernstein's hash.
+  Hash = Hash * 33 + Val;
+}
+
+void MapRegionCounters::assignCounter(const Decl *D) {
+  (*CounterMap)[D->getBody()] = NextCounter++;
+  combineHash(hashDecl(*D));
+}
+
+void MapRegionCounters::assignCounter(const Stmt *S) {
+  (*CounterMap)[S] = NextCounter++;
+  combineHash(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);
@@ -853,22 +934,21 @@ void CodeGenPGO::assignRegionCounters(const Decl *D, llvm::Function *Fn) {
 void CodeGenPGO::mapRegionCounters(const Decl *D) {
   RegionCounterMap = 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;
 }
 
 void CodeGenPGO::computeRegionCounts(const Decl *D) {
   StmtCountMap = 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..dc2ea33 100644
--- a/test/Profile/Inputs/c-attributes.profdata
+++ b/test/Profile/Inputs/c-attributes.profdata
@@ -1,34 +1,34 @@
 hot_100_percent
-2
+36
 2
 100000
 4999950000
 
 hot_40_percent
-2
+36
 2
 40000
 799980000
 
 normal_func
-2
+36
 2
 20000
 199990000
 
 cold_func
-2
+36
 2
 500
 124750
 
 main
-6
+55923587
 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..3f6749c 100644
--- a/test/Profile/Inputs/c-counter-overflows.profdata
+++ b/test/Profile/Inputs/c-counter-overflows.profdata
@@ -1,12 +1,12 @@
 main
-8
+49516093054
 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..124f9aa 100644
--- a/test/Profile/Inputs/c-general.profdata
+++ b/test/Profile/Inputs/c-general.profdata
@@ -1,48 +1,48 @@
 simple_loops
-4
+41485
 4
 1
 100
 100
 75
 
 conditionals
-11
+1779590355041746
 11
 1
 100
 50
 50
 33
 33
 16
 99
 100
 99
 100
 
 early_exits
-9
+1879529829386
 9
 1
 0
 51
 1
 25
 1
 25
 1
 0
 
 jumps
-22
+7252754487440751492
 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
+7720709554288221004
 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
+15837108448607352571
 17
 1
 32
 32
 1
 0
 1
 1
 11
 11
 1
 1
 15
 15
 1
 1
 2
 2
 
 boolean_operators
-8
+49720330851
 8
 1
 100
 34
 66
 17
 34
 33
 50
 
 boolop_loops
-9
+1553772543823
 9
 1
 50
 51
 50
 26
 50
 51
 50
 26
 
 do_fallthrough
-4
+41525
 4
 1
 10
 2
 8
 
 main
 1
 1
 1
 
 c-general.c:static_func
-2
+38
 2
 1
 10
 
diff --git a/test/Profile/Inputs/c-outdated-data.profdata b/test/Profile/Inputs/c-outdated-data.profdata
index 27015be..504429f 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
+1463
 3
 1
 0
 0
 
 main
 1
 1
 1
 
diff --git a/test/Profile/Inputs/cxx-class.profdata b/test/Profile/Inputs/cxx-class.profdata
index 756640d..1459bb0 100644
--- a/test/Profile/Inputs/cxx-class.profdata
+++ b/test/Profile/Inputs/cxx-class.profdata
@@ -1,41 +1,41 @@
 _Z14simple_wrapperv
-2
+38
 2
 1
 100
 
 main
 1
 1
 1
 
 _ZN6SimpleD1Ev
-2
+44
 2
 0
 0
 
 _ZN6SimpleD2Ev
-2
+44
 2
 100
 99
 
 _ZN6Simple6methodEv
-2
+44
 2
 100
 99
 
 _ZN6SimpleC1Ei
-2
+44
 2
 0
 0
 
 _ZN6SimpleC2Ei
-2
+44
 2
 100
 99
 
diff --git a/test/Profile/Inputs/cxx-throws.profdata b/test/Profile/Inputs/cxx-throws.profdata
index 01e6c3c..22235df 100644
--- a/test/Profile/Inputs/cxx-throws.profdata
+++ b/test/Profile/Inputs/cxx-throws.profdata
@@ -1,12 +1,12 @@
 _Z6throwsv
-9
+1635442393046
 9
 1
 100
 100
 66
 33
 17
 50
 33
 100
diff --git a/test/Profile/Inputs/objc-general.profdata b/test/Profile/Inputs/objc-general.profdata
index 8841e90..5d345c6 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
+44
 2
 2
 1
 
 objc-general.m:+[A foreach:]
-2
+40
 2
 1
 2
 
 main
 1
 1
 1
 
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"
