[PGO] eliminate use of static variable

llvm-svn: 258486
This commit is contained in:
Xinliang David Li 2016-01-22 05:48:40 +00:00
parent 050cf771fb
commit 16253b4d49
3 changed files with 71 additions and 63 deletions

View File

@ -51,7 +51,7 @@ public:
std::unique_ptr<MemoryBuffer> writeBuffer();
// Internal interface for testing purpose only.
void setValueProfDataEndianness(support::endianness Endianness);
static support::endianness getValueProfDataEndianness();
private:
void writeImpl(ProfOStream &OS);

View File

@ -14,12 +14,16 @@
#include "llvm/ProfileData/InstrProfWriter.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/OnDiskHashTable.h"
#include <tuple>
using namespace llvm;
static cl::opt<bool> WriteVPInBE("write-vp-data-in-big", cl::ReallyHidden,
cl::init(false));
// A struct to define how the data stream should be patched. For Indexed
// profiling, only uint64_t data type is needed.
struct PatchItem {
@ -74,8 +78,6 @@ public:
}
namespace {
static support::endianness ValueProfDataEndianness = support::little;
class InstrProfRecordTrait {
public:
typedef StringRef key_type;
@ -134,17 +136,18 @@ public:
std::unique_ptr<ValueProfData> VDataPtr =
ValueProfData::serializeFrom(ProfileData.second);
uint32_t S = VDataPtr->getSize();
VDataPtr->swapBytesFromHost(ValueProfDataEndianness);
VDataPtr->swapBytesFromHost(
InstrProfWriter::getValueProfDataEndianness());
Out.write((const char *)VDataPtr.get(), S);
}
}
};
}
// Internal interface for testing purpose only.
void InstrProfWriter::setValueProfDataEndianness(
support::endianness Endianness) {
ValueProfDataEndianness = Endianness;
support::endianness InstrProfWriter::getValueProfDataEndianness() {
if (WriteVPInBE)
return support::big;
return support::little;
}
std::error_code InstrProfWriter::addRecord(InstrProfRecord &&I,

View File

@ -12,6 +12,7 @@
#include "llvm/IR/Module.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/ProfileData/InstrProfWriter.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compression.h"
#include "gtest/gtest.h"
@ -145,6 +146,7 @@ TEST_F(InstrProfTest, get_icall_data_read_write) {
InstrProfValueData VD3[] = {{(uint64_t) "callee1", 1}};
Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
ASSERT_EQ(support::little, InstrProfWriter::getValueProfDataEndianness());
Writer.addRecord(std::move(Record1));
Writer.addRecord(std::move(Record2));
Writer.addRecord(std::move(Record3));
@ -192,6 +194,7 @@ TEST_F(InstrProfTest, get_icall_data_read_write_with_weight) {
InstrProfValueData VD3[] = {{(uint64_t) "callee1", 1}};
Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
ASSERT_EQ(support::little, InstrProfWriter::getValueProfDataEndianness());
Writer.addRecord(std::move(Record1), 10);
Writer.addRecord(std::move(Record2));
Writer.addRecord(std::move(Record3));
@ -218,58 +221,6 @@ TEST_F(InstrProfTest, get_icall_data_read_write_with_weight) {
ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
}
TEST_F(InstrProfTest, get_icall_data_read_write_big_endian) {
InstrProfRecord Record1("caller", 0x1234, {1, 2});
InstrProfRecord Record2("callee1", 0x1235, {3, 4});
InstrProfRecord Record3("callee2", 0x1235, {3, 4});
InstrProfRecord Record4("callee3", 0x1235, {3, 4});
// 4 value sites.
Record1.reserveSites(IPVK_IndirectCallTarget, 4);
InstrProfValueData VD0[] = {{(uint64_t) "callee1", 1},
{(uint64_t) "callee2", 2},
{(uint64_t) "callee3", 3}};
Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
// No value profile data at the second site.
Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
InstrProfValueData VD2[] = {{(uint64_t) "callee1", 1},
{(uint64_t) "callee2", 2}};
Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
InstrProfValueData VD3[] = {{(uint64_t) "callee1", 1}};
Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
Writer.addRecord(std::move(Record1));
Writer.addRecord(std::move(Record2));
Writer.addRecord(std::move(Record3));
Writer.addRecord(std::move(Record4));
// Set big endian output.
Writer.setValueProfDataEndianness(support::big);
auto Profile = Writer.writeBuffer();
readProfile(std::move(Profile));
// Set big endian input.
Reader->setValueProfDataEndianness(support::big);
ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
ASSERT_TRUE(NoError(R.getError()));
ASSERT_EQ(4U, R.get().getNumValueSites(IPVK_IndirectCallTarget));
ASSERT_EQ(3U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
ASSERT_EQ(0U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
ASSERT_EQ(2U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
ASSERT_EQ(1U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
std::unique_ptr<InstrProfValueData[]> VD =
R.get().getValueForSite(IPVK_IndirectCallTarget, 0);
ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
// Restore little endian default:
Writer.setValueProfDataEndianness(support::little);
}
TEST_F(InstrProfTest, get_icall_data_merge1) {
static const char caller[] = "caller";
static const char callee1[] = "callee1";
@ -322,11 +273,11 @@ TEST_F(InstrProfTest, get_icall_data_merge1) {
Record12.addValueData(IPVK_IndirectCallTarget, 3, nullptr, 0, nullptr);
InstrProfValueData VD42[] = {{uint64_t(callee1), 1},
{uint64_t(callee2), 2},
{uint64_t(callee3), 3}};
InstrProfValueData VD42[] = {
{uint64_t(callee1), 1}, {uint64_t(callee2), 2}, {uint64_t(callee3), 3}};
Record12.addValueData(IPVK_IndirectCallTarget, 4, VD42, 3, nullptr);
ASSERT_EQ(support::little, InstrProfWriter::getValueProfDataEndianness());
Writer.addRecord(std::move(Record11));
// Merge profile data.
Writer.addRecord(std::move(Record12));
@ -418,6 +369,7 @@ TEST_F(InstrProfTest, get_icall_data_merge1_saturation) {
auto Result5 = Writer.addRecord(std::move(Record5));
ASSERT_EQ(Result5, instrprof_error::counter_overflow);
ASSERT_EQ(support::little, InstrProfWriter::getValueProfDataEndianness());
auto Profile = Writer.writeBuffer();
readProfile(std::move(Profile));
@ -466,6 +418,7 @@ TEST_F(InstrProfTest, get_icall_data_merge_site_trunc) {
Record12.addValueData(IPVK_IndirectCallTarget, 0, VD1, 255, nullptr);
Record12.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
ASSERT_EQ(support::little, InstrProfWriter::getValueProfDataEndianness());
Writer.addRecord(std::move(Record11));
// Merge profile data.
Writer.addRecord(std::move(Record12));
@ -767,4 +720,56 @@ TEST_F(InstrProfTest, instr_prof_symtab_compression_test) {
}
}
// Keep this the last test case as it sets the VP data endianness
TEST_F(InstrProfTest, get_icall_data_read_write_big_endian) {
InstrProfRecord Record1("caller", 0x1234, {1, 2});
InstrProfRecord Record2("callee1", 0x1235, {3, 4});
InstrProfRecord Record3("callee2", 0x1235, {3, 4});
InstrProfRecord Record4("callee3", 0x1235, {3, 4});
// 4 value sites.
Record1.reserveSites(IPVK_IndirectCallTarget, 4);
InstrProfValueData VD0[] = {{(uint64_t) "callee1", 1},
{(uint64_t) "callee2", 2},
{(uint64_t) "callee3", 3}};
Record1.addValueData(IPVK_IndirectCallTarget, 0, VD0, 3, nullptr);
// No value profile data at the second site.
Record1.addValueData(IPVK_IndirectCallTarget, 1, nullptr, 0, nullptr);
InstrProfValueData VD2[] = {{(uint64_t) "callee1", 1},
{(uint64_t) "callee2", 2}};
Record1.addValueData(IPVK_IndirectCallTarget, 2, VD2, 2, nullptr);
InstrProfValueData VD3[] = {{(uint64_t) "callee1", 1}};
Record1.addValueData(IPVK_IndirectCallTarget, 3, VD3, 1, nullptr);
Writer.addRecord(std::move(Record1));
Writer.addRecord(std::move(Record2));
Writer.addRecord(std::move(Record3));
Writer.addRecord(std::move(Record4));
// Set big endian output.
const char *args[] = {"InstrProfTest", "-write-vp-data-in-big"};
cl::ParseCommandLineOptions(sizeof(args) / sizeof(const char *), args);
ASSERT_EQ(support::big, InstrProfWriter::getValueProfDataEndianness());
auto Profile = Writer.writeBuffer();
readProfile(std::move(Profile));
// Set big endian input.
Reader->setValueProfDataEndianness(support::big);
ErrorOr<InstrProfRecord> R = Reader->getInstrProfRecord("caller", 0x1234);
ASSERT_TRUE(NoError(R.getError()));
ASSERT_EQ(4U, R.get().getNumValueSites(IPVK_IndirectCallTarget));
ASSERT_EQ(3U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 0));
ASSERT_EQ(0U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 1));
ASSERT_EQ(2U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 2));
ASSERT_EQ(1U, R.get().getNumValueDataForSite(IPVK_IndirectCallTarget, 3));
std::unique_ptr<InstrProfValueData[]> VD =
R.get().getValueForSite(IPVK_IndirectCallTarget, 0);
ASSERT_EQ(StringRef((const char *)VD[0].Value, 7), StringRef("callee3"));
ASSERT_EQ(StringRef((const char *)VD[1].Value, 7), StringRef("callee2"));
ASSERT_EQ(StringRef((const char *)VD[2].Value, 7), StringRef("callee1"));
}
} // end anonymous namespace