InstrProf: Support for value profiling in the indexed profile format

Add support to the indexed instrprof reader and writer for the format
that will be used for value profiling.

Patch by Betul Buyukkurt, with minor modifications.

llvm-svn: 248833
diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp
index 23fa7b4..fdf22c3 100644
--- a/llvm/tools/llvm-profdata/llvm-profdata.cpp
+++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp
@@ -58,9 +58,8 @@
       exitWithError(ec.message(), Filename);
 
     auto Reader = std::move(ReaderOrErr.get());
-    for (const auto &I : *Reader)
-      if (std::error_code EC =
-              Writer.addFunctionCounts(I.Name, I.Hash, I.Counts))
+    for (auto &I : *Reader)
+      if (std::error_code EC = Writer.addRecord(std::move(I)))
         errs() << Filename << ": " << I.Name << ": " << EC.message() << "\n";
     if (Reader->hasError())
       exitWithError(Reader->getError().message(), Filename);
@@ -134,8 +133,8 @@
 }
 
 static int showInstrProfile(std::string Filename, bool ShowCounts,
-                            bool ShowAllFunctions, std::string ShowFunction,
-                            raw_fd_ostream &OS) {
+                            bool ShowIndirectCallTargets, bool ShowAllFunctions,
+                            std::string ShowFunction, raw_fd_ostream &OS) {
   auto ReaderOrErr = InstrProfReader::create(Filename);
   if (std::error_code EC = ReaderOrErr.getError())
     exitWithError(EC.message(), Filename);
@@ -162,6 +161,9 @@
          << "    Hash: " << format("0x%016" PRIx64, Func.Hash) << "\n"
          << "    Counters: " << Func.Counts.size() << "\n"
          << "    Function count: " << Func.Counts[0] << "\n";
+      if (ShowIndirectCallTargets)
+        OS << "    Indirect Call Site Count: " << Func.IndirectCallSites.size()
+           << "\n";
     }
 
     if (Show && ShowCounts)
@@ -174,6 +176,16 @@
     }
     if (Show && ShowCounts)
       OS << "]\n";
+
+    if (Show && ShowIndirectCallTargets) {
+      OS << "    Indirect Target Results: \n";
+      for (size_t I = 0, E = Func.IndirectCallSites.size(); I < E; ++I) {
+        for (auto V : Func.IndirectCallSites[I].ValueData) {
+          OS << "\t[ " << I << ", ";
+          OS << (const char *)V.first << ", " << V.second << " ]\n";
+        }
+      }
+    }
   }
   if (Reader->hasError())
     exitWithError(Reader->getError().message(), Filename);
@@ -212,6 +224,9 @@
 
   cl::opt<bool> ShowCounts("counts", cl::init(false),
                            cl::desc("Show counter values for shown functions"));
+  cl::opt<bool> ShowIndirectCallTargets(
+      "ic-targets", cl::init(false),
+      cl::desc("Show indirect call site target values for shown functions"));
   cl::opt<bool> ShowAllFunctions("all-functions", cl::init(false),
                                  cl::desc("Details for every function"));
   cl::opt<std::string> ShowFunction("function",
@@ -240,8 +255,8 @@
     errs() << "warning: -function argument ignored: showing all functions\n";
 
   if (ProfileKind == instr)
-    return showInstrProfile(Filename, ShowCounts, ShowAllFunctions,
-                            ShowFunction, OS);
+    return showInstrProfile(Filename, ShowCounts, ShowIndirectCallTargets,
+                            ShowAllFunctions, ShowFunction, OS);
   else
     return showSampleProfile(Filename, ShowCounts, ShowAllFunctions,
                              ShowFunction, OS);