[llvm] r259813 - [PGO] Add interfaces to annotate instr with VP data
Xinliang David Li via llvm-commits
llvm-commits at lists.llvm.org
Thu Feb 4 11:11:43 PST 2016
Author: davidxl
Date: Thu Feb 4 13:11:43 2016
New Revision: 259813
URL: http://llvm.org/viewvc/llvm-project?rev=259813&view=rev
Log:
[PGO] Add interfaces to annotate instr with VP data
Add interfaces to do value profile data IR annnotation
and read. Needed by both FE and IR based PGO.
Modified:
llvm/trunk/include/llvm/ProfileData/InstrProf.h
llvm/trunk/lib/ProfileData/InstrProf.cpp
llvm/trunk/unittests/ProfileData/InstrProfTest.cpp
Modified: llvm/trunk/include/llvm/ProfileData/InstrProf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProf.h?rev=259813&r1=259812&r2=259813&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ProfileData/InstrProf.h (original)
+++ llvm/trunk/include/llvm/ProfileData/InstrProf.h Thu Feb 4 13:11:43 2016
@@ -178,8 +178,8 @@ StringRef getFuncNameWithoutPrefix(Strin
/// The first field is the legnth of the uncompressed strings, and the
/// the second field is the length of the zlib-compressed string.
/// Both fields are encoded in ULEB128. If \c doCompress is false, the
-/// third field is the uncompressed strings; otherwise it is the
-/// compressed string. When the string compression is off, the
+/// third field is the uncompressed strings; otherwise it is the
+/// compressed string. When the string compression is off, the
/// second field will have value zero.
int collectPGOFuncNameStrings(const std::vector<std::string> &NameStrs,
bool doCompression, std::string &Result);
@@ -193,6 +193,29 @@ class InstrProfSymtab;
/// bytes. This method decodes the string and populates the \c Symtab.
int readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab);
+enum InstrProfValueKind : uint32_t {
+#define VALUE_PROF_KIND(Enumerator, Value) Enumerator = Value,
+#include "llvm/ProfileData/InstrProfData.inc"
+};
+
+struct InstrProfRecord;
+
+/// Extract value profile data for value site \p SiteIdx from \p InstrProfR
+/// and annotate the instruction \p Inst with the value profile meta data.
+void annotateValueSite(Module &M, Instruction &Inst,
+ const InstrProfRecord &InstrProfR,
+ InstrProfValueKind ValueKind, uint32_t SiteIndx);
+/// Extract the value profile data from the \p Inst which is annotated with
+/// value
+/// profile meta data. Return false if there is no value data annotated,
+/// otherwise
+/// return true.
+bool getValueProfDataFromInst(const Instruction &Inst,
+ InstrProfValueKind ValueKind,
+ uint32_t MaxNumValueData,
+ InstrProfValueData ValueData[],
+ uint32_t &ActualNumValueData, uint64_t &TotalC);
+
const std::error_category &instrprof_category();
enum class instrprof_error {
@@ -227,11 +250,6 @@ inline instrprof_error MergeResult(instr
return Accumulator;
}
-enum InstrProfValueKind : uint32_t {
-#define VALUE_PROF_KIND(Enumerator, Value) Enumerator = Value,
-#include "llvm/ProfileData/InstrProfData.inc"
-};
-
namespace object {
class SectionRef;
}
Modified: llvm/trunk/lib/ProfileData/InstrProf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProf.cpp?rev=259813&r1=259812&r2=259813&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/InstrProf.cpp (original)
+++ llvm/trunk/lib/ProfileData/InstrProf.cpp Thu Feb 4 13:11:43 2016
@@ -17,6 +17,7 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/ErrorHandling.h"
@@ -606,6 +607,92 @@ void ValueProfData::swapBytesFromHost(su
sys::swapByteOrder<uint32_t>(NumValueKinds);
}
+void annotateValueSite(Module &M, Instruction &Inst,
+ const InstrProfRecord &InstrProfR,
+ InstrProfValueKind ValueKind, uint32_t SiteIdx) {
+ uint32_t NV = InstrProfR.getNumValueDataForSite(ValueKind, SiteIdx);
+
+ uint64_t Sum = 0;
+ std::unique_ptr<InstrProfValueData[]> VD =
+ InstrProfR.getValueForSite(ValueKind, SiteIdx, &Sum);
+
+ LLVMContext &Ctx = M.getContext();
+ MDBuilder MDHelper(Ctx);
+ SmallVector<Metadata *, 3> Vals;
+ // Tag
+ Vals.push_back(MDHelper.createString("VP"));
+ // Value Kind
+ Vals.push_back(MDHelper.createConstant(
+ ConstantInt::get(Type::getInt32Ty(Ctx), ValueKind)));
+ // Total Count
+ Vals.push_back(
+ MDHelper.createConstant(ConstantInt::get(Type::getInt64Ty(Ctx), Sum)));
+
+ // Value Profile Data
+ uint32_t MDCount = 3;
+ for (uint32_t I = 0; I < NV; ++I) {
+ Vals.push_back(MDHelper.createConstant(
+ ConstantInt::get(Type::getInt64Ty(Ctx), VD[I].Value)));
+ Vals.push_back(MDHelper.createConstant(
+ ConstantInt::get(Type::getInt64Ty(Ctx), VD[I].Count)));
+ if (--MDCount == 0)
+ break;
+ }
+ Inst.setMetadata(LLVMContext::MD_prof, MDNode::get(Ctx, Vals));
+}
+
+bool getValueProfDataFromInst(const Instruction &Inst,
+ InstrProfValueKind ValueKind,
+ uint32_t MaxNumValueData,
+ InstrProfValueData ValueData[],
+ uint32_t &ActualNumValueData, uint64_t &TotalC) {
+ MDNode *MD = Inst.getMetadata(LLVMContext::MD_prof);
+ if (!MD)
+ return false;
+
+ unsigned NOps = MD->getNumOperands();
+
+ if (NOps < 5)
+ return false;
+
+ // Operand 0 is a string tag "VP":
+ MDString *Tag = cast<MDString>(MD->getOperand(0));
+ if (!Tag)
+ return false;
+
+ if (!Tag->getString().equals("VP"))
+ return false;
+
+ // Now check kind:
+ ConstantInt *KindInt = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1));
+ if (!KindInt)
+ return false;
+ if (KindInt->getZExtValue() != ValueKind)
+ return false;
+
+ // Get total count
+ ConstantInt *TotalCInt = mdconst::dyn_extract<ConstantInt>(MD->getOperand(2));
+ if (!TotalCInt)
+ return false;
+ TotalC = TotalCInt->getZExtValue();
+
+ ActualNumValueData = 0;
+
+ for (unsigned I = 3; I < NOps; I += 2) {
+ if (ActualNumValueData >= MaxNumValueData)
+ break;
+ ConstantInt *Value = mdconst::dyn_extract<ConstantInt>(MD->getOperand(I));
+ ConstantInt *Count =
+ mdconst::dyn_extract<ConstantInt>(MD->getOperand(I + 1));
+ if (!Value || !Count)
+ return false;
+ ValueData[ActualNumValueData].Value = Value->getZExtValue();
+ ValueData[ActualNumValueData].Count = Count->getZExtValue();
+ ActualNumValueData++;
+ }
+ return true;
+}
+
// The argument to this method is a vector of cutoff percentages and the return
// value is a vector of (Cutoff, MinBlockCount, NumBlocks) triplets.
void ProfileSummary::computeDetailedSummary() {
Modified: llvm/trunk/unittests/ProfileData/InstrProfTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ProfileData/InstrProfTest.cpp?rev=259813&r1=259812&r2=259813&view=diff
==============================================================================
--- llvm/trunk/unittests/ProfileData/InstrProfTest.cpp (original)
+++ llvm/trunk/unittests/ProfileData/InstrProfTest.cpp Thu Feb 4 13:11:43 2016
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/ProfileData/InstrProfReader.h"
@@ -225,6 +226,60 @@ TEST_P(MaybeSparseInstrProfTest, get_ica
ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
}
+TEST_P(MaybeSparseInstrProfTest, annotate_vp_data) {
+ InstrProfRecord Record("caller", 0x1234, {1, 2});
+ Record.reserveSites(IPVK_IndirectCallTarget, 1);
+ InstrProfValueData VD0[] = {{1000, 1}, {2000, 2}, {3000, 3}};
+ Record.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
+ Writer.addRecord(std::move(Record));
+ auto Profile = Writer.writeBuffer();
+ readProfile(std::move(Profile));
+ ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
+ ASSERT_TRUE(NoError(R.getError()));
+
+ LLVMContext Ctx;
+ std::unique_ptr<Module> M(new Module("MyModule", Ctx));
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
+ /*isVarArg=*/false);
+ Function *F =
+ Function::Create(FTy, Function::ExternalLinkage, "caller", M.get());
+ BasicBlock *BB = BasicBlock::Create(Ctx, "", F);
+
+ IRBuilder<> Builder(BB);
+ BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);
+ BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);
+
+ // Use branch instruction to annotate with value profile data for simplicity
+ Instruction *Inst = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
+ Instruction *Inst2 = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
+ annotateValueSite(*M.get(), *Inst, R.get(), IPVK_IndirectCallTarget, 0);
+
+ InstrProfValueData ValueData[5];
+ uint32_t N;
+ uint64_t T;
+ bool Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 5,
+ ValueData, N, T);
+ ASSERT_TRUE(Res);
+ ASSERT_EQ(3U, N);
+ ASSERT_EQ(6U, T);
+ // The result should be sorted already:
+ ASSERT_EQ(3000U, ValueData[0].Value);
+ ASSERT_EQ(3U, ValueData[0].Count);
+ ASSERT_EQ(2000U, ValueData[1].Value);
+ ASSERT_EQ(2U, ValueData[1].Count);
+ ASSERT_EQ(1000U, ValueData[2].Value);
+ ASSERT_EQ(1U, ValueData[2].Count);
+ Res = getValueProfDataFromInst(*Inst, IPVK_IndirectCallTarget, 1, ValueData,
+ N, T);
+ ASSERT_TRUE(Res);
+ ASSERT_EQ(1U, N);
+ ASSERT_EQ(6U, T);
+
+ Res = getValueProfDataFromInst(*Inst2, IPVK_IndirectCallTarget, 5, ValueData,
+ N, T);
+ ASSERT_FALSE(Res);
+}
+
TEST_P(MaybeSparseInstrProfTest, get_icall_data_read_write_with_weight) {
InstrProfRecord Record1("caller", 0x1234, {1, 2});
InstrProfRecord Record2("callee1", 0x1235, {3, 4});
More information about the llvm-commits
mailing list